汇编中的平均值 8086(宏错误)

Average in assembly 8086 (macro error)

下面的代码计算 20 个用户输入数字的平均值。当我禁用 ShowMsg msg2(将其作为评论)时它工作正常,但是当它启用时,我收到此错误:

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

而且我不知道问题出在哪里。

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

我在 EMU8086 中测试了您的代码,这是对我有用的解决方案,接下来是您的数据段,有 5 个小改动:

data segment      
  sum   dw 0                        ;<==========================
        dw 0                        ;<==========================
  num   dw 0                        ;<==========================
        dw 0                        ;<==========================
  msg1  db 'Enter 20 numbers:', '$'      
  msg2  db 0dh,0ah,'Average: ', '$'        
  array dd 20 dup(0)                ;<==========================
data ends     

在程序"GetNum"中,随着字符被捕获,数组的地址被"msg1"的地址覆盖,因此,捕获的数字覆盖了"msg1"和"msg2"。将数组移动到数据段的末尾修复它(对我来说)。您必须对其进行测试,看看它是否也适合您。

变量 "sum" 和 "num" 的更多变化,因为大小 "DD" 给我带来了问题。解决这个问题的方法是使用两个 "DW",因此在 "num" 和 "sum".

中使用 AX 和 DX 时尺寸没有问题