实践
在前面,我们知道了一些汇编语言的基本知识,接下来我们将学习如何用伪指令来编写汇编程序
。
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
要想运行该程序,我们得用编辑器(notepad之类)将它的后缀名改成asm,然后用masm(汇编编译器)
进行编译,生成包含机器代码的obj文件,如下所示:
在编译生成obj文件后,我们需要对目标文件进行连接,从而得到可执行文件,过程如下:
在这里我们用link
来对我们的obj文件进行了连接,并生成了demo1.exe
这个可执行文件,接下来我们就可以执行它了(当然,16位环境下的应用程序在64位下是不能使用的)。所以我们照书上的来,用debug来调试它:
在这里我们一般使用T命令来进行单步执行,这样我们能清楚地看到当前所有寄存器的状态。要注意的一点就是,在它的指令跳到int 21H时,我们需要用p来执行它(它是一个中断),不用p执行会产生未定义行为,程序会跳转到未知的地方,如下:
如果用p来执行int 21,结果会是这样的:
它就显示程序正常结束了。
浅析
在上面的程序中,我们用assume cs:codesg来给我们的cpu指明了cs(代码段基址寄存器)的值,它表示我们的代码从codesg这个段开始执行。
为了表示一个段,程序使用了【段名称 segment】来定义一个段,codesg会被内化成这个段在内存中的地址,所以assume才能准确地去预定义cs的值,段的结束需要使用【段名称 ends】来标识。
关于【mov 4c00H 和 int 21】,它们大致的作用就是保护当前现场(cs:ip等寄存器的值),避免在使用中断后程序跳转到莫名其妙的地方(写上就对了,不然会报错)。
end用来标记整个程序的结束。