Write a complete assembly program to read 8 digits, each digit separated by a single space from the keyboard (use single key input function). Convert them from character to numbers and calculate the average, lowest and highest score and display them on the screen.
Hint: Subtract
30h
from each character to get actual digit. Before display, add30h
to each digit. For division operation, use appropriate shift instruction.
Average is showing the wrong answer! Where did I do wrong? Plz help me understand division by SRH instruction.
Include emu8086.inc
.model small
.stack 100h
.data
.code
mov bh,0
mov bl,9
mov ah,1
mov dh,0
mov cx,0
input:
int 21H
putc 20h
sub al,30h
inc cx
add dh,al
cmp al,bh
JA _max
cmp al,bl
JB _min
cmp cx,8
JB input
print:
mov ah,2
printn
mov dl,bh
add dl,30h
printn "Max: "
int 21h
printn
mov dl,bl
add dl,30h
printn "Min: "
int 21h
AND dh, 0FH
mov Cl,3
shr dh,cl
or dh,30H
printn
mov dl,dh
printn "Avg: "
int 21h
exit:
mov ah,4ch
int 21h
_max:
mov bh,al
cmp al,bl
JB _min
cmp cx,8
jae print
jb input
_min:
mov bl,al
cmp cx,10
jae print
jb input
Dividing by 8 of an unsigned number is the same as shifting the number 3 times to the right. In 8086 programming we need to put the shift count in the CL
register before executing the shr
instruction. Because you have placed the sum (that you want to divide) in the DH
register and you want to display the average (result from the division) from the DL
register (requested by the DOS.PrintChar function), you can do this in just 2 instructions:
mov cl, 11 ; 11 = 3 (is divide DH by 8) + 8 (is move DH to DL)
shr dx, cl
_min: mov bl,al cmp cx,10
Just like the _max, this _min should be using cmp cx, 8
.
Better still, you should probably not duplicate that much code! Below code uses the opposite conditions and keeps everything nicely together:
.code
mov bx, 9 ; BH=0 is Max, BL=9 is Min
xor dx, dx ; DH=0 is Sum, DL=0 is Count
input:
mov ah, 01h ; DOS.GetCharacter
int 21h
putc 20h
sub al, 30h
add dh, al ; Add to Sum DH
cmp al, bh
jbe NotMax
mov bh, al ; Set new max BH
NotMax:
cmp al, bl
jae NotMin
mov bl, al ; Set new Min BL
NotMin:
inc dx ; Increment Count DL
cmp dl, 8
jb input
Don't forget to add some meaningful comments in your programs so people can quickly understand what you have written.