END就是汇编结束命令。
解释一下吧:END表示汇编到此结束。同时当程序执行这一句后。 即使后面还有汇编指令也不再执行了。
如果在end前一句有jmp xxxx或者其它跳转语句,且跳转成功后。将会继续跳转的地方继续执行。
只有程序执行end时。才会停下。
201002.04
发信人: wain (北斗星), 信区: CS
标 题: 浅谈如何在汇编程序中实现正常退出
发信站: 听音小筑 (2001年10月14日21:28:55 星期天), 站内信件
【论文题目】浅谈如何在汇编程序中实现正常退出
【单位】天津大学计算机系 95 软件乙班
【作者】李罡
【内容摘要】
本文的主要内容是在汇编语言的程序中实现正常退出的两种方法,即中断法和返回指
令法。本文着重谈到利用 INT 20H 及 21H 中 00H、 31H、27H 实现程序退出的方法,
以及使用 ret 指令返回的注意事项,力求使大家知其然而且知其所以然。本文为作者在
学习汇编语言中遇到的问题以及为了解决问题而实践查阅资料总结出的。草写成文,以
求指正。
浅谈如何在汇编程序中实现正常退出
众所周知,汇编语言是一种低级语言。要在 DOS 级上处理 MS-DOS ,没有一种高级
语言能完全胜任这项工作。要想充分利用你的 *** 作系统,则应直接在机器级别上编程,
这就需要汇编语言。对于学习者来说,学习一门高级语言,如 BASIC、PASCAL 或C后,
就应该着手学习汇编语言,使自己的编程水平提高一个台阶。
初学 8086汇编语言的人,大概第一个遇到的问题就是编的汇编程序如何退出。我们
知道,高级语言不需要考虑专门编写退出语句,编译系统会自动为程序加上结束进程、
返回 DOS 的控制语句的,可汇编语言并不是这样,如你的程序在结束工作后没有退出语
句,CPU 将不知何去何从,必“死”无疑。一般来说,退出一个程序有两种办法,一是
利用中断,二是利用 ret 语句返回。
首先谈谈利用中断。INT 20H 是 DOS 的程序结束中断。比如下面一个程序:
example1.asm
cseg segment
assumecs:cseg
start:org 100h
.
.程序体
.
int 20h
cseg ends
end start
这个结构看起来没什么问题,用 masm 或 tasm 生成 example1.obj,再用link 或
tlink 生成 example1.exe,一运行,准死机。这是为什么呢?
查看《DOS/BIOS 使用详解》,对 INT 20H 的说明为“该功能调用与 DOS 功能调用
00H 完成的 *** 作相同。它使当前进程终止,并将控制权返回到它的父进程。”它的入口
参数要求 CS 指向程序的 PSP 的段地址。原来问题出在这儿。用tlink example1.obj
/t 生成 example1.com ,再运行,正常退出。
原来,这涉及到 COM 与 EXE 都是 DOS 下可执行文件,其区别为 COM 文件比较紧
凑,整个程序限定在 64K 中,结构为:偏移地址 0000 到 0100 放的是程序的 PSP,所
谓 PSP,指的是程序段前缀,对于所有的.com和.exe程序,包括 TSR 在内,DOS 都要设
置称为 PSP 的 256 字节区。PSP 是一种前缀,它在内存程序的前面。内容为程序运行
时必需的数据和缓冲区。PSP 后为程序主体,从低向高放程序数据、代码、附加段内容
(这三个段顺序依程序设计而定),从高(偏移地址00FE)向低入程序的堆栈区,整个
程序中 CS=DS=ES=SS ,CS 不必再设,自然指向PSP段地址(即程序所在段),所以能用
INT 20H 退出。而 exe 程序则比较复杂,需要程序重定位,一般而言各段寄存器地址
不全相同,其中 DS 和 ES 指向 PSP,而 CS 则比 DS 大。例如 example1.exe,若用
debug 载入:
c:>debug example1.exe
-rds
0FB5
:
-rcs
0FC5
:
-q
显然,PSP 段址为 0FB5,而 cs 指向 0FC5 ,故 INT 20H 不能正常退出。
对于.exe的退出,应该采用 Microsoft 推荐的 DOS 调用 4CH 子功能,即将examp
le1.asm 中的 int 20h 换为下面两句:
mov ah,4ch
int 21h
因为 4CH 子功能不要求入口地址,且可用 AL 返回终止代码。用 4CH 可以安全退
出.exe和.com,值得推荐使用。
以上是不驻留退出,对下 TSR (常驻内存程序)其退出可采用 INT 27H 或INT 21
H 的 31H 号子功能,其入口参数为 DX 指向程序常驻部分的底部,然后调用中断,这里
不再详述。
对于用 ret 语句返回,要求以下的格式:
example2.asm
cseg segment
main proc far
assumecs:cseg
start:push ds 初始化堆栈底
xor ax,ax
push ax
.
. 程序体
.
ret
main endp
cseg ends
end start
我们知道,ret 语句用于结束过程,返回父进程。对于主进程而言,其父进程即为
DOS,是 DOS 调用它并执行的,这种调用是远调用,所以 main 过程为 far,可开头三
句初始化是什么意思呢?
我们知道,ret 语句实际上是从堆栈中取出两个字,分别赋给 ip 和 cs ,堆栈底
放的即为父进程的返回地址,这样即实现返回。观察前三句初始化语句实际是把 ds 值
和 0000 推入栈中,(xor ax,ax 是 ax 自身异或,实际上即将 ax 赋0)这样返回时将
0000 赋给 ip ,把程序开始时的 ds 值还给 cs ,实现返回DOS ,这是为什么呢?
我们开头讲过,程序开始时 ds 指向 PSP 区,而 PSP 区的前二个字节放的即为返
回指令,籍此实现返回。
综上所述,返回可以有两种办法:中断法和 ret语句法。中断中可用的是20h、27h
和 21h 中的 00h 、31h、4ch 子功能。其中 20h 和 21h 中断的 00h 子功能不加处理
不能直接用于.exe的返回。INT 27H 和 21H 的 31h 用于驻留返回,其余的用于非驻留
退出。用 ret 语句要先进行堆栈初始化方可。了解以上知识,可以避免在学习汇编语言
中走弯路,为进一步学习汇编语言开个好头。
This entry was posted on 星期四, 二月 4th, 2010 at 6:48 上午 and is filed under 未分类. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
Your Reply
点击这里取消回复
Name (required)
Mail (will not be published) (required)
Website
Pages
关于我
Archives
2010年三月
2010年二月
Categories
未分类 (11)
--------------------------------------------------------------------------------
北斗星文轩 by Themebuilder | Entries (RSS) and Comments (RSS).
http://ligang.name/?p=10
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)