Click here to Skip to main content
15,888,330 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
See more:
Can help me fix this, I don't know how to divide the numbers I imputed and the output of it is wrong but I know that my code on the division is wrong but I don't know what is wrong with it and the output of my multiplication doesn't exceed 9, I want to input double digit numbers like 10 and so on but I don't know how
ASM
.model small
.stack 1000
.data

Selection DB 13,10,'1.) Multiplication',10,'2.) Division',10,'3.) Exit',10,10,'Select:$'
First_Number DB 13,10,10,'ENTER FIRST NUMBER:$'
Second_Number DB 13,10,'ENTER SECOND NUMBER: $'

Answer1 DB 13,10,10,'The Product is:$'
Answer2 DB 13,10,10,'The Quotient is:$'

.code
Start:

mov ax, @data
mov ds, ax

mov dx, OFFSET Selection
mov ah, 9
int 21h
mov ah, 1
int 21h

cmp al,'1'
jz Multiplication
cmp al,'2'
jz Division
cmp al,'3'
jz Done

Multiplication:

mov dx, OFFSET First_Number
mov ah, 9
int 21h
mov ah, 01
int 21h
mov bl, al
and bl, 0fh

mov dx,  OFFSET Second_Number
mov ah, 9
int 21h
mov ah, 01
int 21h
mov bh, al
and bh, 0fh

mul bx
mov ah, 0
mov bl, al
aas
or ax, 3030h
mov bx, ax

mov dx, OFFSET Answer1
mov ah, 9
int 21h

mov dl, bh
mov ah, 2
int 21h

mov dl, bl
mov ah, 2
int 21h

Jmp Start
Division:

mov dx, OFFSET First_Number
mov ah, 9
int 21h
mov ah, 01
int 21h
mov bl, al
and bl, 0fh

mov dx,  OFFSET Second_Number
mov ah, 9
int 21h
mov ah, 01
int 21h
mov bh, al
and bh, 0fh

div bx
mov ah, 0
mov bl, al
aas
or ax, 3030h
mov bx, ax
     
mov dx, OFFSET Answer1
mov ah, 9
int 21h

mov dl, bh
mov ah, 2
int 21h

mov dl, bl
mov ah, 2
int 21h

Jmp Start
Done:

mov ah, 4ch
int 21h

END


What I have tried:

I didn't do much changing, I only did the locations of the codes
Posted
Updated 20-Feb-17 10:33am
v2

It's a long time ago that I have written assembly programs using the DOS IRQ 21h.

But your code looks like it needs a lot of fixing.

The following is for the multiplication only.

You are reading two single characters and store them in BL and BH. But the content of the BX register may (and probably will) be changed when calling the next DOS interrupt function. So you would have to push and pop the BX register before and after issuing the call.

You are masking the characters that have been read with 0fh. But they are ASCII characters. If they are known to be digits, 30h must be subtracted instead.

To avoid saving the BX register you can store the input in memory instead. This would also allow using multiple digits later (e.g. until return is entered) and implementing an ASCII to integer conversion.

You are using MUL BX. This will perform the operation DX:AX = AX * BX. But you have loaded BL and BH with the two input values. For proper calculation you have to load these into AL and BL and use MUL BL.

After the multiplication you are trying to convert the result using AAS. That is the wrong method here (it is Adjust AL After Subtraction). You need a hex to decimal string conversion. Or-ing with 0x30 will only work for single digits less than 10.

The printed result is wrong again because the content of the BX register is again destroyed when printing the answer string.

Untested fixes (for results <= 9 only):
Multiplication:

mov dx, OFFSET First_Number
mov ah, 9
int 21h
mov ah, 01
int 21h
mov bl, al
;to number (not checking if a digit here)
sub bl, 30h

;save bx
push bx
mov dx,  OFFSET Second_Number
mov ah, 9
int 21h
mov ah, 01
int 21h
;to number (not checking if a digit here)
sub al, 30h
;restore bx
pop bx

;ax = bl * al
mul bl
;to ASCII (al must be <= 9)
add al,30h

;save result
push ax
mov dx, OFFSET Answer1
mov ah, 9
int 21h
;restore result into dx
pop dx

;print character in dl
mov ah, 2
int 21h

Jmp Start
 
Share this answer
 
Comments
[no name] 20-Feb-17 15:54pm    
it seems to work but the output doesn't exceed 9
Jochen Arndt 21-Feb-17 2:46am    
As stated: That is by design of my solution which is based on your implementation.

You have to implement decimal to string conversion for results greater than nine. Search for something like "asm integer to string" and/or "asm print integer".
When you don't understand what your code is doing or why it does what it does, the answer is debugger.
Use the debugger to see what your code is doing. Just set a breakpoint and see your code performing, the debugger allow you to execute lines 1 by 1 and to inspect variables as it execute, it is an incredible learning tool.

Debugger - Wikipedia, the free encyclopedia[^]
Mastering Debugging in Visual Studio 2010 - A Beginner's Guide[^]

The debugger is here to show you what your code is doing and your task is to compare with what it should do.
There is no magic in the debugger, it don't find bugs, it just help you to. When the code don't do what is expected, you are close to a bug.
 
Share this answer
 
Comments
Graeme_Grant 20-Feb-17 16:39pm    
I don't think asm programming has a debugger...
Patrice T 20-Feb-17 16:51pm    
I can guaranty you that it exist because I have used an asm debugger when I was playing with assembler at the time of DOS.
If I remember, I used CodeView and the TurboC integrated debugger.
Graeme_Grant 20-Feb-17 16:53pm    
Ah, so there is ... x64dbg[^] ... Google is my friend ;)
Patrice T 20-Feb-17 17:01pm    
:-)
enhzflep 20-Feb-17 19:58pm    
Turbo Debugger known simply as TD is the weapon of choice when writing asm code for a DOS environment. DOS don't forget, was a 16 bit environment. The debugger you found is designed to run under windows - not exactly what one needs when running either on real hardware running DOS or inside a DOSbox session.

For those trying to dig yet deeper, there's always (was always) SoftICE.

You could also fire-up a virtual machine using the Bochs virtual machine, install DOS inside it and then use the Bochs debugger - but that truly is for the masochistic when one only wants to debug a DOS program.

TD once again, is _the_ weapon of choice. ;)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900