注册 登录
编程论坛 汇编论坛

汇编子程序ret不到正确的地址

wlmnzf 发布于 2015-04-17 22:46, 4800 次点击
assume cs:code,ds:data,ss:stack

data segment
x dw 1234
y dw 100 dup(?) ;存放数字的ASCII码
data ends

stack segment
dw 16 dup(?)
stack ends

code segment
start:
mov ax,stack
mov ss,ax
mov ax,data
mov ds,ax

mov dx,0
mov ax,x
mov si,0
call s

mov ax,4c00h
int 21h

s proc near
res:mov cx,10

push ax
mov ax,dx
mov dx,0
div cx
mov bx,ax
pop ax
div cx
mov cx,dx
mov dx,bx

push dx
add cl,30h
mov ds:[si+4],cl
pop dx
push ax
push dx
add ax,dx
jz goOut
pop dx
pop ax
inc si
jmp res

goOut:
pop dx
pop ax
mov dl,ds:[si+4]
mov ah,2
int 21h
cmp si,0
jz ok
dec si
jmp goOut

ok:
ret //这个地方使用ret回不到原来的地方,因为程序并未返回dos
;mov ax,4c00h //把ret直接改成返回dos就可以正常运行,请问是怎么一回事
;int 21h

s endp

code ends
end start
7 回复
#2
hu9jj2015-04-18 07:21
中断的返回与程序的结束可不是一回事。
#3
wmf20142015-04-18 09:17
你这个代码编译后属于系统可执行文件,系统加载该文件后会先进行自我现场保护,还会处理一些参数,因此除非你清楚系统做了哪些处理,否则贸然ret可能返回不到正确的位置。
#4
hu9jj2015-04-19 08:09
以下是引用边小白在2015-4-19 07:52:13的发言:

还好,那些字母和数字我还认识,只是拼在一起不知道什么意思。

涉嫌灌水
#5
取名字2015-04-28 10:10
楼主的程序问题出在下面这段代码:
goOut:
pop dx
pop ax
mov dl,ds:[si+4]
mov ah,2
int 21h
cmp si,0
jz ok
dec si
jmp goOut
当程序执行到这一段时,按顺序执行到"cmp si,0"如果si=0则跳到"ok"处执行,程序正常退出,但如果si<>0,则回到"goOut"段继续执行"pop dx""pop ax",但之前入栈的ax与dx已经在第一次执行这2条指令时被弹出了,所以此时弹出的应该是"返回地址",并且程序继续执行下去,如果si<>0,将又跳回"goOut"段执行,这样不断的出栈,而没有入栈操作,等到si=0跳到"ok"段执行时,出栈的已经不是正确的返回地址了,自然不能正确返回.我在汇编网里也回答过.希望能帮到你!
#6
取名字2015-04-29 12:30
goOut:
pop dx
pop ax
mov dl,ds:[si+4]
mov ah,2
int 21h
cmp si,0
jz ok
dec si
jmp goOut
解决办法:
goOut:
pop dx
pop ax
show:
mov dl,ds:[si+4]
mov ah,2
int 21h
cmp si,0
jz ok
dec si
jmp show
#7
wmf20142015-04-30 06:31
回复 9楼 取名字
嗯,认真仔细到位!
#8
取名字2015-04-30 09:08
谢谢wmf2014版主!
1