assembly 如何编写一个X8086汇编程序,它可以得到两个大数作为输入,并将它们相乘和相除?

yeotifhr  于 2023-01-02  发布在  其他
关注(0)|答案(1)|浏览(113)

到目前为止,我已经编写了下面的代码,它分别接收每个数字的每一位作为输入,并将它们存储在ax寄存器中(例如,一个五位数),但是,当涉及到乘或除它们时,我不知道如何得到正确的答案。
以下是我收到每个数字的过程:

;TITLE Multiply input with number then add them

.model small
.stack 100
.data
   
msg1 DB 13,10,"First input = $" ;
msg2 DB 13,10,"Second input = $"
msg3 DB 13,10,"Result = $"

num1 dw ?;user inputs
num2 dw ?

a dw 10000
b dw 1000
c db 100
d db 10

.code
main proc 
mov ax, @data
mov ds, ax

mov ah, 9h
lea dx, msg1
int 21h

mov ah, 1h
int 21h
sub al, 30h
mul a
mov num1, ax

mov ah, 1h
int 21h
sub al, 30h
mul b
add num1, ax

mov ah, 1h
int 21h
sub al, 30h
mul c
add num1, ax

mov ah, 1h
int 21h
sub al, 30h
mul d
add num1, ax

mov ah, 1h
int 21h
sub al, 30h
add num1, ax

; Getting the five digits of the first number
zwghvu4y

zwghvu4y1#

  • 您对输入的乘法和除法的担心来得有点太早了 *。

5位数字输入错误

对于第一位,您首先获得(希望如此)范围[0,9]内的有效数字,并将其存储在AL寄存器中。然后使用mul a指令,根据该数字在整数中的排名,将其相乘。除了 * a * 被定义为之外,这很好(保存值10000),所以乘法是一个字长的乘法,将AX乘以源操作数。错误是只有AL有一个定义的值,而您没有确保AH为零。

mov  ah, 01h
int  21h
sub  al, 30h
mov  ah, 0    ; (*)
mul  a
mov  num1, ax

您需要对第二位进行相同的校正,因为 * b * 也是一个字长变量。
对于第3位和第4位数,您不会遇到这个问题,因为 * c * 和 * d * 变量都是字节,完全符合您需要的字节大小的乘法。
但是第5位数有个问题,它不需要乘法(乘以1),但是如果不确保AH为零,就不能将AX加到 * num1 * 变量上。

mov  ah, 01h
int  21h
sub  al, 30h
mov  ah, 0    ; (*)
add  num1, ax

(*)因为AL是一个小正数,所以可以用1字节cbw指令替换2字节mov ah, 0指令。

乘2个单词

字长乘法将AX乘以字长的源操作数。乘积将存储在寄存器对DX:AX中。

mov  ax, num1
mul  num2        ; -> AX is product (if you can ignore DX)

分开两个单词

字长除法将DX:AX除以字长的源操作数。商存储在AX寄存器,余数存储在DX寄存器。
这是一个经常被忽略的双倍长被除数DX:AX!在做除法之前,你需要将DX清零:

mov  ax, num1
xor  dx, dx
div  num2        ; -> AX is quotient

从您的 * msg3 * 中,我看到您希望显示结果。下一个Q/A将详细解释:Displaying numbers with DOS.
还有Inputting multi-radix multi-digit signed numbers with DOS,以防您需要更强大的数字输入。

相关问题