Reputation: 11
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
Upvotes: 1
Views: 631
Reputation: 39166
Your worry about multiplying and dividing the inputs comes a bit too soon.
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.
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)
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.
Upvotes: 1