因此,我正在构建一个简单的8086程序,该程序允许用户输入2个2位数字和一个运算符并执行操作。如果运算符为“ +”,则将它们相加;如果运算符为“ *”,则将它们相乘并在屏幕上打印结果:
.model small
.stack 100
.data
x db ?
y db ?
rez dw ?
.code
mov ax, data
mov ds, ax
mov es, ax
mov ah, 1
int 21h
sub al, 48
mov bl, 10
mul bl
mov x, al
mov ah, 1
int 21h
sub al, 48
add x, al
mov ah, 1
int 21h
sub al, 48
mov bl, 10
mul bl
mov y, al
mov ah, 1
int 21h
sub al, 48
add y, al
mov ah, 1
int 21h
cmp al, 43
jne Multiply
mov al, x
mov bl, y
add al, bl
mov ah, 0
mov rez, ax
jmp Print
Multiply:
mov al, x
mov ah, 0
mov bl, y
mov bh, 0
mul bx
mov rez, ax
Print:
mov ax, rez
cmp ax, 100
jl Dvocifren
mov bx, 100
div bx
mov cx, dx
mov dl, al
add dl, 48
mov ah, 2
int 21h
mov ax, cx
mov rez, ax
Dvocifren:
mov bx, 10
div bx
mov cl, dl
mov dl, al
add dl, 48
mov ah, 2
int 21h
mov dl, cl
add dl, 48
int 21h
问题出在打印上。如果数字小于100,则跳至仅输出两位数字。但是,如果大于等于100,则将数字除以100,将结果作为3位数中的第一个打印出来,并将其余部分放入AX
中,以便可以继续打印出两位数。但是,当它继续时,我收到错误消息:
除法错误-溢出。
手动处理此错误,
在中断向量表中更改INT 0的地址。
有人可以帮忙吗?
答案 0 :(得分:3)
Dvocifren: mov bx, 10 div bx
当您的代码跳转到此处时,DX
恰好为零(仅当请求的操作是乘法!),这对于WORD大小的除法非常有用
但是,当程序失败时,DX
不再为零。 DL
保存用DOS打印的字符。
通过使用BYTE大小的除法来解决它,或者写:
Dvocifren:
XOR DX, DX
mov bx, 10
div bx
您可能没有意识到这一点,但是2个2位数字的乘积会导致 4位的结果,其中2个2位数字的总和只能产生 3位数的结果。结果,您的程序将在例如32 * 32 = 1024(4位数字!)
由于任务的要求,建议您到处使用BYTE大小的乘法和BYTE大小的除法。
接下来的代码可以显示4位数字的结果:
Multiply:
mov al, x
mov bl, y
mul bl
mov rez, ax
Print:
mov ax, rez
cmp ax, 100
jl Dvocifren
mov bl, 100
div bl
mov cl, ah ;Remainder [0,99]
mov ch, 0
push cx ;Preserve the lowest 2 digits
mov ah, 0 ;Quotient [0,98]
mov bl, 10
div bl
mov cl, ah ;Remainder [0,9]
mov dl, al ;Quotient [0,9]
add dl, 48
mov ah, 02h
int 21h
mov dl, cl
add dl, 48
mov ah, 02h
int 21h
pop ax ;Restore lowest 2 digits
Dvocifren:
mov bl, 10
div bl
mov cl, ah ;Remainder [0,9]
mov dl, al ;Quotient [0,9]
add dl, 48
mov ah, 02h
int 21h
mov dl, cl
add dl, 48
mov ah, 02h
int 21h