二进制除法程序输出错误商值,请求代码问题排查
二进制除法程序商值错误排查求助
我运行二进制除法程序时始终无法得到准确的商值,程序持续输出错误的商结果。以下是我的程序代码:
divide proc ; 设置PROMPT_1的光标位置 mov ah, 02h mov bh, 00h mov dh, 0Bh ; 行 mov dl, 0Ah ; 列 int 10h ; 显示第一个数字的提示 mov dx, offset PROMPT_1 ;(第一个二进制输入) mov ah, 09h int 21h ; 初始化被除数为0 xor bl, bl ; 读取第一个二进制数 mov cx, 8 mov ah, 01h @DIV_LOOP_1: int 21h cmp al, 0Dh jne @DIV_SKIP_1 jmp @DIV_EXIT_LOOP_1 @DIV_SKIP_1: and al, 0Fh shl bl, 1 or bl, al loop @DIV_LOOP_1 @DIV_EXIT_LOOP_1: ; 设置PROMPT_2的光标位置 mov ah, 02h mov bh, 00h mov dh, 0Ch ; 行 mov dl, 0Ah ; 列 int 10h ; 显示第二个数字的提示 mov dx, offset PROMPT_2 ;(第二个二进制输入) mov ah, 09h int 21h ; 初始化除数为0 xor bh, bh ; 读取第二个二进制数 mov cx, 8 mov ah, 01h @DIV_LOOP_2: int 21h cmp al, 0Dh jne @DIV_SKIP_2 jmp @DIV_EXIT_LOOP_2 @DIV_SKIP_2: and al, 0Fh shl bh, 1 or bh, al loop @DIV_LOOP_2 @DIV_EXIT_LOOP_2: ; 执行二进制除法 xor ch, ch ; 商 xor dl, dl ; 减法结果临时寄存器 mov cl, bl ; 将被除数移到cl ; 确保除数不为0,避免除零错误 cmp bh, 0 je @DIV_DIVISION_ERROR mov dl, 8 ; 位位置计数器 @DIV_DIVISION_SHIFT: shl cl, 1 ; 被除数左移 rol ch, 1 ; 商左移,腾出位置写入新位 sub cl, bh ; 尝试用被除数减除数 jc @DIV_SUBTRACTION_FAILED or ch, 1 ; 如果无进位,设置商的最低位为1 jmp @DIV_SUBTRACTION_DONE @DIV_SUBTRACTION_FAILED: add cl, bh ; 减法失败,恢复被除数 @DIV_SUBTRACTION_DONE: dec dl jnz @DIV_DIVISION_SHIFT ; 设置PROMPT_3的光标位置 mov ah, 02h mov bh, 00h mov dh, 0Dh ; 行 mov dl, 0Ah ; 列 int 10h ; 显示结果标签 mov dx, offset DIV_PROMPT_3 mov ah, 09h int 21h ; 显示结果(商) mov bl, ch call DISPLAY_BINARY ; 等待用户输入暂停 mov ah, 01h int 21h ret @DIV_DIVISION_ERROR: ; 处理除零错误 mov ah, 09h mov dx, offset DIVISION_ERROR_MSG int 21h jmp @DIV_END_PROGRAM @DIV_END_PROGRAM: ; 等待用户输入暂停 mov ah, 01h int 21h ret DISPLAY_BINARY: ; 转换并显示BL中的二进制数 mov cx, 8 mov ah, 02h @DISPLAY_LOOP: shl bl, 1 jc @ONE_BIT mov dl, 30h jmp @DISPLAY_BIT @ONE_BIT: mov dl, 31h @DISPLAY_BIT: int 21h loop @DISPLAY_LOOP ret ; 等待用户输入暂停 mov ah, 01h int 21h ret
相关提示信息:
PROMPT_1 DB 'INPUT FIRST NUMBER [000-111]: $' PROMPT_2 DB 'INPUT SECOND NUMBER [000-111]: $'
我尝试了多种方法解决该问题,但程序仍持续输出错误商值,恳请帮忙排查代码中的问题。
问题排查与修复方案
1. 输入读取逻辑不匹配
提示要求输入3位二进制数,但代码中读取循环设置mov cx, 8,会强制读取8个字符。用户输入3位后按回车,程序会继续等待输入直到凑够8个,导致被除数(bl)和除数(bh)的值被错误填充。
修复:
将两处读取循环的cx值改为3:
; 读取第一个二进制数时 mov cx, 3 ; 替换原mov cx,8 ; 读取第二个二进制数时同样修改 mov cx,3
2. 除法核心逻辑错误
当前除法循环的步骤不符合标准二进制移位减法流程,导致商计算错误。正确流程应为:先将被除数左移,把最高位移入进位标志CF,再根据CF或当前值判断是否够减除数,最后更新商的位。
修复后的除法循环:
; 执行二进制除法 xor ch, ch ; 商初始化为0 mov cl, bl ; 被除数存入cl mov dl, 3 ; 输入为3位,循环3次即可,替换原8 @DIV_DIVISION_SHIFT: shl cl, 1 ; 被除数左移,最高位进入CF rol ch, 1 ; 商左移,腾出最低位 jnc @CHECK_SUBTRACT ; CF为0时,先检查是否够减 sub cl, bh ; CF为1,直接减除数 or ch, 1 ; 商的最低位置1 jmp @DIV_SUBTRACTION_DONE @CHECK_SUBTRACT: cmp cl, bh ; 比较当前被除数与除数 jb @DIV_SUBTRACTION_DONE ; 不够减则跳过 sub cl, bh ; 够减则减除数 or ch, 1 ; 商的最低位置1 @DIV_SUBTRACTION_DONE: dec dl jnz @DIV_DIVISION_SHIFT
3. 冗余代码问题
程序末尾有一段不属于任何过程的暂停代码,会导致执行错误,需删除:
; Pause for user input mov ah, 01h int 21h ret
4. 显示逻辑优化
DISPLAY_BINARY默认显示8位,但实际商最多3位,可修改显示循环的cx为3,避免冗余前导0:
DISPLAY_BINARY: ; 转换并显示BL中的二进制数(仅显示3位) mov cx, 3 mov ah, 02h @DISPLAY_LOOP: shl bl, 1 jc @ONE_BIT mov dl, 30h jmp @DISPLAY_BIT @ONE_BIT: mov dl, 31h @DISPLAY_BIT: int 21h loop @DISPLAY_LOOP ret
内容的提问来源于stack exchange,提问作者Nazh Eclan
相关产品推荐
相关产品推荐

