汇编语言-运行程序

汇编语言-一个程序

程序从写出到执行

源程序

这是一段简单的汇编源程序代码,在汇编语言源程序中,包含两种指令,种是汇编指令,种是伪指令。汇编指令是有对应的机器码的指令,可以被编译为机器指令,最终为CPU所执行。而伪指令没有对应的机器指令,最终不被CPU所执行。那么谁来执行伪指令呢?伪指令是由编译器来执行的指令,编译器根据伪指令来进行相关的编译工作。

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

如上面显示的代码,codesg segmentcodesg ends是一组成对使用的伪指令,他们定义了一个段codesg,分别对应着段的开始和结束。一个汇编程序是由多个段组成的,这些段被用来存放代码、数据或当作栈空间。

end是一个汇编程序的结束标记,编译器在编译汇编程序的过程中,如果碰到了伪指令end,就结束对源程序的编译。所以,在我们写程序的时候,如果程序写完了,要在结尾处加上伪指令end。否则,编译器在编译程序时,无法知道程序在何处结束。

assume这条伪指令的含义为假设”。它假设某一段寄存器和程序中的某一个用segment…ends定义的段相关联。通过assume说明这种关联,在需要的情况下,编译程序可以将段寄存器和某一个具体的段相联系。

通过指令汇编指令mov ax,4c00H 和int 21H,实现程序的返回功能,以8086CPU为例,开机后运行的command控制台,当程序运行时将控制权交与程序,程序运行结束后,又将控制权返回给控制台。关于上面的两条指令是如何实现将控制权返还给控制台,会在之后的章节详细介绍。

编译和链接源程序

当我们写好一个程序后,将其保存为file.asm 文件,通过masm编译器实现编译功能,编译器会根据代码编译出.obj 文件,之后再进行链接操作,使用命令link file.obj,即可实现链接功能生成.exe文件。

现在已是2021年,想要重新实现8086CPU不太现实的事情,这里提供几个可以代替的方法:

  1. emu8086
  2. DOSbox

对于第1种方法,他本身集成,无需控制指令,有完整的图形化界面。
对于第2种方法它是一个仿 DOS界面,具体操作可以转到enter link description here

执行程序

以dosbox如果只想执行程序,在链接出.exe文件后,直接输入文件名即可(无需exe后缀)。若想debug程序,需要debug file.exe(文件全名)。

在命令控制台去执行程序,首先它会将我们的目标程序从可执行文件加载到内存中,将CPU的控制权交给目标程序,该程序才可运行。程序运行结束后,又将控制权返还给当初使它运行的程序。

debug程序

如果我们运行一个程序,需要一个程序去调用另一个程序,并将控制权交给他,直到程序运行结束将控制全返还。很容易想到,若是在debug程序的过程中,控制前在程序手中,我们是无法控制程序的操作命令的,在debug的过程中,虽然我们在执行程序,但控制权仍然在command中。

debug后,可以看到,Debug将程序从可执行文件加载入内存后,cx中存放的是程序的长度。hello.exe中程序的机器码共有15个字节。则hello.exe加载后,cx中的内容为000FH。现在程序已从hello.exe中装入内存,接下来查看一下它的内容,可是我们查看哪里的内容呢?程序被装入内存的什么地方?我们如何得知?这里,需要讲解一下在DOS系统中EXE文件中的程序的加载过程。

那么,我们的程序被装入内存的什么地方?我们如何得知?
(1)程序加载后,ds中存放着程序所在内存区的段地址,这个内存区的偏移地址为0,则程序所在的内存区的地址为ds:0;
(2)这个内存区的前256个字节中存放的是PSP,DOS用来和程序进行通信。从256字节处向后的空间存放的是程序。
所以,从ds中可以得到PSP的段地址SA,PSP的偏移地址为0,则物理地址为SA x 16+0

因为PSP占256(100H)字节,所以程序的物理地址是:SA x 16+0+256,可用段地址和偏移地址表示为:SA+10H:0

INT21执行后,显示出”Programterminatednormally”,返回到Debug中。表示程序正常结束。(注意,要使用P命令执行INT21。需要注意的是,在DOS中运行程序时,是command将程序加载入内存,所以程序运行结束后返回到command中,而在这里是Debug将程序加载入内存,所以程序运行结束后要返回到Debug中。)

使用Q命令退出Debug,将返回到command中,因为Debug是由command加载运行的。在DOS中用”debug hello.exe”运行Debug对hello.exe进行跟踪时,程序加载的顺序是:command加载Debug,Debug加载hello.exe。返回的顺序是:从hello.exe中的程序返回到Debug,从Debug返回到command。