汇编语言(王爽)第四章

第四章

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

在这里插入图片描述

使用汇编语言编译程序对源程序进行编译,产生目标文件,再用连接程序对目标文件进行连接,生成可在操作系统中直接运行的可执行文件

可执行文件包括两部分内容

· 程序(从汇编指令翻译过来的机器码)和数据(源程序中定义的数据)

· 相关的描述信息(如程序占用的内存空间等)

操作系统根据可执行文件中的描述信息,将可执行文件中的机器码和数据加载入内存,并进行相关的初始化(如设置CS:IP等)并由CPU执行

4.2 源程序

assume cs:codesg

codesg segment

		mov ax,0123H
		mov bx.0456H
		add ax,bx
		add ax,ax
		
		mov ax.4c00H
		int 21H
		
codesg ends

end

在源程序中包含两个指令:汇编指令和伪指令,汇编指令最终被编译为机器指令,最终由CPU执行,伪指令无对应的机器指令,由编译器根据伪指令进行相关的编译工作

上述源程序有3种伪指令

1、XXX segment …… XXX ends,segment和ends的功能是定义一个段,前者说明段开始,后者说明段结束,XXX是一个名称用来标识一个段,一个汇编程序由多个段组成,这些段用来存放代码、数据甚至当作一个栈空间等,一个有意义的汇编程序至少有一个段用来存放代码,称为代码段

2、end是一个汇编程序的结束标记,编译器在编译时如果碰到了伪指令end,就结束对源程序的编译,若不加end,编译器无法知道程序在何处结束

3、assume的含义为假设,假设某一段寄存器和程序中的某一segment…ends定义的段相关联,以后编程时记得用assume将有特定用途的段和相关的段寄存器关联起来

我们将源程序文件中的所有内容称为源程序,而源程序中最终由计算机执行、处理的指令或数据称为程序

程序最先以汇编指令的形式存在,后转变为机器码(如下图)

在这里插入图片描述

源程序中还有一些标号,如“codesg”,指代了一个地址,比如codesg在segment前面,作为一个栈的名称,这个栈的名称最终将被编译、连接程序处理为一个段的段地址

个人理解,存疑(因为codesg段是代码段,所以这个段的段地址传给cs,这就是为什么这个段要和cs寄存器相关联)

在DOS(一个单任务操作系统)的基础上讨论程序返回,一个程序P2在可执行文件中,需要一个在运行的程序P1将其加载入内存,将CPU的控制权交给P2,使得P2开始运行,同时P1暂停运行,P2运行结束后将CPU控制权还给P1,P1继续运行,所以我们需要在程序的末尾添加返回的程序段来交还CPU 的控制权,即

mov ax,4c00H
int 21H

源程序在编译时发现的错误为语法错误,如assume写为aume,编译后运行时发生的错误为逻辑错误,如没有返回的程序段

4.3 编辑源程序

保存为.asm文件

4.4 编译

使用masm汇编编译器

在这里插入图片描述

[.ASM]提示我们默认文件扩展名为asm,若编写的源程序文件名为t1.asm,只需输入t1,若为t1.txt,则需要输入全名,输入t1后回车,要求输入编译后目标文件的名称,默认为t1.obj,所以回车,要求指定生成目标文件的目录,默认为当前地址,所以回车,之后继续两个回车使编译器不产生中间结果,最后两行显示没有警告错误和必须改正的错误

4.5 连接

使用link

在这里插入图片描述

默认可执行文件名称,回车

忽略中间结果,回车

Libraries提示输入库文件的名称,库文件里包含了一些可以调用的子程序,若程序中调用了某个库文件中的子程序,就需要将这个库文件和目标文件连接到一起,若没有直接回车

忽略最后一行”没有栈段“的警告,最后便生成t1.exe

连接的几个作用

1、当源程序很大时,可以将它分为多个源程序文件来编译,每个源程序编译成为目标文件后,再用连接程序连接到一起,形成可执行文件

2、程序中调用了某个库文件中的子程序,需要将这个库文件和该程序的目标文件连接到一起,生成一个可执行文件

3、一个源程序编译后得到目标文件,其中有些内容还不能直接用来生成可执行文件,需要连接程序将其处理为最终的可执行信息,所以连接这一步骤时必须的

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

masm t1;
link t1;

加分号后可忽略中间文件的生成

4.7 运行

在命令行中直接输入t1即可

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

任何通用的操作系统,都提供一个为shell的程序,操作人员使用这个程序来操作计算机系统进行工作,DOS中的command称为命令解释器,是DOS的shell,在屏幕上显示当前盘符和当前路径,如”c:\“用户可以输入cd、dir等命令,由command执行

要执行一个程序,就输入该程序的可执行文件的名称,command找到后将这个可执行文件中的程序载入内存,并设置CS:IP,然后command暂停运行,CPU运行程序,结束后command继续运行,commond就是之前提到的P1

所以在DOS中直接运行t1.exe时,是正在运行的command将t1.exe中的程序加载入内存,再由command设置CPU的CS:IP指向程序的第一条指令(即程序的入口),运行结束后返回到command,CPU继续运行command

在这里插入图片描述

4.9 程序执行过程的跟踪

可以使用Debug将程序载入内存,设置CS:IP,并用相关命令单步执行程序并查看每次执行后的结果

debug t1.exe	;注意不能省略.exe

输入后CS:IP就会指向程序的入口,cx存放程序的长度,如15个字节即为000FH

关于DOS加载.exe文件

在这里插入图片描述

先找到一段起始地址为SA:0000的容量足够的空闲内存区,这段内存的前256个字节作为数据区,称为程序段前缀(PSP),DOS利用PSP来和被加载程序进行通信,而程序被装入PSP之后的内存区中,为了更好得区分PSP和程序,将它们分在不同的段中(物理地址是连续的,但有不同的段地址)

因为256 = 100H,所以SA * 16 + 0 + 256 = (SA + 16) * 16 + 0,因此程序的段地址可表示为SA+10H,偏移地址为0

最后将该内存区的段地址存入ds,初始化其他相关寄存器后,设置CS:IP

假设t1.exe加载完后DS=129E:0,即PSP的地址为123E:0,那么程序的地址为12AE:0

单步执行至int 21指令时用P命令

这里由Debug将程序载入内存,所以运行结束后返回Debug,而Q命令退出Debug返回到command,所以完整的顺序为:

command加载Debug,再由Debug加载t1.exe,返回时从t1.exe返回到Debug再返回到command

发布了84 篇原创文章 · 获赞 7 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43569916/article/details/104402397