簡體   English   中英

使用MASM Assembly中的FPU x87指令集執行操作時,為什么會得到無意義的數字?

[英]Why am I getting nonsensical numbers when performing operations with the FPU x87 instruction set in MASM Assembly?

我最近開始學習匯編,現在正在學習FPU x86體系結構和FPU堆棧。 我有兩個簡單的函數,可在攝氏溫度和華氏溫度之間轉換,反之亦然。

我研究了各種不同的指令,嘗試了FPU指令的各種變體,包括自動執行POP操作的指令,並嘗試通過調試器了解我所看到的內容。 迄今無濟於事。

.386
.model flat, c

.const
  r8_ftoc real8 0.5555555556 ;5/9
  r8_ctof real8 1.8 ;9/5
  i4_32 dword 32
.code
  fahrentocel PROC
    push ebp
    mov ebp, esp
    fld[r8_ftoc]
    fld real8 ptr [ebp+8] ; load f 
    fild[i4_32] ; load 32    
    fsubp
    fmulp
    pop ebp
    ret
  fahrentocel ENDP

  celtofahren PROC
    push ebp
    mov ebp, esp
    fild real8 ptr [ebp+8] ; load c
    fmul[r8_ctof]
    fiadd[i4_32]
    pop ebp
    ret
  celtofahren endp
END

C代碼:

extern "C" double fahrentocel(double temp);
extern "C" double celtofahren(double temp);

int main()
{
    double celsius = 30.0;
    double fahrenheit = 212.0;
    double output = fahrentocel(fahrenheit);
    printf("%lf", output);

}

我對華氏溫度到攝氏溫度的輸入是212.0,因此攝氏溫度輸出是100,而我從攝氏溫度到華氏溫度的轉換是30.0,所以華氏溫度的結果應該是86。

但是,相反,對於這兩個函數,我分別得到562950和858993459。 我沒有收到任何錯誤代碼,因此該函數似乎毫無例外地執行,這表明我編寫代碼的方式可能是邏輯錯誤。

這里有兩個問題。 根據使用它們的C代碼中的函數聲明,即:

extern "C" double fahrentocel(double temp);
extern "C" double celtofahren(double temp);

這兩個函數都使用double參數,並返回double結果。 關於接口,這很好,但是您對celtofahren的實現則celtofahren

fild real8 ptr [ebp+8] ; load c

在這里,即使您自己已指示C編譯器該函數采用double值,也可以將函數的參數作為整數加載到FPU堆棧上。 因此,C編譯器發出的代碼會將double入常規堆棧,但是由於fild指令,您的程序集將其讀取為常規整數。 請注意, fahrentocel正確加載了該參數。

其次,您將錯誤的格式參數傳遞給printf ,對於double值應為f - d用於整數。 從而,

printf("%d", output);

應該成為

printf("%f", output);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM