开发者

Crazy behaviour during execution

I have been doing some inline-asm with gcc. Everything is ALMOST working, up to some behaviour that is just baffling me. I am evaluating a rational polynomial, but need to use 80-bit constants. The generated code seems to be perfect, but on execution, one of the 80-bit coefficients, when loaded into the fpu, is loaded as 0, even though in memory the byte values are not zero (and I think it is a valid 80-bit real, as the exact same constant loads fine when run with code generated by masm). Here is the output from a gdb session:

(gdb) disassemble
Dump of assembler code for function poly4(double):
0x00402d7c <+0>:     push   %ebp
0x00402d7d <+1>:     mov    %esp,%ebp
0x00402d7f <+3>:     sub    $0x8,%esp
0x00402d82 <+6>:     mov    0x8(%ebp),%eax
0x00402d85 <+9>:     mov    %eax,-0x8(%ebp)
0x00402d88 <+12>:    mov    0xc(%ebp),%eax
0x00402d8b <+15>:    mov    %eax,-0x4(%ebp)
0x00402d8e <+18>:    fld1
0x00402d90 <+20>:    fldl   -0x8(%ebp)
0x00402d93 <+23>:    fmul   %st(0),%st
0x00402d95 <+25>:    fdivrp %st,%st(1)
0x00402d97 <+27>:    fldt   0x40470e
0x00402d9d <+33>:    fadd   %st(1),%st
0x00402d9f <+35>:    fmul   %st(1),%st
0x00402da1 <+37>:    fldt   0x404704
0x00402da7 <+43>:    faddp  %st,%st(1)
0x00402da9 <+45>:    fmul   %st(1),%st
0x00402dab <+47>:    fldt   0x4046fa
0x00402db1 <+53>:    faddp  %st,%st(1)
0x00402db3 <+55>:    fmul   %st(1),%st
0x00402db5 <+57>:    fldt   0x4046f0
0x00402dbb <+63>:    faddp  %st,%st(1)
0x00402dbd <+65>:    fmul   %st(1),%st
=>  0x00402dbf <+67>:    fldt   0x4046e6
0x00402dc5 <+73>:    faddp  %st,%st(1)
...snip....
End of assembler dump.
(gdb) info registers st0 st1 st2 st3 st4 st5
st0            2.7412088761933612e-006  (raw 0x3fecb7f59c22579f9f60)
st1            0.00071574511983807409   (raw 0x3ff4bba0d78724c01468)
st2            <invalid float value>    (raw 0x00077c81cc3b0002021e)
st3            <invalid float value>    (raw 0x00020098007c00f8f0c0)
st4            0        (raw 0x000013af076300003654)
st5            <invalid float value>    (raw 0x0762000000000002021e)
(gdb) x/5xh 0x4046e6
0x4046e6 <_ZL11s_NORMAL_q5>:    0x8996  0xa5d6  0x3d00  0x990a  0x3ff1
(gdb) stepi
0x00402dc5      1577            );
(gdb) info registers st0 st1 st2 st3 st4 st5
st0            0        (raw 0x00000000000000000000)
st1            2.7412088761933612e-006  (raw 0x3fecb7f59c22579f9f60)
st2            0.00071574511983807409   (raw 0x3ff4bba0d78724c01468)
st3            <invalid float value>    (raw 0x00077c81cc3b0002021e)
st4            <invalid float value>    (raw 0x00020098007c00f8f0c0)
st5            0        (raw 0x000013af076300003654)
(gdb) disassemble
Dump of assembler code for function poly4(double):
0x00402d7c <+0>:     push   %ebp
0x00402d7d <+1>:     mov    %esp,%ebp
0x00402d7f <+3>:     sub    $0x8,%esp
0x00402d82 <+6>:     mov    0x8(%ebp),%eax
0x00402d85 <+9>:     mov    %eax,-0x8(%ebp)
0x00402d88 <+12>:    mov    0xc(%ebp),%eax
0x00402d8b <+15>:    mov    %eax,-0x4(%ebp)
0x00402d8e <+18>:    fld1
0x00402d90 <+20>:    fldl   -0x8(%ebp)
0x00402d93 <+23>:    fmul   %st(0),%st
0x00402d95 <+25>:    fdivrp %st,%st(1)
0x00402d97 <+27>:    fldt   0x40470e
0x00402d9d <+33>:    fadd   %st(1),%st
0x00402d9f <+35>:    fmul   %st(1),%st
0x00402da1 <+37>:    fldt   0x404704
0x00402da7 <+43>:    faddp  %st,%st(1)
0x00402da9 <+45>:    fmul   %st(1),%st
0x00402dab <+47>:    fldt   0x4046fa
0x00402db1 <+53>:    faddp  %st,%st(1)
0x00402db3 <+55>:    fmul   %st(1),%st
0x00402db5 <+57>:    fldt   0x4046f0
0x00402dbb <+63>:    faddp  %st,%st(1)
0x00402dbd <+65>:    fmul   %st(1),%st
0x00402dbf <+67>:    fldt   0x4046e6
=>  0x00402dc5 <+73>:    faddp  %st,%st(1)
...snip...
End of assembler dump.
(gdb)

