用 SHR 指令除以 8

问题描述

编写一个完整的汇编程序来读取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

不要忘记在您的程序中添加一些有意义的注释,以便人们可以快速理解您编写的内容。