汇编中的平均值 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 时尺寸没有问题
下面的代码计算 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 时尺寸没有问题