I was trying to run my assembly language program and it is when i try to enter the 2nd input, the cursor freezes and the DOSbox emulator would crash after a few seconds of delay.
I've tried running other assembly language programs and they seem to be working fine. Im not sure of the reason behind this, could it be an error in my code (MASM format) / not enough RAM to run the program? My code is attached below and I had 1.5GB of RAM available while I was running the program.
.MODEL SMALL
.STACK
.DATA
msg1 DB "Quantity (unit): $"
msg2 DB 13,10,"Unit price (RM): $"
msg3 DB 13,10,"Total amount is RM$"
Quantity DB 0
Unit_price DB 0
Total DB 0
Q DB 0
R DB 0
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV AH, 09H
LEA DX, msg1
INT 21H
MOV AH, 01H
INT 21H
MOV Quantity, AL
MOV AH, 09H
LEA DX, msg2
INT 21H
MOV AH, 01H
INT 21H
MOV Unit_price, AL
MOV AH, 09H
LEA AX, msg3
INT 21H
XOR AX, AX
SUB Quantity, '0'
SUB Unit_price, '0'
MOV AL, Quantity
MUL Unit_price
MOV Total, AL
XOR AX, AX
MOV DX, 10H
DIV DX
MOV Q, AL
MOV R, AH
MOV AH, 02H
MOV DL, Q
INT 21H
MOV AH, 02H
MOV DL, R
INT 21H
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAIN
Three bugs that I can see, including some spotted in comments.
MOV AH, 09H
LEA AX, msg3
INT 21H
Looks like a typo for LEA DX, msg3
. As it stands you will have a random value in AH (the high byte of the address of msg3
and will be executing some random DOS function. That might be what crashes DosBox.
Also, more efficient than LEA
here (and in the other similar instances) would be MOV DX, OFFSET msg3
which has the same effect and saves one byte.
XOR AX, AX
MOV DX, 10H
DIV DX
First, you zeroed out AX
thus discarding the total value you so carefully computed (remember, AX
emcompasses both AH
and AL
). Second, DIV r/m16
is a 32 by 16 bit division: it divides the 32-bit unsigned value in DX:AX
by the value in r/m16
, with the quotient placed in AX
and the remainder in DX
. So here you are dividing 100000H
by 10H
; the quotient is 10000h
which overflows 16 bits, and so you will get a divide overflow exception.
This could also be the cause of the crash, though I seem to recall that real MS-DOS had a handler for the divide overflow interrupt that would print a message and terminate the program, without crashing the system. I'm not sure if DosBox provides that, however.
Also, 10H
is hex, so you're dividing by sixteen. I'm assuming you probably wanted decimal output, so you want to divide by ten (10
) instead.
Thus, I think you probably meant
XOR AH, AH ; zero-extend AL into AX
MOV DL, 10
DIV DL
to do a 16 by 8 bit divide of the number from AL
(extended with zeros to produce a 16-bit value in AX
) by 10
, placing the quotient in AL
and the remainder in AH
.
MOV AH, 02H
MOV DL, Q
INT 21H
You need to add '0'
to the values Q
and R
to create printable ASCII characters for output.