程序的建立和运行
步骤:编写汇编程序—>对源程序进行编译连接—>执行可执行文件中的程序
可执行文件包含两部分内容:程序(从源程序中的汇编指令翻译过来的机器码)和数据(源程序中定义的数据)与相关描述信息(程序大小、占用多大空间等)。
操作系统依照可执行文件中的描述信息将可执行文件中的机器码和数据加载如内存,并进行相关的初始化(如:设置CS:IP),然后由CPU执行。
1. 源程序
a) 伪指令:汇编中包含两种指令,汇编指令和伪指令。汇编指令是有对应机器码的指令,可以被编译为机器指令,最终被CPU执行。伪指令没有对应的机器指令,最终不被CPU所执行,伪指令是由编译器来执行,编译器根据伪指令进行相关的编译工作。
b) Segment ends
一个汇编程序由多个段组成,这些段用来存放代码、数据或当做栈控件来使用。Segment和ends是一对指令,定义一个段,segment段开始,ends段结束。
c) End
End是一个汇编程序结束的标记,编译器在编译汇编程序的过程中若碰到了伪指令end,就结束对源程序的编译。所以在程序结束后要加上end,否则编译器不知道从何处结束编译。
d) Assume
该伪指令的含义为:假设;它假设某一段寄存器和程序中的某一个用segment…ends定义的段相关联。在需要的情况下,编译程序可以将段寄存器和某个具体的段相联系。记着用assume将特定用途的段和相关的段寄存器关联起来即可。
2. 程序的返回
Mov ax,4c00H
Int 21h
通过这两条指令可以将CPU的控制权归还给调用者。
3. 编辑源程序
可以使用任意的文本编辑源程序,只要最终将其保存为扩展名为asm文件即可。
4. 编译
a) 进入DOS方式,运行masm.exe
[.ASM]:表示将要编译的文件的默认扩展名为asm,若源文件不是asm扩展名则需要使用文件全名;
[.OBJ]:默认要输出的目标文件,可在后面输入想要输出的文件名;
[NUL.LST]:编译器提示输入列表文件的名称,这个文件是编译器将源程序编译为目标文件的过程中产生的中间结果,可以不让编译器产生此文件,直接按enter;
[NUL.CRF]:提示输入交叉引用文件的名称,这个文件同列表文件一样,是编译器将源程序编译为目标文件过程中产生的中间结果。
可以修改编译产生的文件存放路径,直接在[]后面加上需要保存的路径即可。
5. 连接
在对源程序进行编译得到目标文件后,需要对目标文件进行连接,从而得到可执行文件。
a) 进入DOS,运行link.exe
[.OBJ]:提示默认的文件扩展名是obj,若不是obj文件则需要输入全名,输入需要连接的文件名;
[.EXE]:提示默认生成的exe文件名,可输入自定义的名称。
[NUL.MAP]:连接程序提示输入映像文件的名称,这个文件是连接程序将目标文件连接为可执行文件过程中产生的中间结果,可以让连接程序不生成这个文件。
[.LIB]:提示输入库文件的名称,库文件中包含了一些可以调用的子程序,若程序中调用了某个库文件的子程序,就需要在连接的时候将这个库文件可目标文件连接到一起,生成可执行文件。
最后会警告未找到栈段,忽略此警告。
连接的作用:
i. 当源程序很大时,可将它分为多个源程序文件来编译,每个源程序编译成为目标文件后,再使用连接程序将它们连接到一起,生成一个可执行文件;
ii. 程序中嗲用了某个库文件中的子程序,需要将该库文件和目标文件连接到一起;
iii. 一个源程序编译后,得到了存有机器码的目标文件,目标文件中的有些内容还不能直接用来生成可执行文件,连接程序将这些内容处理为最终的可执行信息。所有在只有一个源程序文件,而又不需要调用某个库中的子程序的情况下,也必须用连接程序对目标文件进行处理。
6. 谁将可执行文件中的程序装在进入内存并是它运行?
操作系统是由多个功能模块组成的庞大、复杂的软件系统,任何通用的操作系统都提供一个称为shell(外壳)的程序,用户使用这个程序来操作计算机系统进行工作。
DOS中有个command.EXE程序,这个程序是DOS的shell。Command根据文件名找到文件并加载入内存中,设置CS:IP指向程序的入口,此后command暂停运行释放CPU控制权,CPU运行。程序运行结束后返回到Command中。