在前面的章节中不仅搭建了dosbox汇编环境,同时还介绍了mov、add、sub、push、pop等汇编指令,也了解了CPU是怎么操控数据和运行指令的。但对于一个功能来说,是需要不同的指令组合才能实现的,同时对于汇编源程序的运行,还需要对其编译生成包含机器码的目标文件,之后通过连接功能最终生成可执行文件。
对于最终生成的可执行文件,可以通过dosbox把可执行文件中的机器指令装载到内存中,同时运用R和T指令来查看相应寄存器和执行程序。
dosbox装载过程如下:
该分配的内存地址如下图所示:
现有以下功能:
计算寄存器AX和BX的和,结果存放AX中,并交换AX和BX的值:
assume cs:codesg
codesg segment
mov ax, 1000H
mov bx, 2000H
add ax, bx
mov ss, bx
mov sp, 0
push ax
push bx
pop ax
pop bx
mov ax, 4C00H
int 21H
codesg ends
end
通过以上汇编代码,可以分析汇编源程序的组成语法:
1-伪指令
伪指令没有对应的机器码,由编译器执行,在这段源程序中,出现了三种伪指令:
assume
...
codesg segment
...
codesg ends
...
end
segment 和 ends 是成对出现的伪指令,用来说明一个段的开始和结束。此处定义了一个代码指令段,段名称为 codesg 。
一个汇编程序可以由多个段组成,不同的段可以被用来存放代码、数据或栈空间来使用。一个有意义的汇编程序至少要有一个代码段。
assume 伪指令用来说明某一寄存器和某一定义的段的关联,在此处把段寄存器 cs 和代码段 codesg 联系起来。
end 伪指令表示一个汇编程序的结束。编译器在编译汇编程序的过程中,如果碰到了伪指令 end ,就会结束对源程序的编译。
2-汇编指令
汇编指令有对应的机器码,编译器会把汇编指令翻译为机器码以供CPU执行。
当执行一个程序后,需要把CPU的控制权交还给使它得以运行的程序,这个过程称为程序返回。在汇编中,可用以下指令实现程序返回:
mov ax, 4C00H
int 21H
3-标号
汇编程序中,除了汇编指令和伪指令外,还有一些标号,如 codesg 。这个标号作为段的名称,指代了一段指令的地址。
分析完汇编源程序后,下面需要对该源程序进行编译连接为可执行文件,使用dosbox装载到内存中并执行:
打开dosbox,执行masm.exe编译源程序,源程序可以在挂载目录的任意位置,后缀名也可以指定:
编译过程中,一般会有两类错误:
1.存在Severe Errors,此时需要检查源程序是否有书写和语法错误
2.找不到所给出的源程序文件。在此示例中,C:\asm\a.asm的实际路径是E:\dosbox\a\a.asm。此处路径若写错,就会出现此错误。
当编译成功时,若不指定目标文件的位置,会在挂载目录下生成一个目标文件:a.obj。
执行link.exe,连接目标文件生成可执行文件:
在连接时,如不指定可执行文件的生成位置,则默认在挂载目录下生成。
连接程序输出了一条没有栈段的警告,在此可以忽略这个警告。
dosbox装载运行:
对于生成的可执行文件,我们可以直接双击运行,但为了能看到每一步的执行情况,可以使用debug命令在dosbox装载程序,并通过R指令查看寄存器的值:
最下面显示当前CS:IP指向的指令:mov ax, 1000,通过T命令可以执行一条指令,并显示当前各个寄存器的值:
此时寄存器AX的值为:1000H
执行下一条指令: mov bx, 2000H,并查看寄存器的值:
此时寄存器BX的值为:2000H
执行下一条指令:add ax, bx,并查看寄存器的值:
此时寄存器AX的值为:3000H
执行下一条指令:mov ss, bx,并查看寄存器的值:
此时寄存器SS的值为2000H,同时注意到下一条指令为 PUSH AX ,并不是 MOV SP, 0 ,此处涉及到中断机制,先不做过多说明。
执行接下来的指令,一直到程序返回前,并查看寄存器的值:
此时AX=2000H,BX=3000H,已顺利完成AX和BX的数据交换,然后执行完剩余的指令即可。
目录
上一章
下一章