MASM摄氏转华氏程序idiv指令整数溢出,求改写方案得59°F
解决MASM摄氏转华氏程序的整数溢出问题
问题分析
你的代码执行idiv dword ptr [NINE]时触发整数溢出,核心原因是**idiv指令要求被除数是64位的EDX:EAX组合**,但你仅将乘法结果存入EAX,EDX未做符号扩展处理,导致除法操作时被除数的高位(EDX)是随机值,触发溢出。另外变量命名混乱(NINE实际存的是5),且输入温度32°C转华氏是90°F,不符合你要的59°F结果(对应15°C)。
改写方案及修改点
- 修正变量命名:将存储除数5的变量
NINE改为FIVE,避免逻辑混淆 - 修复除法溢出:在
imul之后添加cdq指令,将EAX的符号位扩展到EDX,形成合法的64位有符号被除数EDX:EAX - 调整输入温度:将
CelsiusTemperature设为15,确保计算结果为59°F - 简化冗余代码:移除函数中多余的栈空间操作,直接用EAX传递结果
修改后的完整代码
.386 .model flat, stdcall .stack 4096 ExitProcess PROTO, dwExitCode:DWORD .data CelsiusTemperature DWORD 15 ; 15°C 转华氏为59°F .code ; 摄氏转华氏函数 ; 输入: ecx - 摄氏温度 ; 输出: eax - 华氏温度 _convertC2F PROC push ebp mov ebp, esp mov eax, ecx ; 加载摄氏温度到EAX imul eax, 9 ; 乘以9: 15*9=135 cdq ; 将EAX符号位扩展到EDX,形成EDX:EAX=00000000 00000087(135的十六进制) idiv dword ptr [FIVE] ; 除以5: 135/5=27 add eax, 32 ; 加32: 27+32=59 pop ebp ret _convertC2F ENDP main PROC mov ecx, CelsiusTemperature call _convertC2F ; EAX中现在存储59(0x3B) ; 可在此处添加代码将结果写入内存,比如: ; mov dword ptr [result], eax (需在.data段定义result DWORD ?) INVOKE ExitProcess, 0 main ENDP FIVE DWORD 5 ; 修正变量命名,存储除数5 END main
关键修改说明
cdq指令的作用:对于有符号除法idiv,必须确保EDX是EAX的符号扩展结果。如果EAX是正数,EDX会被清零;如果是负数,EDX会被设为0xFFFFFFFF。这样EDX:EAX构成完整的64位被除数,避免溢出。- 输入温度调整:15°C转换为华氏的计算过程为
(15 * 9)/5 +32 = 135/5 +32=27+32=59,正好符合你要的结果。 - 冗余代码移除:原函数中
sub esp,4和栈存储返回值的操作完全多余,因为EAX本身就是函数返回值的标准寄存器,直接使用即可。
内容的提问来源于stack exchange,提问作者wizard
相关产品推荐
相关产品推荐

