组装程序不是 运行 Intel 8086
Assembly Procedures not running Intel 8086
下面的代码应该获取 20 个用户输入的数字(6 位数字或更少)并计算平均值并对它们进行排序,当我将它设置为获取 6 个或更少的数字时,它工作正常。但是当它设置为获取 7-20 个数字时,在获取数字后,它会跳过下一个过程,有时会再次运行 GetNum 过程(从用户那里获取数字的过程),当它获得 11 个数字时,我收到此消息"PROGRAM HAS RETURNED CONTROL TO THE OPERATING SYSTEM".
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
ave dd 0
array dd 20 dup(0)
msg1 db 'Enter 20 numbers:', '$'
msg2 db 0dh,0ah,'Average: ', '$'
temp dd ?
data ends
stack segment
dd 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
;Printing first message.
ShowMsg msg1
call GetNum
call Average
call Sort
call Print
mov ah, 4ch
int 21h
Main endp
proc GetNum
mov bp, 0
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 array[bp], ax
mov array[bp+2], dx
add bp, 4
add sum, ax
adc sum+2, dx
dec ch
jnz NextNumber
ret
GetNum endp
proc Average
mov bx, 20
mov dx, 0
mov ax, word ptr sum+2
div bx
mov word ptr ave+2, ax
mov ax, word ptr sum
div bx
mov word ptr ave, ax
ShowMsg msg2
mov cl, 0
Next1:
mov bx, 10
mov dx, 0
mov ax, word ptr ave+2
div bx
mov word ptr ave+2, ax
mov ax, word ptr ave
div bx
mov word ptr ave, ax
push dx
inc cl
cmp ave, 0
jnz Next1
Next2:
pop dx
add dl, 30h
mov ah, 02h
int 21h
dec cl
jnz Next2
NewLine
ret
Average endp
proc Sort
mov ch, 20
OuterFor:
mov bp, 0
Cmp1:
mov ax, array[bp+2]
mov bx, array[bp+6]
cmp ax,bx
ja Xchange
cmp ax,bx
jz Cmp2
jmp Next
Cmp2:
mov ax, array[bp]
mov bx, array[bp+4]
cmp ax, bx
ja Xchange
jmp Next
Xchange:
mov ax, array[bp]
mov dx, array[bp+2]
mov temp, ax
mov temp+2, dx
mov ax, array[bp+4]
mov dx, array[bp+6]
mov array[bp], ax
mov array[bp+2], dx
mov ax, temp
mov dx, temp+2
mov array[bp+4], ax
mov array[bp+6], dx
Next:
add bp, 4
cmp bp, 76
jnz Cmp1
dec ch
jnz OuterFor
ret
Sort endp
proc Print
mov bp, 0
C:
mov cl, 0
A:
mov bx, 10
mov dx, 0
mov ax, array[bp+2]
div bx
mov array[bp+2], ax
mov ax, array[bp]
div bx
mov array[bp], ax
push dx
inc cl
mov ax, array[bp]
mov dx, array[bp+2]
or ax, dx
jnz A
B:
pop dx
add dl, 30h
mov ah, 02h
int 21h
dec cl
jnz B
add bp, 4
NewLine
cmp bp, 80
jnz C
ret
Print endp
code ends
end main
问题在于这两行(其他地方也可能类似):
mov array[bp], ax
mov array[bp+2], dx
默认情况下,bp
寄存器寻址 stack
段,而不是 array
所在的 data
段。您必须使用另一个索引寄存器,或者使用
覆盖该段
mov ds:array[bp], ax
mov ds:array[bp+2], dx
如果它与少量元素一起工作,那是幸运的,没有任何东西被破坏而导致崩溃或破坏数据。
更新
我建议修改 GetNum
过程,这样你就可以使用 bx
来索引 array
,而不是 bp
。
proc GetNum
mov bx, 0
mov ch, 20
NextNumber:
push bx
NewLine
...
pop bx
mov array[bx], ax
mov array[bx+2], dx
add bx, 4
...
与您的排序功能类似 - 交换 bx
和 bp
的角色。最好将 bp
用作通用寄存器,将 bx
用作索引寄存器。
下面的代码应该获取 20 个用户输入的数字(6 位数字或更少)并计算平均值并对它们进行排序,当我将它设置为获取 6 个或更少的数字时,它工作正常。但是当它设置为获取 7-20 个数字时,在获取数字后,它会跳过下一个过程,有时会再次运行 GetNum 过程(从用户那里获取数字的过程),当它获得 11 个数字时,我收到此消息"PROGRAM HAS RETURNED CONTROL TO THE OPERATING SYSTEM".
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
ave dd 0
array dd 20 dup(0)
msg1 db 'Enter 20 numbers:', '$'
msg2 db 0dh,0ah,'Average: ', '$'
temp dd ?
data ends
stack segment
dd 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
;Printing first message.
ShowMsg msg1
call GetNum
call Average
call Sort
call Print
mov ah, 4ch
int 21h
Main endp
proc GetNum
mov bp, 0
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 array[bp], ax
mov array[bp+2], dx
add bp, 4
add sum, ax
adc sum+2, dx
dec ch
jnz NextNumber
ret
GetNum endp
proc Average
mov bx, 20
mov dx, 0
mov ax, word ptr sum+2
div bx
mov word ptr ave+2, ax
mov ax, word ptr sum
div bx
mov word ptr ave, ax
ShowMsg msg2
mov cl, 0
Next1:
mov bx, 10
mov dx, 0
mov ax, word ptr ave+2
div bx
mov word ptr ave+2, ax
mov ax, word ptr ave
div bx
mov word ptr ave, ax
push dx
inc cl
cmp ave, 0
jnz Next1
Next2:
pop dx
add dl, 30h
mov ah, 02h
int 21h
dec cl
jnz Next2
NewLine
ret
Average endp
proc Sort
mov ch, 20
OuterFor:
mov bp, 0
Cmp1:
mov ax, array[bp+2]
mov bx, array[bp+6]
cmp ax,bx
ja Xchange
cmp ax,bx
jz Cmp2
jmp Next
Cmp2:
mov ax, array[bp]
mov bx, array[bp+4]
cmp ax, bx
ja Xchange
jmp Next
Xchange:
mov ax, array[bp]
mov dx, array[bp+2]
mov temp, ax
mov temp+2, dx
mov ax, array[bp+4]
mov dx, array[bp+6]
mov array[bp], ax
mov array[bp+2], dx
mov ax, temp
mov dx, temp+2
mov array[bp+4], ax
mov array[bp+6], dx
Next:
add bp, 4
cmp bp, 76
jnz Cmp1
dec ch
jnz OuterFor
ret
Sort endp
proc Print
mov bp, 0
C:
mov cl, 0
A:
mov bx, 10
mov dx, 0
mov ax, array[bp+2]
div bx
mov array[bp+2], ax
mov ax, array[bp]
div bx
mov array[bp], ax
push dx
inc cl
mov ax, array[bp]
mov dx, array[bp+2]
or ax, dx
jnz A
B:
pop dx
add dl, 30h
mov ah, 02h
int 21h
dec cl
jnz B
add bp, 4
NewLine
cmp bp, 80
jnz C
ret
Print endp
code ends
end main
问题在于这两行(其他地方也可能类似):
mov array[bp], ax
mov array[bp+2], dx
默认情况下,bp
寄存器寻址 stack
段,而不是 array
所在的 data
段。您必须使用另一个索引寄存器,或者使用
mov ds:array[bp], ax
mov ds:array[bp+2], dx
如果它与少量元素一起工作,那是幸运的,没有任何东西被破坏而导致崩溃或破坏数据。
更新
我建议修改 GetNum
过程,这样你就可以使用 bx
来索引 array
,而不是 bp
。
proc GetNum
mov bx, 0
mov ch, 20
NextNumber:
push bx
NewLine
...
pop bx
mov array[bx], ax
mov array[bx+2], dx
add bx, 4
...
与您的排序功能类似 - 交换 bx
和 bp
的角色。最好将 bp
用作通用寄存器,将 bx
用作索引寄存器。