【发布时间】:2019-08-09 20:40:27
【问题描述】:
我最近开始学习汇编,现在正在学习 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。我没有收到任何错误代码,因此该函数似乎毫无例外地执行,这告诉我这可能是我编写代码的方式存在逻辑错误。
【问题讨论】:
-
我没有看到任何输出函数。您的输出表明您得到
SDWORDs 作为输出,但您应该得到DOUBLEs。你确定你的输出函数显示DOUBLEs? -
你没有展示任何实际使用这些函数的代码,所以我们只能假设参数的类型是什么。
fahrentocel函数的参数是double,但celtofahren的参数似乎是一个整数,因为它加载了fild。这是故意的吗? -
请发布生成完整、可编译、可运行程序所需的所有其余代码,即minimal reproducible example。
-
我已经添加了 C 代码,对此我深表歉意。谢谢你通知我!
-
@fuz
%f是 double,%Lf是 long double,%lf是编译器供应商想要的任何东西。