在C++中將浮點數強制轉換為整數,做了些什麼——ftol註釋
阿新 • • 發佈:2019-01-23
_ftol2: 0040142C 55 push ebp 0040142D 8B EC mov ebp,esp 0040142F 83 EC 20 sub esp,20h //堆疊上空出20h個位元組,用於儲存臨時變數 00401432 83 E4 F0 and esp,0FFFFFFF0h //將esp對齊到16位元組 00401435 D9 C0 fld st(0) //壓入st(0),原先的st(0)變為st(1),這樣st(1) == st(0) 00401437 D9 54 24 18 fst dword ptr [esp+18h] //將st(0)轉換為單精度(dword) 儲存倒[esp + 18h]位置 0040143B DF 7C 24 10 fistp qword ptr [esp+10h] //將st(0)取整儲存到[esp+10h]位置,這個結果是64位的(qword),結果偏0還是遠離0應該取決於協處理器msw。同時彈出st(0),原先的st(1)變為st(0) 0040143F DF 6C 24 10 fild qword ptr [esp+10h] //將剛才取整的結果load到st(0)。現在st(1)是原值,st(0)是取整後的值 00401443 8B 54 24 18 mov edx,dword ptr [esp+18h] //取原值單精度版到edx 00401447 8B 44 24 10 mov eax,dword ptr [esp+10h] //取64位取整結果的低32位 0040144B 85 C0 test eax,eax 0040144D 74 3C je integer_QnaN_or_zero (0040148B) //如果eax位0,則該浮點數可能是0或者NAN arg_is_not_integer_QnaN: 0040144F DE E9 fsubp st(1),st //原值減去取整後的結果,結果在st(0)中。取整結果如果偏0, 原值為正結果得正,原值為負結果得負; 取整結果如果遠離0, 原值為正結果得負,原值為負結果得正 00401451 85 D2 test edx,edx //測試原浮點數的單精度格式 00401453 79 1E jns positive (00401473) //如果原值是非負數則跳轉,以下是負數的處理方法 00401455 D9 1C 24 fstp dword ptr [esp] //將減法結果儲存到[esp]位置,彈出棧頂元素,st(0)變為原值 00401458 8B 0C 24 mov ecx,dword ptr [esp] 0040145B 81 F1 00 00 00 80 xor ecx,80000000h //減法結果最高位取反,其餘位不變 00401461 81 C1 FF FF FF 7F add ecx,7FFFFFFFh //如果減法結果為正,則最高為取反後為1,再加7FFFFFFFh必定CF=1,即遠離0;如果減法結果為0或者負數,則CF=0,即偏向0 00401467 83 D0 00 adc eax,0 //對於負浮點數,取整結果遠離0(CF=1)就是多減了1,需要加1,讓結果偏0;取整結果如果偏向0(CF=0),結果eax加上CF和0,值仍然不變 0040146A 8B 54 24 14 mov edx,dword ptr [esp+14h] 0040146E 83 D2 00 adc edx,0 00401471 EB 2C jmp localexit (0040149F) positive: 00401473 D9 1C 24 fstp dword ptr [esp] //註釋同上 00401476 8B 0C 24 mov ecx,dword ptr [esp] 00401479 81 C1 FF FF FF 7F add ecx,7FFFFFFFh 0040147F 83 D8 00 sbb eax,0 //對於正浮點數,取整遠離0(CF=1)就是多加了1,需要減1,讓結果偏0;取整結果如果偏向0(CF=0),結果減去CF和0,值仍然不變 00401482 8B 54 24 14 mov edx,dword ptr [esp+14h] 00401486 83 DA 00 sbb edx,0 00401489 EB 14 jmp localexit (0040149F) integer_QnaN_or_zero: //對於0或者NAN 0040148B 8B 54 24 14 mov edx,dword ptr [esp+14h] //取64位取整結果的高32位 0040148F F7 C2 FF FF FF 7F test edx,7FFFFFFFh //測試高字的低31位, 00401495 75 B8 jne arg_is_not_integer_QnaN (0040144F) 00401497 D9 5C 24 18 fstp dword ptr [esp+18h] 0040149B D9 5C 24 18 fstp dword ptr [esp+18h] localexit: 0040149F C9 leave 004014A0 C3 ret //結果在eax中