汇编打印多位数问题求助:打印乱码后报错终止
嘿,我来帮你排查这个汇编代码的问题~你遇到的乱码+报错情况,大概率是数字转ASCII时的偏移错误、拆分顺序没处理好,或者字符串缺少终止符导致的,下面给你具体拆解和修复方案:
问题分析与解决思路
1. 数字转ASCII的核心错误
汇编里直接打印数字的二进制值是不行的——系统会把它当作ASCII码解析,比如数字5的二进制是0x05,对应的是不可见的控制字符(也就是你看到的乱码)。正确的做法是给每个数字位加上0x30(也就是字符'0'的ASCII值),这样0-9的数字才能转换成对应的可见字符。
2. 拆分数字的顺序问题
当你拆分大于9的数字(比如123)时,通常是先取个位(3)、再十位(2)、再百位(1),如果直接按这个顺序打印,输出会是321而非正确的123。解决办法是把拆分后的每一位先存入缓冲区,倒序输出;或者用栈存储每一位,利用栈“后进先出”的特性反转顺序后再打印。
3. 字符串终止符的问题
如果用MessageBox或WriteConsole这类函数打印字符串,必须确保字符串末尾有0(ASCII空字符)作为终止符,否则函数会持续读取内存直到找到空字符,这会引发乱码甚至内存访问错误。
修复后的示例代码片段
.386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\user32.inc includelib \masm32\lib\user32.lib include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib .data buffer db 10 dup(0) ; 定义缓冲区,预留位置存转换后的字符,末尾预存0作为终止符 num dd 1234 ; 要打印的目标数字 .code start: mov eax, num mov esi, offset buffer + 9 ; 指向缓冲区倒数第二个位置(留最后一位存0) mov ebx, 10 ; 除数,用于拆分数字 split_loop: xor edx, edx div ebx ; eax = 商(剩余未拆分的数字),edx = 余数(当前要处理的数字位) add dl, 30h ; 把余数转换成对应的ASCII字符 dec esi mov [esi], dl ; 把字符存入缓冲区 test eax, eax jnz split_loop ; 直到eax为0,完成所有位的拆分 ; 调用MessageBox打印正确的数字字符串 invoke MessageBox, NULL, esi, NULL, MB_OK invoke ExitProcess, 0 end start
代码说明
- 用
div ebx拆分数字,每次取余数得到当前位,转成ASCII后存入缓冲区的末尾往前的位置 - 缓冲区初始就预存了
0作为终止符,避免出现乱码 - 最后直接传入缓冲区的有效起始位置(esi指向的第一个数字字符)给MessageBox,就能正确输出
1234啦
你可以对照这个示例检查自己的代码,看看是不是没加ASCII偏移、没处理顺序或者遗漏了终止符~
内容的提问来源于stack exchange,提问作者faf
相关产品推荐
相关产品推荐

