主题:[讨论]关于ret的问题
yunnuy
[专家分:0] 发布于 2006-04-17 00:10:00
本人初学汇编,很菜。下面这个程序会陷入好多次循环,我只想输出一遍,我想是不是int 21和ret连用的关系,使程序不能返回操作系统,请高手赐教,谢谢。
stack segment stack
db 1024 dup(0)
tos label word
stack ends
data segment
string db 0dh,0ah,'Hello world!$'
data ends
code segment
assume cs:code,ds:data,ss:stack
start:
mov ax,stack
mov ss,ax
mov sp,offset tos
push ds
sub ax,ax
push ax
mov ax,data
mov ds,ax
mov dx,offset string
mov cx,12
mov ah,9
int 21h 就是这里!!!!!
ret
code ends
end start
回复列表 (共5个回复)
沙发
yunnuy [专家分:0] 发布于 2006-04-17 00:13:00
如果就用ret要怎么写才能只输出一遍就返回操作系统??
板凳
yxzmarsm [专家分:50] 发布于 2006-04-17 21:14:00
真的不好意思 我也弄了半天 但是就是找不出其中的原因
stack segment stack
db 1024 dup(0)
tos label word
stack ends
有过好象这个在这里没有什么作用
mov cx,12
这句话我也不知道是否有必要
3 楼
chenzep [专家分:3640] 发布于 2006-04-17 21:21:00
我来回答这个问题把,估计现在懂的人不多了.
RET返回OS是因为你的代码开始有这样的几行代码
push ds
sub ax,ax
push ax
RET的时候,就是把入栈的AX和DS送到IP,CS中去,改变IP,CS的数值,返回到OS
我们现在一般都是用 MOV AX,4C00H,INT 21H返回,所以上面的几行代码现在很少见到了,在老的书还可以见到影子把.
4 楼
yxzmarsm [专家分:50] 发布于 2006-04-21 15:49:00
;stack segment stack
;db 1024 dup(0)
;tos label word
;stack ends
data segment
string db 0dh,0ah,'Hello world!$'
data ends
code segment
main proc far ;在这里必须加这一条伪指令
assume cs:code,ds:data ;,ss:stack
start:
;mov ax,stack
;mov ss,ax
;mov sp,offset tos
push ds
sub ax,ax
push ax
mov ax,data
mov ds,ax
mov dx,offset string
;mov cx,12
mov ah,9
int 21h
ret
code ends
end start
如果用
push ds
sub ax,ax
push ax
.....
ret
这种格式就得在前加同main proc far 这条伪指令
5 楼
pigtwo [专家分:0] 发布于 2006-04-22 09:57:00
stack segment stack
db 1024 dup(0)
tos label word
stack ends
data segment
string db 0dh,0ah,'Hello world!$'
data ends
code segment
assume cs:code,ds:data,ss:stack
str proc far
start: push ds
mov ax,0
push ax
mov ax,stack
mov ss,ax
mov sp,offset tos
push ds
sub ax,ax
push ax
mov ax,data
mov ds,ax
mov dx,offset string
mov cx,12
mov ah,9
int 21h
ret
str endp ;过程结束
code ends ;代码结束
end start ;程序结束
这个问题你有两点没搞明白:
第一是过程调用的属性建议看一下IBM-PC汇编程序设计第二版的P196。
第二就是RET没有理解:其实还是子程序的调用是返回问题
进入子程序之前你要先保护DOS断点,以便你调用结束时
能返回到此push ds是让DOS的段先压栈,再把AX清0压栈
ret所暗含的就是:pop ax ,pop ds这能就返回到DOS
了,再就是为什么要借助于AX:段地址寄存器不能用立
即数来修改,硬件无法实现这一功能
我来回复