title: Average in assembly 8086 (macro error)
body: <p>The code below computes the average of 20 user entered numbers. It works fine when I disable <code>ShowMsg msg2</code> (make it a comment), but when its enabled, I get this error :</p>
  
  <pre><code>INT 21h, AH=09h - 
  address: 0711E
  byte 24h not found after 2000 bytes.
  ; correct example of INT 21h/9h:
  mov dx, offset msg
  mov ah, 9
  </code></pre>
  
  <p>And I cant figure what the problem is.</p>
  
  <pre><code>ShowMsg macro msg     
  mov ah, 09h      
  mov dx, offset msg      
  int 21h  
  endm
  
  NewLine macro      
  mov ah, 02h      
  mov dl, 0ah      
  int 21h      
  mov dl, 0dh      
  int 21h
  endm
  
  
  data segment      
  sum   dd 0      
  num   dd 0           
  array dd 20 dup(0)      
  msg1  db 'Enter 20 numbers:', '$'      
  msg2  db 0dh,0ah,'Average: ', '$'        
  data ends     
  
  stack segment      
  dw 100 dup(?)  
  stack ends    
  
  code segment      
  assume cs:code, ds:data, ss:stack      
  Main Proc Far                    
      mov ax, data          
      mov ds, ax          
      mov ax, stack          
      mov ss, ax
  
      ShowMsg msg1
      lea si, array                   
      call GetNum
  
      ;**** PROBLEM IS HERE! ****
      ShowMsg msg2 
      lea si, array         
      call Average        
  
      mov ah, 4ch          
      int 21h                
      Main endp
  
  ;Gets 20 numbers(max 6 digit) from user 
  ;and puts them in the array 
  ;which its effective address is in SI.
  proc GetNum
      push si                           
      mov ch, 20
  
      NextNumber:          
      NewLine                    
      mov cl, 6          
      mov word ptr num, 0          
      mov word ptr num+2, 0
  
      GetChar:              
      mov ah, 07h          
      int 21h                
      cmp al, 0dh          
      jz Flag                 
      cmp al, 30h          
      jb GetChar                
      cmp al, 39h          
      ja GetChar
  
      mov ah, 02h          
      mov dl, al         
      int 21h
  
      sub al, 30h                
      mov bl, al  
      mov di, 10          
      mov ax, num          
      mul di                
      mov num, ax          
      push dx               
      mov ax, num+2          
      mul di                
      mov num+2, ax          
      pop dx          
      add num+2, dx                
      mov bh, 0          
      add num, bx          
      adc word ptr num+2, 0
  
      dec cl          
      jnz GetChar
  
      Flag:          
      mov ax, num          
      mov dx, num+2                
      mov [si], ax          
      mov [si+2], dx          
      add si, 4                     
  
      dec ch          
      jnz NextNumber
  
      pop si            
      ret       
      GetNum endp
  
  ;Computes the average of numbers in the array 
  ;which its effective address is in SI.
  proc Average
      push si
      mov cx, 20
  
      Average_Next:
      mov ax, [si]
      add word ptr sum, ax
      mov ax, [si+2]
      adc word ptr sum+2, ax
      add si, 4
      loop Average_Next
  
      mov bx, sum
      mov bp, sum+2
      mov di, 20
  
      call Div32
  
      call Show
  
      pop si
  
      ret 
      Average endp
  
  ;Divides BP:BX to DI,
  ;returns the quotient to BP:BX,
  ;remainder to DX
  proc Div32
      mov dx, 0
      mov ax, bp
      div di
      mov bp, ax
      mov ax, bx
      div di
      mov bx, ax
      ret
      Div32 endp
  
  ;Prints the number in BP:BX
  proc Show
      mov di, 10
      mov cx, 0
  
      Show_Next1:
      call Div32
      push dx
      inc cx
      or bp, bx
      jnz Show_next1
  
      Show_next2:
      pop dx
      add dl, 30h
      mov ah, 02h
      int 21h
      loop Show_next2
  
      ret
      Show endp
  </code></pre>