引言
- 现在我们将开始编写完整的汇编语言程序,用编译器将它们编译成可执行文件(如:*.exe文件),在操作系统中运行。
- 这一章,我们将编写第一个这样的程序。
4.1 一个源程序从写出到执行的过程
一个汇编语言程序从写出到最终执行的简要过程:
编写
使用文本编辑器(如:记事本、NotePad++、UltraEdit等),用汇编语言编写汇编源程序。
编译链接
使用汇编语言编译程序(MASM.EXE)对源程序文件中的源程序进行编译,产生目标文件;
再用链接程序(LINK.EXE)对目标文件进行链接,生成可在操作系统中直接运行的可执行文件。
可执行文件
可执行文件中包含两部分内容:
- 程序(从原程序中的汇编指令翻译过来的机器码)和数据(源程序中定义的数据)
- 相关的描述信息(比如:程序有多大、要占多少内存空间等)
执行可执行文件中的程序
操作系统依照可执行文件中的描述信息,将可执行文件中的机器码和数据加载入内存,并进行相关的初始化(比如:设置 CS:IP 指向第一条要执行的指令),然后由CPU执行程序。
4.2 源程序
1.asm
assume cs:abc abc segment mov ax, 2 add ax, ax add ax, ax mov ax, 4c00H int 21Habc endsend
4.3 编辑源程序
4.4 编译
masm 1.asm
编译1.asm生成1.obj目标文件。
4.5 链接
link 1.obj
链接1.obj目标文件生成1.exe可执行文件
4.6 以简化的方式进行编译和链接
编译和链接的作用是什么呢?
链接的作用有以下几个:
当源程序很大时,可以将它分为多个源程序文件来编译,每个源程序编译成为目标文件后,再用链接程序将它们链接到一起,生成一个可执行文件;
程序中调用了某个库文件中的子程序,需要将这个库文件和该程序生成的目标文件链接到一起,生成一个可执行文件。
注:目标文件(.obj);可执行文件(.exe)
一个源程序编译后,得到了存有机器码的目标文件,目标文件中的有些内容还不能直接用来生成可执行文件,链接程序将这些内容处理为最终的可执行信息。
所以,在只有一个源程序文件,而又不需要调用某个库中的子程序的情况下,也必须用链接程序对目标文件进行处理,生成可执行文件。
注意,对于链接的过程,可执行文件是我们要得到的最终结果。
强调!!
这里再次强调一下,我们学习汇编的主要目的,就是通过用汇编语言进行编程而深入地理解计算机底层的基本工作原理,达到可以随心所欲地控制计算机的目的。
4.7 1.exe的执行
1.exe
4.8 可执行文件中的程序装入内存并运行的原理
汇编程序从写出到执行的过程:
编程(edit) -> 1.asm -> 编译(masm) -> 1.obj -> 链接(link) -> 1.exe -> 加载(command) -> 内存中的程序 -> 运行(CPU)
编译器认为
end
后的标记(本例中的标记即为doctorX,标记自定义)就为程序的入口assume cs:codesgcodesg segmentdoctorX: mov ax, 0123H mov bx, 0456H add ax, bx add ax, ax mov ax, 4c00H int 21Hcodesg endsend doctorX
4.9 程序执行过程的跟踪
总结
程序加载后,ds中存放着程序所在内存区的段地址。这个内存区的偏移地址为0,则程序所在的内存区的地址为:ds:0
。这个内存区的前256个字节中存放的是PSP,PSP是dos用来和程序进行通信。从256字节处向后的空间存放的是程序。所以,我们从ds中可以得到PSP的段地址SA,PSP的偏移地址为0,则PSP的物理地址为SA * 16 + 0 。因为PSP占256(100H)字节,所以程序的物理地址是:
SA * 16 + 0 + 256 = SA * 16 + 16 * 16 = (SA + 16) * 16 + 0
可用段地址和偏移地址表示为:SA + 10:0
注:乘16可以通过将十六进制左移1位来实现。10:0 对应的物理地址 100H