You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

汇编打印多位数问题求助:打印乱码后报错终止

嘿,我来帮你排查这个汇编代码的问题~你遇到的乱码+报错情况,大概率是数字转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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:31:19