汇编关于ret怎么没有返回到正确的地方??
这个程序整体是关于输入人名,输入电话号码,存进tel_tab中,制成一个电话本。再做查找,输出想要查找的人名的号码。
整个程序debug了貌似没什么问题,只是主要有个问题就是在search那个子程序里,那个子程序最后的ret返回的位置不对,用debug时发现的,不知道它为什么会乱跳,是因为堆栈的问题吗,不大明白哪出问题了,后来我就把那个search子程序删掉,并把里面的内容整个复制,贴到主程序里了,这样没了ret就运行正常了。
但是!!我还是想知道为什么???!!哪里的问题!!!!
高手帮忙解答一下呗!!
data segment
; namepar label byte
maxnlen db 21
namelen db ?
namefld db 21 dup(?)
numberpar label byte
maxmlen db 9
numlen db ?
numfld db 9 dup(?)
judge label byte
maxjlen db 2
judgelen db ?
judgefld db 2 dup(?)
crlf db 13,10, '$ '
tel_tab db 50 dup(28 dup(?))
table db 28 dup(?),13,10, '$ '
messg1 db 'name tel. ',13,10, '$ '
messg2 db 'Input name: ', '$ '
messg3 db 'Input a telephone number: ', '$ '
messg4 db 'Do you want a telephone number? ',13,10, '$ '
messg5 db 'name? ',13,10, '$ '
messg6 db 'No match! ', '$ '
endaddr dw ?
have_xchd db 0
printit db 0
data ends
;--------------------------------------
code segment
main proc far
assume cs:code,ds:data
mov ax,data
mov ds,ax
mov es,ax
mov cx,50
lea di,tel_tab
loop1:
cmp cx,0
jz sort
call input_name
cmp namelen,0
jz sort
call stor_name
mov ah,09h
lea dx,messg3
int 21h
call inphone
dec cx
jmp loop1
sort:
cmp cx,50
jz over
call name_sort
y_or_n:
mov ah,09h
lea dx,messg4
int 21h
mov ah,0ah
lea dx,judge
int 21h
mov al,judgefld
cmp al,4eh
jz over
cmp al,59h
jne y_or_n
mov ah,09h
lea dx,messg5
int 21h
call input_name
call name_search
jmp y_or_n ;ret该返回的位置
over:
mov ax,4c00h
int 21h
main endp
;--------------------------------------------
input_name proc near
push cx
mov ah,09h
lea dx,messg2
int 21h
mov ah,0ah
; lea dx,namepar
lea dx,maxnlen
int 21h
mov ah,09h
lea dx,crlf
int 21h
mov bh,0
mov bl,namelen
mov cx,21
sub cx,bx
to_blank:
mov namefld[bx],20h
inc bx
loop to_blank
pop cx
ret
input_name endp
;------------------------------------------------
stor_name proc near
push cx
cld
lea si,namefld
; lea di,tel_tab
mov cx,20
rep movsb
pop cx
ret
stor_name endp
;-------------------------------------------------
inphone proc near
push cx
mov ah,0ah
lea dx,numberpar
int 21h
mov ah,09h
lea dx,crlf
int 21h
cld
lea si,numfld
mov cx,8
rep movsb
pop cx
ret
inphone endp
;-------------------------------------------------
name_sort proc near
push di
lea di,tel_tab
mov ax,50
sub ax,cx
dec ax
mov bx,28
imul bx
add di,ax
mov endaddr,di
sort0:
mov have_xchd,0
lea si,tel_tab
sort1:
mov di,si
mov cx,20
cld
add di,28
mov ax,di
mov bx,si
; cmp di,endaddr
; jz sort0
repe cmpsb
jbe no_xche
call yes_xche
no_xche:
mov si,ax
cmp si,endaddr
jb sort1
; jbe sort1
cmp have_xchd,0
jnz sort0
pop di
ret
name_sort endp
;---------------------------------------------
yes_xche proc near
push di
mov cx,28
lea di,table
mov si,bx
rep movsb
mov cx,28
mov di,bx
rep movsb
mov cx,28
lea si,table
rep movsb
mov have_xchd,1
pop di
ret
yes_xche endp
;--------------------------------------------
name_search proc near ;问题所在子程序,这是一个查询搜索
push di
lea di,tel_tab
mov ax,endaddr
add ax,28
compare:
lea si,namefld
mov printit,0
mov bx,di
mov cx,20
; push si
cld
repe cmpsb
; pop si
jne go_on
call printline
go_on:
mov di,bx
add di,28
cmp printit,1
jz exit
cmp di,ax
jb compare
mov ah,09h
lea dx,messg6
int 21h
pop di
exit: ret ;这个ret返回的位置不固定貌似,它怎么乱跳呢它,按道理讲它应该返回到上面注释的 那个位置吧?就是这里不会。
name_search endp
;-------------------------------------------
printline proc near
push di
push cx
mov ah, 09h
lea dx,messg1
int 21h
mov cx,28
cld
lea di,table
mov si,bx
rep movsb
mov ah,09h
lea dx,table
int 21h
mov printit,1
pop cx
pop di
ret
printline endp
;-----------------------------------------------
code ends
end main
[解决办法]
ret 不能正确返回,无法是子程里的堆栈操作不平衡,或者是无意破坏了堆栈里的内容。你这里,那个子程中的 exit: 标号位置错了,应该在 pop di 指令之前;现在的样子导致子程开始时压栈的 di 没有被出栈,致使堆栈没平衡,ret 指令就返回到了错误的地方。