NASM汇编两整数乘积转ASCII打印无输出问题排查
问题排查结果
代码无输出/输出错误的核心原因有两个:
- 取值逻辑错误:
mov eax, x、mov ebx, y指令加载的是x和y两个变量的内存地址,不是变量里存的整数值2、3。NASM语法中要获取内存地址中存储的内容,必须用方括号包裹变量名,正确写法是mov eax, [x]、mov ebx, [y]。原代码拿两个内存地址做乘法,结果和预期的6完全不符,加'0'后自然得不到可打印的正确ASCII字符。 - 存储冗余问题:原代码把4字节长度的
eax整体写入预留的4字节mynum空间,但write系统调用只读取1字节长度,虽然x86小端序下低地址刚好存的是结果低字节、小数值场景不影响输出,但存整个4字节属于多余操作,多位数场景还可能引发输出异常。
另外补充注意:32位模式下mul ebx指令的计算结果会存在EDX:EAX寄存器对中,EDX存乘积高32位、EAX存低32位,当前测试用例乘积仅为6,EDX值为0不影响结果,若计算大数字乘积需要处理EDX中的高位值,否则会出现计算错误。
修正后可运行代码
section .text global _start _start: ; 加载两个乘数的实际存储值 mov eax, [x] mov ebx, [y] mul ebx add eax, '0' ; 个位数转ASCII码 mov [mynum], al ; 仅存储1字节长度的ASCII字符即可 ; write系统调用:打印1个字符到标准输出 mov ecx, mynum mov edx, 1 mov ebx, 1 mov eax, 4 int 0x80 ; exit系统调用:程序正常退出 mov eax, 1 mov ebx, 0 int 0x80 section .data x dd 2 y dd 3 segment .bss mynum resb 1 ; 预留1字节空间存单个ASCII字符即可
提示:上述写法仅支持乘积为0-9的单数字场景,如果乘积是多位数,不能直接给整数值加'0'转ASCII,需要逐位拆分每一位数字、分别转码后逆序存储再打印,否则会输出乱码。
内容的提问来源于stack exchange,提问作者Sebastian Bucarion
相关产品推荐
相关产品推荐

