MASM32浮点运算程序输出异常求助:计算结果无法正常显示
MASM浮点A+B计算程序异常排查
我用MASM编写了浮点A+B计算的程序,但运行结果异常。尝试过修改_res1 db 14 DUP(0),10,13的缓冲区定义,也把DWORD替换为REAL4,但问题仍未解决。以下是程序代码、运行截图及OllyDBg调试截图,请求排查问题原因。
程序代码
.486 ;设置CPU为80486指令集模式 .model flat, stdcall ;设置内存模型为flat,调用约定为stdcall option casemap :none ;设置符号大小写敏感为不区分 include \masm32\include\windows.inc ;引入windows.inc文件 include \masm32\macros\macros.asm ;MASM支持宏 include \masm32\include\masm32.inc ;引入masm32.inc文件 include \masm32\include\gdi32.inc ;引入gdi32.inc文件 include \masm32\include\fpu.inc ;引入fpu.inc文件 include \masm32\include\user32.inc ;引入user32.inc文件 include \masm32\include\kernel32.inc ;引入kernel32.inc文件 include \masm32\include\msvcrt.inc ;引入msvcrt.inc文件 includelib \masm32\lib\msvcrt.lib ;链接msvcrt.lib库 includelib \masm32\lib\fpu.lib ;链接fpu.lib库 includelib \masm32\lib\masm32.lib ;链接masm32.lib库 includelib \masm32\lib\gdi32.lib ;链接gdi32.lib库 includelib \masm32\lib\user32.lib ;链接user32.lib库 includelib \masm32\lib\kernel32.lib ;链接kernel32.lib库 uselib masm32, comctl32, ws2_32 .data ;数据段定义 _const_A DWORD 1.5 ;定义常量A _const_B DWORD 0.7 ;定义常量B _result DWORD 0.0 ;定义结果变量 _title db "实验5",0 ;消息框标题 strbuf dw ?,0 ;消息框输出缓冲区 _text db " KNEU IITE学生",10, "通过MessageBox输出结果:",10, "A+B",10, "结果: " ;消息框显示文本 _res1 db 14 DUP(0),10,13 ;定义14个0填充的字符串,末尾加换行符和回车符 .code ;代码段开始 start: ;程序入口标记 finit ;初始化协处理器 fld _const_A ;将A加载到FPU栈 fadd _const_B ;将B加到栈顶值上 fstp _result ;将栈顶值保存到_result并弹出栈 invoke FpuFLtoA, 0, 10, ADDR _res1, SRC1_FPU or SRC2_DIMM ;将FPU值转字符串 invoke MessageBox, 0, offset _text, offset _title, MB_ICONINFORMATION ;显示消息框 invoke ExitProcess, 0 ;退出程序 end start ;程序结束
运行截图

OllyDBg调试截图

问题排查与解决
核心问题1:结果字符串未参与消息框显示
调用FpuFLtoA已经把计算结果转成字符串存在_res1里,但MessageBox只传入了_text的偏移地址,完全没把_res1的内容拼接进去,所以消息框里看不到计算结果。
核心问题2:浮点数类型定义错误
在MASM中,DWORD是32位无符号整数类型,REAL4才是32位单精度浮点数的正确类型。之前用DWORD定义浮点数变量,会导致编译器解析错误,必须替换为REAL4。
修复步骤
- 修正变量类型:将数据段中所有浮点数变量的DWORD替换为REAL4:
_const_A REAL4 1.5 _const_B REAL4 0.7 _result REAL4 0.0
- 拼接显示文本与结果:使用
lstrcat函数把_text和_res1的内容合并到同一个缓冲区,再传给MessageBox。同时要给_text预留足够空间:
; 修改_text的定义,预留足够空间存放结果 _text db " KNEU IITE学生",10, "通过MessageBox输出结果:",10, "A+B",10, "结果: ", 100 DUP(0) ; 在调用FpuFLtoA之后添加拼接代码 invoke lstrcat, ADDR _text, ADDR _res1
- 确认缓冲区大小:
_res1的14字节缓冲区足够容纳10位小数的浮点数字符串,无需调整。
修复后的核心代码片段
.data _const_A REAL4 1.5 _const_B REAL4 0.7 _result REAL4 0.0 _title db "实验5",0 _text db " KNEU IITE学生",10, "通过MessageBox输出结果:",10, "A+B",10, "结果: ", 100 DUP(0) _res1 db 14 DUP(0),10,13 .code start: finit fld _const_A fadd _const_B fstp _result invoke FpuFLtoA, 0, 10, ADDR _res1, SRC1_FPU or SRC2_DIMM invoke lstrcat, ADDR _text, ADDR _res1 ; 拼接文本与结果 invoke MessageBox, 0, offset _text, offset _title, MB_ICONINFORMATION invoke ExitProcess, 0 end start
内容的提问来源于stack exchange,提问作者Bogdan Batyuk
相关产品推荐
相关产品推荐

