《汇编语言》——王爽 第四章 第一个程序

现在我们开始将编写完整的汇编语言程序,用编译和连接程序将它们编译连接成为可执行文件(如.exe),在操作系统中运行。

4.1一个源程序从写出到执行的过程

....

操作系统依照可执行文件中的描述信息,将可执行文件中的机器码和数据加载入内存,并进行相关的初始化(比如设置CS:IP指向第一条要执行的指令),然后由CPU执行

4.2源程序

1.伪指令:

在汇编语言源程序中,包含两种指令,一种是汇编指令,一种是伪指令。汇编指令是有对应的机器码的指令,伪指令没有对应的机器码,最终不被CPU执行。

伪指令是由编译器来执行的指令。

程序4.1中出现了3种伪指令:

1 XXX segment,XXX ends

这是一对成对使用的伪指令,segment说明一个段开始,ends说明一个段结束

一个段必须有一个名称来标识,使用格式为:

段名: segment

段名 : ends

一个汇编程序是由多个段组成的,这些段被用来存放代码,数据或当作栈空间来使用。一个源程序中所有将被计算机所处理的信息:指令,数据 ,栈被划分到了不同的段中。

一个有意义的汇编指令至少要有1个段,这个段用来存放代码。

2 end

end是一个汇编程序的结束标记

不要搞混了 end与ends

3 assume

以后我们编程时,记着用assume将有特定用途的段和相关的段寄存器关联起来即可。

2.源程序中的“程序”

注意,以后可以将源程序文件中的所有内容称为源程序,将源程序中最终由计算机执行,处理的指令或数据,成为程序。

3.标号

汇编源程序中,除了汇编指令和伪指令外i,还有一些标号如“codesg”,这个段的名称最终将被编译,连接程序处理为一个段的段地址。

4.程序的结构

5.程序返回

我们的程序最先以汇编指令的形式存在源程序中,经编译,连接后转变为机器码,存储在可执行文件中,那么它怎样得到运行呢?

下面,我们在DOS(一个单任务操作系统)的基础上,简单地讨论一下这个问题。

一个程序P2在可执行文件中,则必须有一个正在运行的程序P1,将P2从可执行文件中加载到内存后,将CPU的控制权交给P2,P2才能得以运行。P2开始运行后,P1暂停运行。而当P2运行完毕后,应该将CPU的控制权交还给使它得以运行的程序。

我们称这个过程为程序返回。那么,如何返回呢?应该在程序的末尾添加返回的程序段:

看一下程序4.1中的两条指令:

mov ax,4c00H

int 21H

这两条指令所实现的功能就是程序返回。

在目前阶段,只要知道在程序的末尾使用这两条指令就可以实现程序返回。

 6.语法错误和逻辑错误

程序在编译时被编译器发现的错误是语法错误

在运行时发生的错误是逻辑错误

4.3编辑源程序

4.4编译

注意,在编译的过程中,我们提供了一个输入,即源程序文件夹。最多可以得到3个输出:目标文件(obj),列表文件(list),交叉引用文件(.crf),这3个输出文件中,目标文件是我们最终要得到的结果,而另外两个只是中间结果,在汇编课程中,我们不讨论这两类文件。

4.5连接

连接的作用:

见书

注意,对于连接的过程,可执行文件是我们要得到的最终结果。

4.6以简化的方式进行编译和连接

4.7 1.exe的执行

4.8 谁将可执行文件中的程序装载进入内存并使它运行?

看一下4.7节中1.exe的执行过程(思考相关问题)

(1)在提示符“c:\masm"后面输入可执行文件的名字”1“,按Enter键,这时,请思考问题4.1

(2)1.exe中的程序得以运行

(3)运行结束,返回,再次显示提示符”c:\masmm",请思考问题4.2

问题4.1

此时,有一个正在运行的程序将1.exe中的程序加载入内存,这个正在运行的程序是什么?它将程序加载入内存后,如何使程序得以运行?

问题4.2

程序运行结束后,返回到哪里?

如果你对DOS有比较深入的了解,那么,很容易回答。如果没有了解,请看下面的内容(见书)

DOS中有一个程序command.com,这个程序在DOS中成为命令解释器,也就是DOS系统的shell

DOS启动时,先完成其他重要的初始化工作,在运行command.com

在DOS中,command处理各种输入:命令或要执行的程序的文件名

现在回答问题4.1和4.2中所提出的问题:

(1):在DOS中直接执行1.exe时,是正在运行的command,将1.exe中的程序加载入内存

(2):command设置CPU的CS:IP指向程序中的第一条指令(即程序的入口),从而使程序得以运行。

(3):程序运行结束后,返回到command中,CPU继续运行command

汇编程序从写出到执行的过程:

4.9 程序执行过程的跟踪

对于简单的错误,仔细检查一下源程序就可以发现,而对于隐藏较深的错误,就必须对程序的执行过程跟踪分析才容易发现。

现在我们知道,在DOS运行一个程序的时候,是由command将程序从可执行文件中加载入内存,并使其得以执行。但是,这样我们不能逐条指令地看到程序的执行过程,因为command的程序加载,设置CS:IP指向程序的入口的操作是连续完成的,而当CS:IP一指向程序的入口,command就放弃了CPU的控制权,CPU立即开始运行程序,直至程序结束。

为了观察程序的运行过程,可以使用Debug,Debug可以将程序加载入内存,设置CS:IP指向程序的入口,但Debug并不放弃对CPU的控制,这样,我们就可以使用Debug的相关命令来单步执行程序,查看每一条指令的执行结果。

程序被装入内存的什么地方?我们如何得知?

这里,需要讲解一下在DOS系统中.EXE文件中的程序的加载过程。图4.20

在DOS中用"Debug 1.exe"运行Debug对1.exe进行跟踪时,程序加载的顺序是:command加载Debug,Debug加载1.exe。返回的顺序是:从1.exe中的程序返回到Debug,从Debug返回到command。

实验 3 编程,编译,连接,跟踪

PSP的内容:共256个字节

PSP以后的内容才是程序的真正内容

 

为啥CS:IP和DS里的内容一样?

 见图4.20

在该内存区的段地址存入ds中,初始化其他相关寄存器后,设置CS:IP指向程序的入口!!

猜你喜欢

转载自www.cnblogs.com/JasonPeng1/p/12116498.html