如何在汇编中输出十进制数值而非其ASCII表示?乘法程序求助
解决汇编程序乘法结果十进制输出异常的问题
你的程序输出异常的核心原因是:直接把乘法得到的二进制数值(比如24)作为字节输出,而系统调用int 0x80的4号功能(write)会把这个字节当作ASCII码解析。24对应的ASCII是不可打印的控制字符,所以屏幕显示异常。要输出十进制数字,必须先把二进制数值转换成对应的ASCII字符串(比如24转成'2'和'4'),再输出。
修改方案
下面是调整后的完整代码,包含数值转十进制ASCII的逻辑:
section .text global _start _start: ; 3 x 8 = 24 mov ax, 3 mov bl, 8 mul bl ; 结果存在ax中,这里乘积是24,al=24, ah=0 call num_to_dec ; 调用转换子程序,把al中的数值转成十进制ASCII字符串,存在buffer中 ; 输出提示信息(可选) mov eax, 4 mov ebx, 1 mov ecx, msg mov edx, msg_len int 0x80 ; 输出转换后的十进制结果 mov eax, 4 mov ebx, 1 mov ecx, buffer mov edx, dec_len int 0x80 ; 程序退出 mov eax, 1 xor ebx, ebx int 0x80 ; 子程序:将al中的8位无符号数转换为十进制ASCII字符串 ; 输入:al = 要转换的数值(0~255) ; 输出:buffer中存储转换后的ASCII字符串,dec_len存储字符串长度 num_to_dec: mov cx, 0 ; cx记录数字位数 mov bx, 10 ; 除数设为10 mov di, buffer + 3 ; 从buffer末尾开始存储(预留4位足够存0~255的十进制) convert_loop: xor dx, dx ; dx清零,准备除法 div bx ; ax = ax / 10,dx = ax % 10 add dl, 0x30 ; 余数转成ASCII(0x30是'0'的ASCII码) dec di mov [di], dl inc cx test ax, ax ; 判断商是否为0 jnz convert_loop mov dec_len, cx ; 保存数字长度 mov buffer, di ; 保存字符串起始地址 ret section .data msg db "乘法结果:", 0xA msg_len equ $ - msg buffer resb 4 ; 预留4字节存储十进制字符串(最多3位数字+换行/结束符) dec_len db 0
关键说明
num_to_dec子程序:通过除以10取余的方式拆分数字,余数加上0x30转成对应ASCII字符(比如余数2转成'2'),因为取余得到的是低位到高位,所以从buffer末尾往前存储,最后调整起始地址。- 数据段的
buffer预留了4字节,足够存储0~255范围内的所有十进制数字(最多3位),dec_len记录转换后的字符串长度,确保输出时不会多输出无关字节。 - 保留了系统调用的正确使用:
eax=4是write功能,ebx=1表示标准输出,ecx是输出内容地址,edx是输出长度。
编译链接命令
和你原来的命令一致:
nasm -f elf32 multiply.asm -o multiply.o ld -m elf_i386 -s -o multiply multiply.o
运行后就能看到正确的十进制输出了。
内容的提问来源于stack exchange,提问作者oleg002
相关产品推荐
相关产品推荐

