汇编语言除法程序问题:余数显示错误
汇编除法程序余数显示错误的排查与修复
该汇编程序用于实现两个一位数的除法运算并输出商.余数格式的结果,但当运算存在余数时,余数会显示错误数值;余数为0时可正常运行。
原问题代码
jmp start mess1 db 'Enter 1st number: $' mess2 db 0a,0d, 'Enter 2nd number: $' nextline db 0a,0d, '$' start: mov ax, 03 int 10h mov dx, offset mess1 call printstring call input sub al, 30h push ax mov dx, offset mess2 call printstring call input mov bl, al mov dx, offset nextline call printstring sub cl, 30h sub bl, 30h pop ax mov ah, 0 aad div bl mov dl, al add dl, 30h push ax call printchar mov dl, '.' call printchar mov ah, 0 pop ax mov dl, ah add dl, 30h call printchar int 20h input: mov ah, 1 int 21h ret printstring: mov ah, 9 int 21h ret printchar: mov ah, 2 int 21h ret
错误原因分析
- 无效指令干扰:
sub cl, 30h属于完全多余的代码,cl寄存器未初始化,执行此指令会修改随机值,虽不会直接导致余数错误,但可能引发标志位混乱,属于无效冗余代码。 - 不必要的BCD转换:
aad指令用于将AX中的两位BCD数转为二进制,但本程序仅处理一位数输入,mov ah, 0后AX已为纯二进制值,aad指令完全多余,若后续代码修改时遗漏mov ah, 0,会直接导致被除数错误(比如AX变为0105h,aad后转为十进制15,除法结果完全偏离预期)。 - 寄存器初始化时机滞后:第一个数入栈前未将
ah置0,入栈的AX包含input过程遗留的ah=1,虽然后续修正了该问题,但冗余操作增加了出错概率。
修复后的代码
jmp start mess1 db 'Enter 1st number: $' mess2 db 0a,0d, 'Enter 2nd number: $' nextline db 0a,0d, '$' start: ; 清屏操作 mov ax, 03h int 10h ; 输入第一个数并转二进制 mov dx, offset mess1 call printstring call input sub al, 30h mov ah, 0 ; 提前初始化AH,确保AX为纯二进制被除数 push ax ; 输入第二个数并转二进制 mov dx, offset mess2 call printstring call input mov bl, al mov dx, offset nextline call printstring sub bl, 30h ; 执行除法运算 pop ax div bl ; AX / BL,商存AL,余数存AH ; 打印商 mov dl, al add dl, 30h call printchar ; 打印小数点 mov dl, '.' call printchar ; 打印余数 mov dl, ah add dl, 30h call printchar ; 程序结束 int 20h ; 输入字符:返回AL为输入字符的ASCII码 input: mov ah, 1h int 21h ret ; 打印字符串:DS:DX指向以'$'结尾的字符串 printstring: mov ah, 9h int 21h ret ; 打印字符:DL为要打印的字符ASCII码 printchar: mov ah, 2h int 21h ret
修复说明
- 删除了无效的
sub cl, 30h指令 - 移除了多余的
aad指令 - 将
mov ah, 0提前到第一个数入栈前,确保入栈的AX是正确的纯二进制被除数 - 删除了打印余数前冗余的
mov ah, 0指令 - 添加了注释提升代码可读性
内容的提问来源于stack exchange,提问作者JOHN PHILIP ILUSTRISIMO
相关产品推荐
相关产品推荐

