实验 汇编程序编写与汇编调试
一、实验任务1
ex1.asm源代码如下:
;ex1.asm assume cs:code ;将有特定用途的段和相关的段寄存器关联起来:将code当做代码段来用,将code和cs关联起来 code segment ;段名 segment . mov ax,0b810h mov ds,ax mov byte ptr ds:[0],1 mov byte ptr ds:[1],1 mov byte ptr ds:[2],2 mov byte ptr ds:[3],2 mov byte ptr ds:[4],3 mov byte ptr ds:[5],3 mov byte ptr ds:[6],4 mov byte ptr ds:[7],4 mov ah,4ch int 21h code ends ;段名 ends end ;汇编程序的结束标记
上图中有注释行的代码为伪指令;
1)创建代码文件,并写入代码:
注意点:十六进制数的表示;
edit ex1.asm
结果:产生了一个存储源程序的文本文件;
源程序:包括伪指令(由编译器来处理)和指令(有对应的机器码指令,可被编译为机器指令);
程序:最终由计算机执行、处理的指令或数据,现阶段以汇编指令形式存储在源程序中。
2)对源程序进行编译:(以分号结尾跳过中间文件的生成过程)
amsm ex1.asm;
结果:得到了目标文件ex1.obj
3)连接:
link ex1.obj;
结果:程序经过编译、连接转变为机器码,存储在可执行文件ex1.exe中。
4)执行:直接执行ex1
ex1
执行结果有图案显示在屏幕上,猜测是向显存写入了内容;下面进行跟踪调试:
5)程序执行过程的跟踪:
debug ex1.exe
①利用反汇编指令查看汇编程序代码:
已知寄存器CX中存储的是程序的长度,一共31字节;
代码段的起始段地址存储在寄存器CS中,偏移量为IP的值:
用以下命令进行精确反汇编:(指定偏移地址,段地址使用默认的CS)
u 0 30
或
u 0 L31
与写入的代码进行比较:内容一致;
②查看程序段前缀PSP:
DS中存储程序所在内存区的段地址;
观察上图:CS:IP指向第一条指令,而CS = DS + 10H;可相互印证;
③使用g命令执行:
g cs:2d
运行结果与直接运行结果一致;
由实验可印证:g 段地址:偏移地址 指令是指定程序执行到所给定的地址之前;
二、实验任务2
ex2.asm源代码如下:
;ex2.asm assume cs:code code segment mov ax,0b810h mov ds,ax mov bx,0 mov ax,101H mov cx,4 s: mov [bx],ax add bx,2 add ax,101H loop s mov ah,4ch int 21h code ends end
1)同实验任务一编译、连接并执行:
代码依次为:
masm ex2.asm; link ex2.obj; ex2
运行结果:与实验任务一结果相同
2)跟踪调试:
①CX=001C
精确反汇编,指令如下:
u 0 1b
或
u 0 L1c
与源代码对比可知:loop:标号: loop s –> loop 000E
标号的本质为地址;
②用t / p / g命令执行:
mov ax,B810 mov DS, AX mov BX,0000
将数据段段地址设置为显存所在地址;BX寄存器置0:
设定寄存器AX = 0101;指定循环次数CX=0004 ;
mov AX,0101 mov CX,0004
MOV [BX],AX ADD BX,+02 ADD AX,0101 LOOP 000E
将0101赋给B810:0 1,BX –> BX + 2
AX = 0101 –> AX = 0202
在执行跳转指令之前,CX = (CX)- 1,判断CX不为0则跳转;
执行结果与之相符:
持续执行,中间步骤类似,略;
直到将AX=0404 –> B810:6 7 中后,CX=0001;
执行到loop 000E判定时:CX = CX – 1 = 0000 不再跳转,
实验结果如下,一致:
直接使用g命令,有输出显示:
③ex2.asm与ex1.asm对比分析:
实现了相同的功效,在具体实现上:
实验任务1中采用的是通过8次mov指令,将直接数移入指定内存单元;
实验任务2中采用[BX]和loop指令相结合,通过move [BX],AX改变指定内存单元内容;
对比之下,实验一中程序的长度为0031H ,实验二中程序的长度为001CH,程序长度明显减少。
内存单元信息包含 内存单元地址,内存单元长度(类型),[BX]:偏移地址在bx中,段地址默认在ds中,数据类型长度由具体指令中其他操作对象决定;
这样的特性可以使得代码段更为精简。
三、实验任务3
ex3.exe源代码如下:
;ex3.asm assume cs:code code segment mov ax,0b800h mov ds,ax mov bx,07b8h mov ax,0237h mov cx,10h s: mov [bx],ax add bx,2 loop s mov ah,4ch int 21h code ends end
运行结果如下:
改变代码如下:
mov ax,0239h ;mov ax,0237h
运行结果:
改变代码如下:
mov ax,0437h ;mov ax,0237h
运行结果:
实验结果:
0237 –> 0239 低位字节改变,图案改变;
0237 –> 0437 高位字节改变,颜色改变;
猜测分析:低字节数据控制图案,高字节数据控制颜色。
四、实验任务4
使用[bx] 和 loop指令实现向0:200~0:23f写入0~64:,源代码如下:
;ex4.asm assume cs:code code segment mov ax,0h mov ds,ax mov bx,200h mov ax,0000h mov cx,40h ;写入0~3f共40h个数据 s: mov [bx],al add bx,1 add al,01h loop s mov ah,4ch int 21h code ends end
①编译连接:
②运行,并查看运行前后内存情况:
;用到的指令如下 d 0:200 23f g 001b
目标数据已成功写入指定内存;
五、实验任务5
最终代码如下:
;ex5.asm assume cs:code code segment mov ax,cs mov ds,ax mov ax,0020h mov es,ax ;es保存目标内存段的段地址 mov bx,0 mov cx,23 s: mov al,[bx] mov es:[bx],al inc bx ;偏移地址内存单元每次+1 loop s mov ax,4c00h int 21h code ends end
1)填空分析:
①第一处填空:目标空 — 》 AX –》DS 也即填空要复制的内容的段地址,也即当前代码段的段地址;
通过 assume cs:code可知,已将代码段与cs关联起来;所以代码段的段地址保存在了cs中,第一个空处填 CS
②在原始代码文件中给CX赋一个随机值,如下图:确定要复制的目标代码段长度为:17H = 23
修改EX5.ASM文件,确定 mov cx,21;
2)编译连接修改后的文件:
3)跟踪运行:
程序执行前目标内存:
①DS确定被复制的目标代码的段地址:
②ES确定目标内存段地址:
确定循环次数CX=0017H
③一次循环:DS:0 –> ES:0
④执行完后后,查看目标内存:
反汇编结果也一致:
代码复制成功。