Search code examples
assemblydosx86-16emu8086

Division by 8 with SHR instruction


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, add 30h 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

Solution

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