汇编调用C2F过程输出异常:浮点栈使用问题求助
问题排查与修正
核心错误点
转换公式完全错误
摄氏度转华氏度的正确公式是F = C × 9/5 + 32,但你的conversion.asm中使用了Cfirst=2、Csecond=1,实际计算的是C*2 +32,这直接导致结果偏离预期。冗余且错误的栈操作
在C2F过程中,你对系统栈的操作完全多余且存在错误:每次push数据到栈后用fld加载,接着add esp,4释放栈空间,却又执行sub esp,4重新占用,这会破坏栈平衡,且完全没必要——直接从.data段加载数据到FPU栈即可,无需经过系统栈。main过程中的冗余栈操作
main里先push Cel再fld [esp]属于多余操作,直接fld dword ptr [Cel]就能把摄氏度值加载到FPU栈,无需借助系统栈。
修正后的代码
main.asm
Include conversion.asm .386 .model flat, stdcall ; 补充stdcall模型,确保调用约定一致 .stack 4096 ExitProcess PROTO, dwExitCode:DWORD .data Cel DD 25 Faren DD ? .code main PROC fld dword ptr [Cel] ; 直接加载摄氏度值到FPU栈 call C2F fstp dword ptr [Faren] ; 把结果存入Faren变量 ; 注意:ExitProcess的退出码是DWORD,仅能表示0-255的数值,若结果超出会被截断 ; 若要查看完整结果,建议使用调试工具查看Faren变量的值 mov ebx, [Faren] INVOKE ExitProcess, ebx main ENDP END main
conversion.asm
.model flat, stdcall .stack 4096 .data ; 修正公式系数:9/5对应华氏度转换的比例 Cfirst DD 9 Csecond DD 5 common DD 32 C2F PROC fld dword ptr [Cfirst] ; 加载9到FPU栈,栈结构:[C, 9] fmulp ; 执行C*9,栈结构:[C*9] fld dword ptr [Csecond] ; 加载5到FPU栈,栈结构:[C*9,5] fdivp ; 执行(C*9)/5,栈结构:[C*9/5] fld dword ptr [common] ; 加载32到FPU栈,栈结构:[C*9/5,32] faddp ; 执行(C*9/5)+32,栈结构:[F] RET C2F ENDP END ; 补充END,避免编译警告
验证结果
25℃转换为华氏度的正确结果是77,修正后运行代码,Faren变量的值将是77,通过ExitProcess传递的退出码也会是77,符合预期。
内容的提问来源于stack exchange,提问作者Pruthvi Batta
相关产品推荐
相关产品推荐

