NASM汇编中div指令除法运算异常问题求助
NASM除法指令div使用问题排查与修正
代码中的核心错误
- 输入处理错误:
sys_read读取输入时,num1和num2定义为resb 2,会同时读取用户输入的数字和换行符(ASCII 0xA),后续未过滤换行符导致数值计算错误。 - 重复的ASCII转数值操作:对
num1和num2执行了两次sub '0',将已转成十进制的数值再次减去48,导致数值严重偏离正确值。 - 结果存储越界:
res仅定义为1字节(resb 1),但代码用mov [res], ax写入16位数据,破坏内存中其他数据。 - 冗余且错误的寄存器操作:存在逻辑混乱的寄存器清零操作(如
mov ebx, 0注释却标注为清除eax高16位),属于无效操作。
修正后的代码
section .data msg1 db "Enter first digit (a): ", 0 len1 equ $- msg1 msg2 db "Enter second digit (b): ", 0 len2 equ $- msg2 newLine db 0xA msg3 db "The division (a/b) is: ", 0 len3 equ $- msg3 section .bss num1 resb 2 num2 resb 2 res resb 1 section .text global _start _start: ; 提示输入第一个数字 mov eax, 4 mov ebx, 1 mov ecx, msg1 mov edx, len1 int 0x80 ; 读取第一个数字 mov eax, 3 mov ebx, 0 mov ecx, num1 mov edx, 2 int 0x80 ; 提示输入第二个数字 mov eax, 4 mov ebx, 1 mov ecx, msg2 mov edx, len2 int 0x80 ; 读取第二个数字 mov eax, 3 mov ebx, 0 mov ecx, num2 mov edx, 2 int 0x80 ; 提示输出结果 mov eax, 4 mov ebx, 1 mov ecx, msg3 mov edx, len3 int 0x80 ; 处理第一个数字:取输入的数字字符,转十进制 mov al, [num1] sub al, '0' mov [num1], al ; 处理第二个数字:取输入的数字字符,转十进制 mov bl, [num2] sub bl, '0' mov [num2], bl ; 16位除法准备:被除数为DX:AX,除数为BX mov ax, [num1] mov dx, 0 mov bx, [num2] div bx ; AX=商,DX=余数 ; 商转ASCII并存储 add al, '0' mov [res], al ; 输出商 mov eax, 4 mov ebx, 1 mov ecx, res mov edx, 1 int 0x80 ; 输出换行 mov eax, 4 mov ebx, 1 mov ecx, newLine mov edx, 1 int 0x80 ; 退出程序 mov eax, 1 int 0x80
关键修改说明
- 输入过滤:改用
mov al, [num1]只取输入的第一个字符(数字),忽略后续换行符,避免干扰数值转换。 - 移除重复转换:仅执行一次
sub '0'的ASCII转十进制操作,确保数值正确。 - 内存安全存储:用
mov [res], al写入1字节数据,匹配res的定义,避免内存越界。 - 规范除法操作:明确16位除法的寄存器规则,用
mov dx, 0清零DX,确保被除数为DX:AX,逻辑清晰。 - 简化换行符定义:移除冗余的空字符串,直接定义
newLine db 0xA,保证换行输出正确。
内容的提问来源于stack exchange,提问作者X_Abhishek_X
相关产品推荐
相关产品推荐

