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.
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 ofmsg3and will be executing some random DOS function. That might be what crashes DosBox.Also, more efficient than
LEAhere (and in the other similar instances) would beMOV DX, OFFSET msg3which has the same effect and saves one byte.First, you zeroed out
AXthus discarding the total value you so carefully computed (remember,AXemcompasses bothAHandAL). Second,DIV r/m16is a 32 by 16 bit division: it divides the 32-bit unsigned value inDX:AXby the value inr/m16, with the quotient placed inAXand the remainder inDX. So here you are dividing100000Hby10H; the quotient is10000hwhich 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,
10His 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
to do a 16 by 8 bit divide of the number from
AL(extended with zeros to produce a 16-bit value inAX) by10, placing the quotient inALand the remainder inAH.You need to add
'0'to the valuesQandRto create printable ASCII characters for output.