So note: before the stepi, we are about to execute the "fldt 0x4046e6", and a dump of memory at 0x4046e6 clearly shows it is not zero. Yet the "fldt 0x4046e6" results in zero being loaded into st0. All the previous fldt instructions worked fine; the constants are good (the identical code in masm with the same constants works flawlessly). For those interested, here is the source for the constants:

Double80 s_NORMAL_p5 = { 0xE0, 0x14, 0x24, 0x6E, 0x43, 0x6C, 0x37, 0xF4, 0xEF, 0x3F}; // 0x3FEFF4376C436E2414E0, 2.9112874951168791857936318084879e-5
Double80 s_NORMAL_p4 = { 0x74, 0x5B, 0x7C, 0x72, 0xE2, 0x9F, 0x55, 0xBA, 0xF5, 0x3F}; // 0x3FF5BA559FE2727C5B74, 0.0014216191932278934659235163911273
Double80 s_NORMAL_p3 = { 0x3B, 0xD1, 0x83, 0xB3, 0xE8, 0xC1, 0x26, 0xB6, 0xF9, 0x3F}; // 0x3FF9B626C1E8B383D13B, 0.022235277870649807464320442391811
Double80 s_NORMAL_p2 = { 0x4B, 0xA2, 0x6C, 0x9F, 0x32, 0x73, 0x75, 0x82, 0xFC, 0x3F}; // 0x3FFC827573329F6CA24B, 0.1274011611602473638801278160334
Double80 s_NORMAL_p1 = { 0x49, 0xDC, 0x10, 0x22, 0x5C, 0x81, 0x14, 0xDD, 0xFC, 0x3F}; // 0x3FFCDD14815C2210DC49, 0.2158985340579569904693315913281
Double80 s_NORMAL_p0 = { 0x3E, 0xCE, 0xA6, 0x2B, 0xB9, 0x83, 0x04, 0xBD, 0xF9, 0x3F}; // 0x3FF9BD0483B92BA6CE3E, 0.023073441764940173030448369674463

Double80 s_NORMAL_q5 = { 0x96, 0x89, 0xD6, 0xA5, 0x00, 0x3D, 0x0A, 0x99, 0xF1, 0x3F}; // 0x3FF1990A3D00A5D68996, 0.0000729751555083966204509375
Double80 s_NORMAL_q4 = { 0xF8, 0x37, 0xEF, 0xEB, 0x8B, 0x14, 0xE2, 0xF7, 0xF6, 0x3F}; // 0x3FF6F7E2148BEBEF37F8, 0.0037823963320275824448625
Double80 s_NORMAL_q3 = { 0x35, 0xC5, 0x61, 0x91, 0xF0, 0xC9, 0x24, 0x87, 0xFB, 0x3F}; // 0x3FFB8724C9F09161C535, 0.065988137868928551531
Double80 s_NORMAL_q2 = { 0xCC, 0x68, 0x85, 0xAF, 0x42, 0xEB, 0xBC, 0xEF, 0xFD, 0x3F}; // 0x3FFDEFBCEB42AF8568CC, 0.4682382124808651180225
Double80 s_NORMAL_q1 = { 0xF3, 0xDB, 0x06, 0x40, 0x84, 0xA2, 0x62, 0xA4, 0xFF, 0x3F}; // 0x3FFFA462A2844006DBF3, 1.28426009614491121036

and here is the source for the poly4 function:

