2015-08-08 104 views
2

我正在關注這個編譯的代碼(我不知道編譯器也沒有源代碼)。以下彙編代碼是做什麼的?

Sub1: 
mov edx,[esp+04h] 
and edx,00000300h 
or edx,0000007Fh 
mov [esp+06h],dx 
fldcw word ptr [esp+06h] 
retn 

我的理解:

Sub1(4byte param1) 
edx=param1&0x00000300|0x0000007F 
higher 2 bytes of param1 = lower 2 bytes of edx 
fldcw ??????? 

fldcw加載控制字。但是什麼是浮點控制字?

結果存儲在param1的高2字節中。我對嗎?

這個子程序的目的是什麼?

回答

5

FLDCW是加載x87 FPU的16位控制字的指令。例如,可以在this Intel web page上找到控制字的位佈局。

控制字的低8位包含IEEE-754定義的異常的掩碼。 ORing 0x7F因此掩蓋了所有浮點異常,因爲未使用位6和位7。

高8中的控制字的位包含在比特8和9的精度控制,並且在10位舍入控制和11通過AND運算與0x300精度控制在力PC目前被傳遞後保持不變,而舍入控制RC被強制爲0,這對應於IEEE-754舍入模式「round to nearest or even」。

這是不可能說這個功能的目的是什麼。在調用程序刪除的[esp+4]上傳遞一個4字節的整數,提示C調用約定。傳入的4字節整數大概是FPU控制字的先前保存的值,與FSTCW一起存儲,零擴展爲2到4個字節。強制舍入控制和異常的值掩碼建議該函數用於恢復x87控制字的某些編譯器的數學庫默認值,但沒有額外的上下文沒有辦法知道這一點。

+0

非常感謝。我正在閱讀文章。然而,現在我想知道如果這個函數等同於'round(x)',爲什麼輸入參數是4個字節而不是8個字節? – barej

+0

由於你顯示的代碼將舍入控制'RC'設置爲0(舍入到最近或偶數),所以我沒有看到這個代碼如何與'floor()'相關。 'floor()'函數向下舍入,即負無窮大,這對應於1的RC值,而不是0.這裏的代碼看起來像是爲編譯器的庫設置了x87默認值,但是沒有額外的上下文這是純粹的猜測。 FPU控制字是一個16位整數,可能上面的代碼來自一個子程序,該子程序在[esp + 4]處作爲零擴展的4字節整數自變量傳入控制字值,但在此子程序存在之前也是推測 – njuffa

+0

稱爲一行'fstcw word ptr [esp]'被執行。可能與你的意思有關。如果將FPU控制字傳遞給該函數,那麼浮點數的四捨五入是什麼?它在'FPU'的ST(0)中嗎? – barej