Инструкцията flds е неуспешна на Mac OSX

Инструкцията flds трябва да съхранява стойността в регистър st0. Отстранявам грешки в споделена библиотека, за която нямам код. Понякога инструкцията flds няма никакъв ефект върху st0. По-долу е gdb изход за случай, когато работи, и случай, когато не работи. В счупения случай регистърът fstat е 0x2261 вместо 0x2061. Какво показва флагът 0x200?

Работна версия:

    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)  

Повредена версия:

    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)  

person user3359929    schedule 27.02.2014    source източник


Отговори (1)


Флаг 0x200 е известен като бит за условие C1 и предоставя допълнителна информация в случай на проблем със стека на FPU. Ръководството на intel казва следното:

Флагът за код на условие C1 се използва за различни функции. Когато и двата флага IE и SF в думата за състояние на x87 FPU са зададени, указващи изключение за препълване на стека или недостиг (#IS), флагът C1 прави разлика между препълване (C1 = 1) и недостатъчно препълване (C1 = 0).

Обърнете внимание, че info float ще ви даде по-подробен дъмп, включително имена на статус и контролни битове, дори с обяснения за последното.

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

Всичко това означава, че някъде кодът не балансира правилно fpu стека. Очевидно както работещата, така и неработещата версия имат проблем със стека, само едната е препълнена, а другата е препълнена, или флагът C1 е променен между тях.

Причината, поради която един от тях работи, вероятно е, че въпросният FPU регистър се оказва празен в един случай. Не можем да кажем това без думата FPU таг (която info float също би показала).

person Jester    schedule 27.02.2014
comment
Благодаря ти за помощта. Сега оправих проблема. Както казвате, стекът вече е повреден и в двата случая. Проблемът беше, че библиотеката извикваше обратно извикване в моя код, който връщаше float вместо int. - person user3359929; 27.02.2014
comment
Добра работа, благодаря за актуализацията. Винаги е хубаво да знаеш как си успял да разрешиш проблема. - person Jester; 27.02.2014