inline long double poly4(double y)
{
    __asm__(
    "\n\t" "fld1"                       //1
    "\n\t" "fldl %[y]"                      //y, 1
    "\n\t" "fmul %%st(0), %%st(0)"          //y^2, 1
    "\n\t" "fdivp %%st(0), %%st(1)"     //1/y^2=xsq
    //den
    "\n\t" "fldt  %[s_NORMAL_q1]"       //q1, xsq
    "\n\t" "fadd %%st(1), %%st(0)"          //q1+xsq, xsq
    "\n\t" "fmul %%st(1), %%st(0)"          //(q1+xsq)*xsq, xsq
    "\n\t" "fldt  %[s_NORMAL_q2]"           //q2, (q1+xsq)*xsq, xsq
    "\n\t" "faddp %%st(0), %%st(1)"     //q2+(q1+xsq)*xsq, xsq
    "\n\t" "fmul %%st(1), %%st(0)"          //(q2+(q1+xsq)*xsq)*xsq, xsq
    "\n\t" "fldt  %[s_NORMAL_q3]"           //q3, (q2+(q1+xsq)*xsq)*xsq, xsq
    "\n\t" "faddp %%st(0), %%st(1)"     //q3+(q2+(q1+xsq)*xsq)*xsq, xsq
    "\n\t" "fmul %%st(1), %%st(0)"          //(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq, xsq
    "\n\t" "fldt  %[s_NORMAL_q4]"       //q4, (q3+(q2+(q1+xsq)*xsq)*xsq)*xsq, xsq
    "\n\t" "faddp %%st(0), %%st(1)"     //q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq, xsq
    "\n\t" "fmul %%st(1), %%st(0)"          //(q4+(q3+(q2+(q1+                xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fldt  %[s_NORMAL_q5]"           //q5, (q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "faddp %%st(0), %%st(1)"     //q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    //num
    "\n\t" "fldt  %[s_NORMAL_p0]"       //p0, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fmul %%st(2), %%st(0)"          //p0*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fldt  %[s_NORMAL_p1]"           //p1, p0*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "faddp %%st(0), %%st(1)"     //p1+p0*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fmul %%st(2), %%st(0)"          //(p1+p0*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fldt  %[s_NORMAL_p2]"           //p2, (p1+p0*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "faddp %%st(0), %%st(1)"     //p2+(p1+p0*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fmul %%st(2), %%st(0)"          //(p2+(p1+p0*xsq)*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fldt  %[s_NORMAL_p3]"       //p3, (p2+(p1+p0*xsq)*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "faddp %%st(0), %%st(1)"     //p3+(p2+(p1+p0*xsq)*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fmul %%st(2), %%st(0)"          //(p3+(p2+(p1+p0*xsq)*xsq)*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fldt  %[s_NORMAL_p4]"       //p4, (p3+(p2+(p1+p0*xsq)*xsq)*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "faddp %%st(0), %%st(1)"     //p4+(p3+(p2+(p1+p0*xsq)*xsq)*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fmul %%st(2), %%st(0)"          //(p4+(p3+(p2+(p1+p0*xsq)*xsq)*xsq)*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fldt  %[s_NORMAL_p5]"       //p5, (p4+(p3+(p2+(p1+p0*xsq)*xsq)*xsq)*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "faddp %%st(0), %%st(1)"     //p5+(p4+(p3+(p2+(p1+p0*xsq)*xsq)*xsq)*xsq)*xsq, q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq), xsq
    "\n\t" "fmulp %%st(0), %%st(2)"     //q5+(q4+(q3+(q2+(q1+xsq)*xsq)*xsq)*xsq)=den, (p5+(p4+(p3+(p2+(p1+p0*xsq)*xsq)*xsq)*xsq)*xsq)*xsq=num
    // num/den
    "\n\t" "fdivp %%st(0), %%st(1)"     //num/den
    "\n\t" "fldt  %[s_oneOverRootTwoPi]"    // oneOverRootTwoPi, num/den
    "\n\t" "fsubrp %%st(0), %%st(1)"        //oneOverRootTwoPi - num/den
    "\n\t" "fldl %[y]"                      //y, (oneOverRootTwoPi - num/den)
    "\n\t" "fdiv %%st(0), %%st(1)"          //y, (oneOverRootTwoPi - num/den)/y

    "\n\t" "sub $8, %%esp" 
    "\n\t" "fstpl  (%%esp)"             //(oneOverRootTwoPi - num/den)/y
    "\n\t" "call (%P[exp_X2_2])" 
    "\n\t" "add $8, %%esp"
    "\n\t" "fmulp %%st(0), %%st(1)" 

    "\n\t" "leave"
    "\n\t" "ret"
    : 
    : [y] "m" (y)
    , [s_oneOverRootTwoPi] "m" (*s_oneOverRootTwoPi)
    , [s_NORMAL_p0] "m" (*s_NORMAL_p0)
    , [s_NORMAL_p1] "m" (*s_NORMAL_p1)
    , [s_NORMAL_p2] "m" (*s_NORMAL_p2)
    , [s_NORMAL_p3] "m" (*s_NORMAL_p3)
    , [s_NORMAL_p4] "m" (*s_NORMAL_p4)
    , [s_NORMAL_p5] "m" (*s_NORMAL_p5)
    , [s_NORMAL_q1] "m" (*s_NORMAL_q1)
    , [s_NORMAL_q2] "m" (*s_NORMAL_q2)
    , [s_NORMAL_q3] "m" (*s_NORMAL_q3)
    , [s_NORMAL_q4] "m" (*s_NORMAL_q4)
    , [s_NORMAL_q5] "m" (*s_NORMAL_q5)
    , [exp_X2_2] "i" (exp_X2_2)
    : 
    );
}

