Question

The flds instruction should store the value in register st0. I am debugging a shared library I don't have code for. Sometimes the flds instruction doesn't have any effect on st0. Below is gdb output for a case when it works and a case when it fails. In the broken case the fstat register is 0x2261 instead of 0x2061. What does the 0x200 flag indicate?

Working version:

    0x6d9b4f :    flds   -0x4(%ebp)  
    0x6d9b52 :    leave  
    0x6d9b53 :    ret  
    (gdb) info registers fstat st0 st1 st2 st3 st4 st5 st6 st7  
    fstat          0x2061   8289  
    st0            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st1            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st2            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st3            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st4            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st5            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st6            780250362506194  (raw 0x4030b1688c6c5af48000)  
    st7            1        (raw 0x3fff8000000000000000)  
    (gdb) ni  
    0x006d9b52 in Startup ()  
    1: x/3i $pc  
    0x6d9b52 :    leave  
    0x6d9b53 :    ret  
    0x6d9b54 :    push   %ebp  
    (gdb) info registers fstat st0 st1 st2 st3 st4 st5 st6 st7  
    fstat          0x1861   6241  
    st0            -1584    (raw 0xc009c600000000000000)  
    st1            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st2            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st3            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st4            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st5            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st6            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st7            780250362506194  (raw 0x4030b1688c6c5af48000)  

Broken version:

    0x6d9b4f :    flds   -0x4(%ebp)  
    0x6d9b52 :    leave  
    0x6d9b53 :    ret  
    (gdb) info registers fstat st0 st1 st2 st3 st4 st5 st6 st7  
    fstat          0x2261   8801  
    st0            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st1            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st2            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st3            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st4            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st5            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st6            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st7            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    (gdb) ni  
    0x006d9b52 in Startup ()  
    1: x/3i $pc  
    0x6d9b52 :    leave  
    0x6d9b53 :    ret  
    0x6d9b54 :    push   %ebp  
    (gdb) info registers fstat st0 st1 st2 st3 st4 st5 st6 st7  
    fstat          0x1a61   6753  
    st0            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st1            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st2            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st3            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st4            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st5            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st6            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
    st7            -nan(0xc000000000000000) (raw 0xffffc000000000000000)  
Was it helpful?

Solution

Flag 0x200 is known as C1 condition bit, and it provides additional information in case of an FPU stack problem. The intel manual says this:

The C1 condition code flag is used for a variety of functions. When both the IE and SF flags in the x87 FPU status word are set, indicating a stack overflow or underflow exception (#IS), the C1 flag distinguishes between overflow (C1 = 1) and underflow (C1 = 0).

Note that info float will give you a more verbose dump, including status and control bit names, even with explanations for the latter.

Status Word:         0x1a61   IE             PE        SF      C1
                       TOP: 3

What all this means is somewhere the code doesn't balance the fpu stack properly. Apparently both the working and the broken version have a stack problem, just one is underflow and the other is overflow, or the C1 flag has been changed in between.

The reason one of them works is probably because the FPU register in question happens to be empty in one case. We can't tell that without the FPU tag word (which info float would also show).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top