这是代码,您认为它为什么不断产生错误的商有什么问题。
divide proc
; Set cursor position for PROMPT_1
mov ah, 02h
mov bh, 00h
mov dh, 0Bh ; row
mov dl, 0Ah ; column
int 10h
; Display the prompt for the first number
mov dx, offset PROMPT_1 ;(THIS IS THE FIRST BINARY INPUT)
mov ah, 09h
int 21h
; Initialize the dividend to zero
xor bl, bl
; Read the first binary number
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:
; Set cursor position for PROMPT_2
mov ah, 02h
mov bh, 00h
mov dh, 0Ch ; row
mov dl, 0Ah ; column
int 10h
; Display the prompt for the second number
mov dx, offset PROMPT_2 ;(THIS IS THE SECOND BINARY INPUT)
mov ah, 09h
int 21h
; Initialize the divisor to zero
xor bh, bh
; Read the second binary number
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:
; Perform binary division
xor ch, ch ; quotient
xor dl, dl ; temporary register for subtraction result
mov cl, bl ; move dividend to cl
; Ensure divisor is not zero to avoid division by zero
cmp bh, 0
je @DIV_DIVISION_ERROR
mov dl, 8 ; bit position counter
@DIV_DIVISION_SHIFT:
shl cl, 1 ; shift left the dividend
rol ch, 1 ; rotate left the quotient to shift in a new bit
sub cl, bh ; attempt to subtract divisor from dividend
jc @DIV_SUBTRACTION_FAILED
or ch, 1 ; if no carry, set LSB of quotient
jmp @DIV_SUBTRACTION_DONE
@DIV_SUBTRACTION_FAILED:
add cl, bh ; restore dividend if subtraction failed
@DIV_SUBTRACTION_DONE:
dec dl
jnz @DIV_DIVISION_SHIFT
; Set cursor position for PROMPT_3
mov ah, 02h
mov bh, 00h
mov dh, 0Dh ; row
mov dl, 0Ah ; column
int 10h
; Display the result label
mov dx, offset DIV_PROMPT_3
mov ah, 09h
int 21h
; Display the result (quotient)
mov bl, ch
call DISPLAY_BINARY
; Pause for user input
mov ah, 01h
int 21h
ret
@DIV_DIVISION_ERROR:
; Handle division by zero error
mov ah, 09h
mov dx, offset DIVISION_ERROR_MSG
int 21h
jmp @DIV_END_PROGRAM
@DIV_END_PROGRAM:
; Pause for user input
mov ah, 01h
int 21h
ret
DISPLAY_BINARY:
; Convert and display the binary number in 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
; Pause for user input
mov ah, 01h
int 21h
ret
我尝试了不同的方法来解决这个问题,但它总是产生错误的商。你能检查一下我的代码有什么问题吗?
显示是这样的
PROMPT_1 DB 'INPUT FIRST NUMBER [000-111]: $'
PROMPT_2 DB 'INPUT SECOND NUMBER [000-111]: $'
它不断产生错误的商。你能检查一下我的代码有什么问题吗?
你的输入和输出例程很好,但实际的除法算法在我看来是不可挽救的。
以下所有代码都将 AL 除以 BL,在 AL 中产生商,在 AH 中产生余数。
div
您的问题中没有任何地方提到限制不使用
div
指令。所以这里是:
test bl, bl
jz @DIV_DIVISION_ERROR
mov ah, 0
div bl ; AX / BL -> AL is quotient, AH is remainder
这是迄今为止最简单的替代解决方案; (不使用
div
指令的解决方案):
test bl, bl
jz @DIV_DIVISION_ERROR
mov ah, 0 ; Temporary quotient
.a:
inc ah
sub al, bl
jnb .a
dec ah
add al, bl
xchg al, ah ; -> AL is quotient, AH is remainder
快得多,可能就是您的目标,但仍然没有使用
div
指令:
xor dl, dl ; Quotient under construction
mov cl, 1 ; Nominal weight of the divisor BL
test bl, bl
jz @DIV_DIVISION_ERROR
js .Subtract ; Divisor already occupies MSB of its byte-sized container
.ShiftUp:
shl cl, 1 ; Adjust the weight of the current divisor
shl bl, 1 ; Double the current divisor
jns .ShiftUp ; Until at MSB of the byte-sized container
.Subtract:
cmp bl, al ; Could we borrow-less subtract current divisor from dividend ?
ja .Skip ; No, then skip
add dl, cl ; Add current weight to quotient under construction
sub al, bl ; Lower dividend by current divisor (building remainder)
.Skip:
shr bl, 1 ; Try next lower divisor
shr cl, 1 ; Adjust to lesser weight
jnz .Subtract ; Repeat for as long as there is weight
mov ah, al ; -> AH is remainder
mov al, dl ; -> AL is quotient