问题描述
编写一个完整的汇编程序来读取8位数字,每个数字与键盘之间用一个空格分隔(使用单键输入功能)。将它们从字符转换为数字并计算平均、最低和最高分并显示在屏幕上。
提示:从每个字符中减去 30h
以获得实际数字。显示前,在每个数字前加上30h
。对于除法运算,使用适当的移位指令。
Average 显示错误答案!我哪里做错了?请帮我理解SRH指令的划分。
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,8
jae print
jb input
_min:
mov bl,al
cmp cx,10
jae print
jb input
解决方法
无符号数除以 8 与将数字右移 3 次相同。在 8086 编程中,我们需要在执行 CL
指令之前将移位计数放入 shr
寄存器中。因为您已将总和(要除的)放在 DH
寄存器中,并且您想显示 DL
寄存器中的平均值(除法的结果)(由 DOS.PrintChar 函数请求) ),您只需 2 条指令即可完成此操作:
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
就像 _max 一样,这个 _min 应该使用 cmp cx,8
。
更好的是,您可能不应该复制那么多代码!下面的代码使用相反的条件并将所有内容很好地结合在一起:
.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
不要忘记在您的程序中添加一些有意义的注释,以便人们可以快速理解您编写的内容。