一、实验目的
1. 理解并掌握汇编源程序组成与结构
2. 掌握汇编语言源程序编写→汇编→链接→调试的工具和方法
3. 理解汇编源程序中地址表示、段寄存器的用法
4. 理解和掌握寄存器间接寻址方式[bx]
5. 通过汇编指令loop的使用理解编程语言中循环的本质
二、实验准备
1. 学习/复习第5章使用[bx]和loop实现循环的编程应用示例(教材5.5节,5.8节)
2. 复习第3章「栈」的知识
3. 结合第4章课件,复习完整汇编源程序编写→汇编→连接→运行→调试的方法
4. 复习8086汇编中内存单元地址的表示,以及段寄存器DS, SS, ES, CS的用途
三、实验内容
1. 实验任务1
使用任意一款文本编辑器,编写8086汇编源程序ex1.asm。源代码如下:
;ex1.asm assume cs:code code 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 end
使用masm、link对ex1.asm进行汇编、链接,得到可执行文件ex1.exe,运行并观察结果。
masm、link对ex1.asm进行汇编、链接得到ex1.obj,ex1.exe文件:
使用debug加载可执行文件ex1.exe后,使用d命令查看程序段前缀PSP所占的256个字节。
结合可执行文件中寄存器CX的值,使用u命令对ex1.exe进行精确反汇编:
使用g命令执行到程序退出执行之前(即源码文件中line16之前),观察结果。
单步执行的结果:
从上面可知进行写内存操作后,但是却没有改变内存使之形成0 01 02..的形式。
因为dosbox虚拟机的显示窗口对应显存中的一块区域,由b800:0 开始是所谓文字模式的 [显存地址] 当你输入 e b810:0 1 2 3 2 1 实际上是在显存上放资料,大约在第一列 输入完按一下 [回车], 屏幕 [上卷] 一列,完来的资料已经被下一列(第2列上卷到第1)覆盖了。
需要在debug ex1.exe时先进行清屏cls操作,执行接下来的步骤时不可出现滚屏操作最好g命令执行。
2.实验任务2
使用8086汇编程序编写、汇编、链接、运行、调试方法,对ex2.asm进行汇编、链接、运行
使用任意一款文本编辑器,编写8086汇编源程序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
使用masm、link对ex2.asm进行汇编、链接,得到可执行文件ex2.exe,运行并观察结果。
使用debug工具对可执行文件进行调试、用u指令进行反编译:
t命令单步执行:
中间没有出现特定符号的显示,因为随着内容的增多,页面滚动,显存地址b810:0~f 所对应的显示页面上内容的变化,该段地址中存储的数据也发生变化。
把ex2.asm中 mov cx, 4 改成 mov cx, 8 ,保存后重新汇编、链接、运行并观察结果。
使用masm、link对ex2.asm进行汇编、链接,得到可执行文件ex2.exe,运行并观察结果。
使用debug工具对程序进行调试。
结合可执行文件中寄存器CX的值,使用u命令对ex2.exe进行精确反汇编
g命令直接调试结果:
灵活使用t命令、p命令、g命令,对ex2.exe进行调试。(不一定要单步,有些地方可以用g命令,一次执行多行汇编指令)
注意:单步调试时,对于循环指令loop, 中断指令int,使用t命令和p命令单步调试的区别,t命令调试指令loop,中断指令int。p命令调试指令loop和中断指令int
结合上述实验和观察,分析、对比ex2.asm和ex1.asm,它们实现的是否是相同的功能和效?
观察可执行文件ex1.exe和ex2.exe的运行结果。ex1.asm是通过mov指令改
写地址b810:0~f 中的内容,ex2.asm通过循环来改写内存数据。
3.实验任务3
要求:把填充的字数据,从0237H 改成0239H,再次保存后,汇编、链接、运行,观察结果。
把填充的字数据,从0237H 改成0437H,再次保存后,汇编、链接、运行,观察结果。
猜测并分析,这个字数据中高位字节里存放的是什么信息,低位字节里存放的是什么信息。
执行恶行.exe文件,执行结果如图:
修改程序中的数据:0237H 改成0239H,再次保存后,汇编、链接、运行,运行结果如图:
修改程序中的数据:0237H 改成0437H,再次保存后,汇编、链接、运行,运行结果如图:
使用debug调试产看写入的数据,如图:
修改程序中的数据:0237H 改成0239H,再次保存后,汇编、链接、运行,运行结果如图:
修改程序中的数据:0237H 改成0437H,再次保存后,汇编、链接、运行,运行结果如图:
结论:0237H;运行结果:7777777777777777(绿色)
0239H;运行结果:9999999999999999(绿色)
0437H;运行结果:7777777777777777(红色)
0237H 0437H低地址(37H)中内容相同,高地址不同,结果都为字符串7,但是颜色不同
0237H 0239H低地址中内容不同,高地址相同(02),结果为颜色相同,字符串不同
可知高地址存放的数据对应颜色对应的十六进制数,低地址存放的数据对应显示的字符的十六进制数且这个数字对应ASCii码值。
4.实验任务4
要求:编写完整汇编源程序,实现向内存0:200~0:23F依次传送数据0~63(3FH)。
汇编、连接接无误后,灵活使用debug的t命令、g命令、p命令调试,用d命令查看0:200~0:23F,确认是否将0~63传送至此段内存区域。
使用masm进行编译,执行结果如图:
使用link进行连接,执行结果如图:
使用debug工具对可执行文件进行调试:
使用debug指令调试ex4.exe文件、在执行后查看地址200~23f 中的的数据,执行结果如图:
g p 命令调试:
用d命令查看0:200~0:23F,可知确实将0~3F传送至此段内存区域。
5.实验任务5
mov ax,cs cs指向程序存储的地址
mov cx,1c 一次只复制一个字节,需要循环整个程序的长度的数值次
使用masm和link对程序进行编译,连接,执行结果如图:
使用debug工具对ex5.exe进行调试:
g直接执行到指定位置命令和t单步执行:
使用p指令执行循环,执行后查看目标地址的数据和目标地址反汇编的指令代码:
数据被正确的复制到目的地址段对目标地址的数据反汇编后是所复制的指令内容。
四、实验总结
cx寄存器中一般用来存放整个程序的长度 单位是字节。
在loop指令的循环中 通过指定cx寄存器的值来确定循环的次数 每次循环结束后cx的值会自动减1。
文本编辑器编写程序时程序中的十六进制数需要带上h,否则再执行过程中会被当成十进制数。但是在debug内部写入时不用,因为debug默认数据是16进制的。
使用内存单元时不能直接使用“[偏移量]“的形式,可以通过寄存器来传递偏移量:[寄存器]或者在内存单元前面加上段地址寄存器。
debug命令调试时需要带上文件后缀名,否则执行报错 编译连接时可以不带