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
...