This is the state of the FPU immediately prior to the ineffective load:

(gdb) info float
  R7: Valid   0x3ff4bba0d78724c01468 +0.00071574511983807409
=>R6: Valid   0x3fecb7f59c22579f9f60 +2.7412088761933612e-006
  R5: Empty   0x3ff6f7e2148bebef37f8
  R4: Empty   0x000000020a0d00000007
  R3: Empty   0xf1be000000000002021e
  R2: Empty   0x00001697f1bf00003654
  R1: Empty   0x00020098007c00f8f0c0
  R0: Empty   0x00077c81cc3b0002021e

Status Word:         0xffff3320                  PE             C0 C1
                       TOP: 6
Control Word:        0xffff037f   IM DM ZM OM UM PM
                       PC: Extended Precision (64-bits)
                       RC: Round to nearest
Tag Word:            0xffff0fff
Instruction Pointer: 0x1b:0x00402dbd
Operand Pointer:     0xffff0023:0x004046f0
Opcode:              0xd8c9

I am wondering what is the meaning of the "C1" flag in the status word above - I cannot find documentation on this. This is the state immediately after the failed fldt (executed by the stepi):

(gdb) stepi
0x00402dc5      1485            );
(gdb) info float
  R7: Valid   0x3ff4bba0d78724c01468 +0.00071574511983807409
  R6: Valid   0x3fecb7f59c22579f9f60 +2.7412088761933612e-006
=>R5: Zero    0x00000000000000000000 +0
  R4: Empty   0x000000020a0d00000007
  R3: Empty   0xf1be000000000002021e
  R2: Empty   0x00001697f1bf00003654
  R1: Empty   0x00020098007c00f8f0c0
  R0: Empty   0x00077c81cc3b0002021e

Status Word:         0xffff2920                  PE             C0
                       TOP: 5
Control Word:        0xffff037f   IM DM ZM OM UM PM
                       PC: Extended Precision (64-bits)
                       RC: Round to nearest
Tag Word:            0xffff07ff
Instruction Pointer: 0x1b:0x00402dbf
Operand Pointer开发者_JAVA技巧:     0xffff0023:0x0040cce6
Opcode:              0xdb2d

OK, I have now modified the code so that the instructions at 0x00402db5 and 0x00402dbf are identical. The first succeeds, the second fails. Here is a gdb session showing the disassembled code, and the fpu state immediately before execution of the two identical instructions. The only significant difference in the state is the presence of the C1 flag in the status prior to the execution of the second fldt instruction:

(gdb) disassemble
Dump of assembler code for function poly4(double):
   0x00402d7c <+0>:     push   %ebp
   0x00402d7d <+1>:     mov    %esp,%ebp
   0x00402d7f <+3>:     sub    $0x8,%esp
   0x00402d82 <+6>:     mov    0x8(%ebp),%eax
   0x00402d85 <+9>:     mov    %eax,-0x8(%ebp)
   0x00402d88 <+12>:    mov    0xc(%ebp),%eax
   0x00402d8b <+15>:    mov    %eax,-0x4(%ebp)
=> 0x00402d8e <+18>:    fld1
   0x00402d90 <+20>:    fldl   -0x8(%ebp)
   0x00402d93 <+23>:    fmul   %st(0),%st
   0x00402d95 <+25>:    fdivrp %st,%st(1)
   0x00402d97 <+27>:    fldt   0x40470e
   0x00402d9d <+33>:    fadd   %st(1),%st
   0x00402d9f <+35>:    fmul   %st(1),%st
   0x00402da1 <+37>:    fldt   0x404704
   0x00402da7 <+43>:    faddp  %st,%st(1)
   0x00402da9 <+45>:    fmul   %st(1),%st
   0x00402dab <+47>:    fldt   0x4046fa
   0x00402db1 <+53>:    faddp  %st,%st(1)
   0x00402db3 <+55>:    fmul   %st(1),%st
   0x00402db5 <+57>:    fldt   0x4046f0
   0x00402dbb <+63>:    faddp  %st,%st(1)
   0x00402dbd <+65>:    fmul   %st(1),%st
   0x00402dbf <+67>:    fldt   0x4046f0
   0x00402dc5 <+73>:    faddp  %st,%st(1)
   0x00402dc7 <+75>:    fldt   0x4046dc
   0x00402dcd <+81>:    fmul   %st(2),%st
   0x00402dcf <+83>:    fldt   0x4046d2
   0x00402dd5 <+89>:    faddp  %st,%st(1)
   0x00402dd7 <+91>:    fmul   %st(2),%st
   0x00402dd9 <+93>:    fldt   0x4046c8
   0x00402ddf <+99>:    faddp  %st,%st(1)
   0x00402de1 <+101>:   fmul   %st(2),%st
   0x00402de3 <+103>:   fldt   0x4046be
   0x00402de9 <+109>:   faddp  %st,%st(1)
   0x00402deb <+111>:   fmul   %st(2),%st
   0x00402ded <+113>:   fldt   0x4046b4
   0x00402df3 <+119>:   faddp  %st,%st(1)
   0x00402df5 <+121>:   fmul   %st(2),%st
   0x00402df7 <+123>:   fldt   0x4046aa
   0x00402dfd <+129>:   faddp  %st,%st(1)
   0x00402dff <+131>:   fmulp  %st,%st(2)
   0x00402e01 <+133>:   fdivrp %st,%st(1)
   0x00402e03 <+135>:   fldt   0x40408e
   0x00402e09 <+141>:   fsubrp %st,%st(1)
   0x00402e0b <+143>:   fldl   -0x8(%ebp)
   0x00402e0e <+146>:   fdivr  %st,%st(1)
   0x00402e10 <+148>:   sub    $0x8,%esp
   0x00402e13 <+151>:   fstpl  (%esp)
   0x00402e16 <+154>:   fwait
   0x00402e17 <+155>:   call   0x4013c0 <exp_X2_2(double)>
   0x00402e1c <+160>:   add    $0x8,%esp
   0x00402e1f <+163>:   fmulp  %st,%st(1)
   0x00402e21 <+165>:   fstl   0x406020
   0x00402e27 <+171>:   fld    %st(0)
   0x00402e29 <+173>:   fsubl  0x406020
   0x00402e2f <+179>:   fildll 0x403020
   0x00402e35 <+185>:   fmulp  %st,%st(1)
   0x00402e37 <+187>:   fstpl  0x406020
   0x00402e3d <+193>:   leave
   0x00402e3e <+194>:   ret
   0x00402e3f <+195>:   flds   0x40472c
   0x00402e45 <+201>:   leave
   0x00402e46 <+202>:   ret
End of assembler dump.
(gdb) tbreak *0x00402db5
Temporary breakpoint 61 at 0x402db5: file cody2.cpp, line 1489.
(gdb) continue
Continuing.

Temporary breakpoint 61, 0x00402db5 in poly4 (y=37.37840817302294) at cody2.cpp:1489
1489            );
(gdb) info float
  R7: Valid   0x3ff4bba0d78724c01468 +0.00071574511983807409
=>R6: Valid   0x3ff0c71ba235b8f6a603 +4.7471033066735141e-005
  R5: Empty   0x3ffb8724c9f09161c535
  R4: Empty   0xf13d00000a0d00000007
  R3: Empty   0x07ec000000000002021e
  R2: Empty   0x000016cbc40900003654
  R1: Empty   0x00020098007c00f8f0c0
  R0: Empty   0x00077c81cc3b0002021e

