汇编语言 —— 第一个完整的程序


一个汇编语言程序从写出到最终执行的简要过程如下:

  1. 编写汇编源程序,生成源程序文件
  2. 对源程序进行编译连接,生成可执行文件
  3. 在操作系统中,执行可执行文件中的程序
汇编语言程序从写出到执行的过程
汇编语言程序从写出到执行的过程

一段简单的汇编语言源程序:

text

assume cs:codesg        ; 将用作代码段的段 codesg 和 CPU 中的段寄存器 cs 联系起来

codesg segment          ; 定义一个段,段的名称为 “codesg”,这个段从此开始
    mov ax, 0123H
    mov bx, 0456H
    add ax, bx
    add ax, ax

    mov ax, 4c00H       ; 程序返回
    int 21H
codesg ends             ; 名称为 “codesg” 的段到此结束

end

在汇编语言源程序中,包含两种指令,一种是汇编指令,一种是伪指令。

伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作。

segment 和 ends 是一对成对使用的伪指令。功能是定义一个段,segment 说明一个段开始,ends 说明一个段结束。

一个汇编程序是由多个段组成的,这些段被用来存放代码、 数据或当作栈空问来使用。一个有意义的汇编程序中至少要有一个段,这个段用来存放代码。

end 是一个汇编程序的结束标记,编译器在编译汇编程序的过程中,如果碰到了伪指令 end,就结束对源程序的编译。

编译程序可以将段寄存器和某一个具体的段相联系。

使用 assume 指令可以一段寄存器和程序中的某一个用 segment..ends 定义的段相关联。

源程序中最终由计算机执行、处理的指令或数据,称为程序。程序最先以汇编指令的形式存在源程序中,经编译、 连接后转变为机器码,存储在可执行文件中。

汇编语言程序从写出到执行的过程
源程序经过编译连接之后称为机器吗

汇编源程序中,除了汇编指令和伪指令外,还有一些标号,比如 “codesg”。一个标号指代了一个地址。

“codesg” 这个标号是代码段的名称,这个段的名称最终将被编译、连接程序处理为一个段的段地址。

一个程序 P2 在可执行文件中,则必须有一个正在运行的程序 P1,将 P2 从可执行文件中加载入内存后,将 CPU 的控制权交给 P2,P2 才能得以运行。P2 开始运行后,P1 暂停运行。

而当 P2 运行完毕后,应该将 CPU 的控制权交还给使它得以运行的程序 P1,此后, P1 继续运行。

一个程序结束后,将 CPU 的控制权交还给使它得以运行的程序,我们称这个过程为:程序返回。

总结一下与结束相关的指令:

目的 相关指令 指令性质 指令执行者
通知编译器一个段结束 段名 ends 伪 指 令 编译时,由编译器执行
通知编译器程序结束 end 伪 指 令 编译时,由编译器执行
程序返回 mov ax,4c00H int 21H 汇编指令 执行时,由 CPU 执行

编译的作用是通过源程序文件生成包含机器代码的目标文件(.obj 文件)。

连接的作用如下:

  1. 当源程序很大时,可以将它分为多个源程序文件来编译,每个源程序编译成为目标文件后,再用连接程序将它们连接到一起,生成一个可执行 文件;
  2. 程序中调用了某个库文件中的子程序,需要将这个库文件和该程序生成的目标文件连接到一起,生成一个可执行文件;
  3. 一个源程序编译后,得到了存有机器码的目标文件,目标文件中的有些内容还不能直接用来生成可执行文件,连接程序将这些内容处理为最终的可执行信息。所以,在只有一个源程序文件,而又不需要调用某个库中的子程序的情况下,也必须用连接程序对目标文件进行处理,生成可执行文件(.exe 文件)。

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

如果用户要执行一个程序,则输入该程序的可执行文件的名称,command 首先根据文件名找到可执行文件,然后将这个可执行文件中的程序加载入内存,设置 CS:IP 指向程序的入口。此后,command 暂停运行,CPU 运行程序。程序运行结束后,返回到 command 中,command 再次显示由当前盘符和当前路径组成的提示符,等待用户的输入。

Debug 将程序从可执行文件载入内存后,各个内存器的设置情况入下图:

程序加载后各个寄存器的设置情况
程序加载后各个寄存器的设置情况

DOS 系统中 EXE 文件中的程序的加载过程入下图:

EXE 文件中程序的加载过程
EXE 文件中程序的加载过程
  1. 程序从可执行文件加载入内存后,cx 中存放程序的长度;
  2. ds 中存放着程序所在内存区的段地址,这个内存区的偏移地址为 0,则程序所在的内存区的地址为 ds:0;
  3. 这个内存区的前 256 个字节中存放的是 PSP,DOS 用来和程序进行通信。从 256 字节处向后的空间存放的是程序;
  4. cs:ip 指向程序的第一条指令。

到此,完成了一个汇编程序从写出到执行的全部过程。

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