4.1一个源程序从编写到执行的过程
第一步:编写汇编源程序;第二步:对源程序进行编译和连接:编译器进行编译,生成目标文件,连接器对目标文件进行连接,生成可执行文件;第三步:执行可执行文件。
1.伪指令
汇编语言源程序中有两种指令:一种是汇编指令,一种是伪指令。汇编指令对应有机器码,可以被编译为机器指令;而伪指令是由编译器来执行的指令,是辅助编译工作的指令,并不转化成机器码,更不会被执行。
(1)比如:segment和ends是一对成对使用的伪指令,使用格式为:
段名 segment
:
段名 ends
一个有意义的汇编程序中至少有一个段,这个段用来存放代码。
(2)end
end是一个汇编程序的结束标记,如果程序写完了,必须在结尾处加上伪指令end。否则,编译器在编译程序时,无法知道程序在何处结束。注意,不要搞混了end和ends,ends和segment是成对使用的。而ends可以理解为 end segment。
(3)assume
假设某一段寄存器和程序中对某一个segment ends定义对段相关联。 例如 assume cs:codesg 将cs 和codeseg对地址关联起来。
2. 源程序中的“程序” 程序指最终由计算机执行,处理的指令或数据 源程序就是包含汇编指令和伪指令代码的文件。 3. 标号 例如codesg 一个标号指代一个地址。 4. 程序的结构 源程序由一些段构成。段中存放代码,数据,或将某个段当作栈空间。 abc segment mov ax, 2 add ax, ax add ax, ax abc ends
程序返回:一个程序要被执行,首先要被加载到内存,然后将CPU控制权交给该程序。比如对于单任务操作系统DOS下,若P1正在执行,要执行P2的话,则P1先要将P2加载到内存,将CPU控制权交给P2,然后P2开始运行,P1暂停。当P2运行结束后,需要将CPU控制权交还给P1,这个交还称之为“程序返回”。汇编指令里的“mov ax,4c00H/int 21H"实现的功能就是程序返回。
与结束相关的指令:
目的 相关指令 指令性质 指令执行者
通知编译器一个段结束 段名 ends 伪指令 编译时编译器执行
通知编译器程序结束 end 伪指令 编译时编译器执行
程序返回 mov ax,4c00H int 21h 汇编指令 执行时由CPU执行
通过debug可对程序进行单步跟踪,程序加载进入内存后,cx寄存器中存放的是该程序的长度。程序的第一条指令地址即在CS:IP。
编译 常见的两类错误:(1)SevereErrors(2)找不到所给出的源程序文件 在编译的过程中最多可以得到3个输出的文件:.obj、.lst、.crf,只有.obj是最终要得到的结果。 连接 库文件里面包含了一些可以调用的子程序,如果程序调用了某一个库文件中的子程序就需要在连接的时候将这个库文件和需要的目标文件连接到一起,生成可执行文件。 没有栈段只是一个警告错误,可以忽略。 连接的作用: (1)源程序很大的时候可以把它分为多个源程序文件来编译,每个源程序编译成为目标文件后,再用连接程序将他们连接到一起,生成一个可执行文件。 (2)若程序调用了某个库文件中的子程序,可通过连接的方式把他们连接到一起。 (3)有时目标文件中的有些内容还不能直接用来生成可执行文件,连接程序将这些内容处理为最终的可执行信息。 可执行文件中的程序装入内存并运行的原理 .exe的执行过程: (1)在dos中执行.exe时正在运行的程序是command,将程序加载入内存。 (2)command设置CPU的CS:IP指向程序的第一条指令(程序的入口),从而使程序得以运行。 (3)程序运行结束后,返回到command,cpu继续运行command。 汇编程序从写出到执行的过程: 编程→编译→连接→加载→内存中的程序→运行 程序执行过程的跟踪(Debug) 使用Debug观察程序的运行的原因:在DOS中运行一个程序的时候,我们不能逐条指令的看到程序的执行过程,因为command程序加载和设置CS:IP的操作是连续的,而当CS:IP一指向程序的入口,command就放弃了对CPU的控制权,CPU立即开始运行程序直至程序结束。而Debug并不放弃对CPU的控制。 程序加载后ds中存放着程序所在内存区的段地址,程序所在的内存区的地址为ds:0 这个内存区的前256字节中存放的是PSP,dos用来和程序进行通信,从256字节处向后的空间存放的是程序。 程序的物理地址=ds+10:0