Status Word:         0xffff3120                  PE             C0
                       TOP: 6
Control Word:        0xffff037f   IM DM ZM OM UM PM
                       PC: Extended Precision (64-bits)
                       RC: Round to nearest
Tag Word:            0xffff0fff
Instruction Pointer: 0x1b:0x00402db3
Operand Pointer:     0xffff0023:0x004046fa
Opcode:              0xd8c9
(gdb) stepi
0x00402dbb      1489            );
(gdb) info float
  R7: Valid   0x3ff4bba0d78724c01468 +0.00071574511983807409
  R6: Valid   0x3ff0c71ba235b8f6a603 +4.7471033066735141e-005
=>R5: Valid   0x3ff6f7e2148bebef37f8 +0.0037823963320275824
  R4: Empty   0xf13d00000a0d00000007
  R3: Empty   0x07ec000000000002021e
  R2: Empty   0x000016cbc40900003654
  R1: Empty   0x00020098007c00f8f0c0
  R0: Empty   0x00077c81cc3b0002021e

Status Word:         0xffff2920                  PE             C0
                       TOP: 5
Control Word:        0xffff037f   IM DM ZM OM UM PM
                       PC: Extended Precision (64-bits)
                       RC: Round to nearest
Tag Word:            0xffff03ff
Instruction Pointer: 0x1b:0x00402db5
Operand Pointer:     0xffff0023:0x004046f0
Opcode:              0xdb2d
(gdb) stepi
0x00402dbd      1489            );
(gdb) stepi
0x00402dbf      1489            );
(gdb) info float
  R7: Valid   0x3ff4bba0d78724c01468 +0.00071574511983807409
=>R6: Valid   0x3fecb7f59c22579f9f60 +2.7412088761933612e-006
  R5: Empty   0x3ff6f7e2148bebef37f8
  R4: Empty   0xf13d00000a0d00000007
  R3: Empty   0x07ec000000000002021e
  R2: Empty   0x000016cbc40900003654
  R1: Empty   0x00020098007c00f8f0c0
  R0: Empty   0x00077c81cc3b0002021e

Status Word:         0xffff3320                  PE             C0 C1
                       TOP: 6
Control Word:        0xffff037f   IM DM ZM OM UM PM
                       PC: Extended Precision (64-bits)
                       RC: Round to nearest
Tag Word:            0xffff0fff
Instruction Pointer: 0x1b:0x00402dbd
Operand Pointer:     0xffff0023:0x004046f0
Opcode:              0xd8c9
(gdb) stepi
0x00402dc5      1489            );
(gdb) info float
  R7: Valid   0x3ff4bba0d78724c01468 +0.00071574511983807409
  R6: Valid   0x3fecb7f59c22579f9f60 +2.7412088761933612e-006
=>R5: Zero    0x00000000000000000000 +0
  R4: Empty   0xf13d00000a0d00000007
  R3: Empty   0x07ec000000000002021e
  R2: Empty   0x000016cbc40900003654
  R1: Empty   0x00020098007c00f8f0c0
  R0: Empty   0x00077c81cc3b0002021e

Status Word:         0xffff2920                  PE             C0
                       TOP: 5
Control Word:        0xffff037f   IM DM ZM OM UM PM
                       PC: Extended Precision (64-bits)
                       RC: Round to nearest
Tag Word:            0xffff07ff
Instruction Pointer: 0x1b:0x00402dbf
Operand Pointer:     0xffff0023:0x0040ccf0
Opcode:              0xdb2d
(gdb)


I note that in the debugger, the entries on the stack below the valid entries are marked invalid float value:

st2  <invalid float value>    (raw 0x00077c81cc3b0002021e)
st3  <invalid float value>    (raw 0x00020098007c00f8f0c0)
st4  0                        (raw 0x000013af076300003654)
st5  <invalid float value>    (raw 0x0762000000000002021e)

This leads me to believe that your x87 stack may be corrupted before this routine begins executing. This could be either because you have overflowed the stack, or another routine has used MMX instructions without issuing the requiredemms instruction to restore the floating-point state. Break at entry to your routine and put info float in the gdb, and report the results.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