简体   繁体   中英

How to write a X8086 assembly program which gets two large numbers as inputs and multiplies and divides them?

I have written the following code so far, which receives each digit of each number separately as inputs and stores them in the ax register (for instance, a five-digit number). However, when it comes to multiplying or dividing them, I have no idea how to get the right answer.

Here's how I received each of my numbers' digits:

 ;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

Your worry about multiplying and dividing the inputs comes a bit too soon .

Incorrect input of the 5-digit number

For the 1st digit you first obtain a (hopefully) valid digit in the range [0,9] and you have it stored in the AL register. Then you use the mul a instruction to multiply this digit according to its rank in the whole number. That's fine except that a is defined a word (holding the value 10000), and so the multiplication will be a word-sized multiplication that multiplies AX by the source operand. The error is that only AL got a defined value and that you haven't made sure that AH is zero.

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

You need the same correction for the 2nd digit because b too is a word-sized variable.

You don't have this problem for the 3rd and 4th digits as both the c and d variables are bytes that perfectly fit the byte-sized multiplication that you need.

The 5th digit poses a problem however. It doesn't require a multiplication (would be times 1), but you can't add AX to the num1 variable without making sure AH is zero.

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

(*) Because AL is a small positive number, you could replace the 2-byte mov ah, 0 instruction by the 1-byte cbw instruction.

Multiplying 2 words

The word-sized multiplication will multiply AX by its word-sized source operand. The product will be in the pair of registers DX:AX.

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

Dividing 2 words

The word-sized division will divide DX:AX by its word-sized source operand. The quotient will be in the AX register and the remainder in the DX register.
It's this double-length dividend DX :AX that is often overlooked: You need to zero DX before doing the division:

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

From you msg3 , I see that you will want to display the results. Next Q/A explains that in some detail: Displaying numbers with DOS .

There's also Inputting multi-radix multi-digit signed numbers with DOS in case you should need a more powerful number input.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM