You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

二进制除法程序输出错误商值,请求代码问题排查

二进制除法程序商值错误排查求助

我运行二进制除法程序时始终无法得到准确的商值,程序持续输出错误的商结果。以下是我的程序代码:

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 19:07:33