'Total Average Grade Calculator emu8086
I'm new to this assembly language emo8086 and I just wanna ask if there's something wrong about this code because I want to display the average grade, but the output is only the word "Average" and it doesn't show any numbers. What should I do to solve or debugg my code?
.MODEL SMALL
.DATA
VAL1 DB ?
DISPLAY1 DB 0AH,0DH,'NUMBER OF SUBJECTS :','$'
DISPLAY2 DB 0AH,0DH,'ENTER GRADE:','$'
DISPLAY3 DB 0AH,0DH,'AVEARGE:','$'
BUFFER DB 3,4 DUP(?)
.CODE
MAIN PROC
.STARTUP
LEA DX,DISPLAY1
MOV AH,09H
INT 21H
MOV AH,01H
INT 21H
SUB AL,30H
MOV CL,AL
MOV BL,AL
MOV AL,00
MOV VAL1,AL
LBL1:
LEA DX,DISPLAY2
MOV AH,09H
INT 21H
MOV AH,0AH
LEA DX,BUFFER
INT 21H
SUB AL,30H
ADD AL,VAL1
MOV VAL1,AL
LOOP LBL1
LBL2:
LEA DX,DISPLAY3
MOV AH,09H
INT 21H
MOV AX,00
MOV AL,VAL1
DIV BL
ADD AX,3030H
MOV DX,AX
MOV AH,02H
INT 21H
MOV AH,4CH
INT 21H
.EXIT
MAIN ENDP
END MAIN
Solution 1:[1]
MOV AH,0AH LEA DX,BUFFER INT 21H SUB AL,30H
The first error is that you are using the DOS.BufferedInput function 0Ah to input the grade, but you are not retrieving the number from the buffer. You seem to expect to find it in the AL register, as would be the case with the DOS.GetCharacter function 01h.
LOOP LBL1
The second error is that you are using the loop
instruction that depends on the whole of the CX register, but your code only ever sets up the CL part of CX. You should never rely on any register content when your program starts, unless such settings were well documented of course.
ADD AX,3030H MOV DX,AX MOV AH,02H INT 21H
The third error is that it looks like you seem to expect to display an average grade composed of two digits and do it with a single invokation of the DOS.PrintCharacter function 02h.
For this simple exercise we can assume that both the number of subjects and their grade are single-digit numbers. Naturally, the average grade will be a single-digit number too.
Using the DOS.Getcharacter function 01h is fine and you are using the correct conversion from character into the value that the digit represents. However, when dealing with user input, you can never truly trust the user to supply a valid input to your program. It's up to you to validate the input. For a single-digit number it's easy enough:
GetDigit0_9:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
sub al, '0'
cmp al, 9
ja GetDigit0_9
Pay attention to the unintentional 'infinite loop' and 'division by zero' problems.
You cannot allow the grade loop to run or the div bl
instruction to execute if the user inputted 0 for the number of subjects. Use the jcxz
(JumpOnCXZero) instruction to either
redo asking the user for a value in [1,9]
LBL0: call GetDigit0_9 ; -> AX=[0,9] mov cx, ax jcxz LBL0 ; Guard against 0 number of subjects
or skip right to the end of the program
jcxz LBL3 ; Guard against 0 number of subjects LBL1: ... loop LBL1 LBL2: ... LBL3: mov ax, 4C00h ; DOS.Terminate int 21h
Revised code:
...
LEA DX, DISPLAY1
MOV AH, 09h ; DOS.PrintString
INT 21h
call GetDigit0_9 ; -> AX=[0,9]
mov cx, ax
mov bl, al ; (*)
MOV VAL1, 0
jcxz LBL3 ; Guard against 0 number of subjects
LBL1:
LEA DX, DISPLAY2
MOV AH, 09h ; DOS.PrintString
INT 21h
call GetDigit0_9 ; -> AX=[0,9]
add VAL1, al
loop LBL1
LBL2:
LEA DX, DISPLAY3
MOV AH, 09h ; DOS.PrintString
INT 21h
mov ah, 0
mov al, VAL1
div bl ; (*)
add al, '0'
mov dl, al
mov ah, 02h ; DOS.PrintCharacter
int 21h
LBL3:
mov ax, 4C00h ; DOS.Terminate
int 21h
; IN () OUT (ax)
GetDigit0_9:
mov ah, 01h ; DOS.GetCharacter
int 21h ; -> AL
sub al, '0'
cmp al, 9
ja GetDigit0_9
mov ah, 0
ret
...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |