实验2 汇编源程序编写与汇编、调试
一、实验目的
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的用途。
三、实验内容
为了偷懒省去排版的精力,实验内容请详见实验二实验指导pdf文件。
四、实验结论
1. 实验任务1
此部分书写内容:
ex1.asm源代码
1 ;ex1.asm 2 assume cs:code 3 code segment 4 mov ax, 0b810h 5 mov ds, ax 6 mov byte ptr ds:[0], 1 7 mov byte ptr ds:[1], 1 8 mov byte ptr ds:[2], 2 9 mov byte ptr ds:[3], 2 10 mov byte ptr ds:[4], 3 11 mov byte ptr ds:[5], 3 12 mov byte ptr ds:[6], 4 13 mov byte ptr ds:[7], 4 14 mov ah, 4ch 15 int 21h 16 code ends 17 end
使用masm、link工具汇编、链接的命令行及运行结果截图
汇编
链接
运行和运行结果
给出使用debug调试的截图
可执行文件加载后寄存器CX的值
使用u命令精确反汇编截图
查看PSP的命令及截图
使用g命令执行到line16退出执行之前
查看相应写入的内存单元
2. 实验任务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
使用masm、link工具汇编、链接的命令行及运行结果截图
可执行文件加载后寄存器CX的值
使用u命令精确反汇编
灵活使用t命令/p命令、g命令,对ex2.exe进行调试的截图
可以看到在循环执行原汇编代码中 s: 到 loop 之间的指令。每次循环CX值自减,直到为0退出循环。
直接运行ex2.exe显示结果:
实验任务2小结:
ex1和ex2实现效果相同,都是向现存中写入相应数据,在屏幕上显示图形。只是ex1由程序员手动编写一条一条实现重复相同的指令,而ex2使用loop自动执行重复的数条指令。
3. 实验任务3
ex3源代码
; ex3.asm assume cs:code code segment mov ax, 0b800h mov ds, ax mov bx, 07B8h mov ax, 0237h mov cx, 0010h s: mov [bx], ax add bx, 0002h loop s mov ah, 4ch int 21h code ends end
存疑:为什么第一次给ax赋值数据需要加上0(0b800h而非b800h),否则汇编时会有severe error?
课本P104:在汇编程序中,数据不能以字母开头
ex3运行结果截图
0237H在虚拟机屏幕出现一排绿色数字7
![]()
把填充的字数据,从0237H 改成0239H,再次保存后,汇编、链接、运行,观察结果。
![]()
把填充的字数据,从0237H 改成0437H,再次保存后,汇编、链接、运行,观察结果。
猜测并分析,这个字数据中高位字节里存放的是什么信息,低位字节里存放的是什么信息:
由ex3结果推测数据中高位存放显示颜色,低位存放显示字符值。
4. 实验任务4
源程序:
; ex4.asm assume cs:code code segment mov ax, 0000h mov ds, ax mov dx, 0200h mov cx, 0040h s: mov [dx], ax add dx, 0001h add ax, 0001h loop s mov ah, 4ch int 21h code ends end
注意这里地址偏移从0到3f,总共有64次循环,cx赋值为40h而非3fh。ex4实验内容时以字节(byte)为单位,向内存中存放数据,而寄存器ax长度为一个字,即两个字节。结果尝试这里程序使用al进行迭代自增得到的效果相同。
由于小端法存放低位数据存在内存地址低位,高位数据存在内存地址高位,且低位地址作为字的地址,因此使用长度为两个字节的寄存器为容器向内存存放字时,高位(本实验中为00)被存放到目标地址字节后面一个字节中,在下一次存放时,正好被低位数据覆盖,因此使用ax也能实现预计效果。
汇编、链接无误:
使用debug的t命令、g命令、p命令调试:
略,直接一步-g命令执行完了。
用d命令查看0:200~0:23F,确认是否将0~63传送至此段内存区域:
5. 实验任务5
课本填空后的代码:
; ex5.asm assume cs:code code segment mov ax, cs mov ds, ax mov ax, 0020h mov es, ax mov bx, 0 mov cx, 0015h s: mov al, [ax] mov es:[bx], al inc bx loop s mov ax,4c00h int 21h code ends end
查看复制目标地址,为了更加清晰,反汇编相应内存空间存放的指令
程序思路:经过初次阅读可以看出,es(extra segment)用于存放目标位置段地址。ds是复制源的地址,程序开始段地址由cs给出,所以通过ax将cs值赋给ds。值得注意的是,inc指令没有特殊说明自增量为1,即这个程序逐字节复制内容,所以使用al存放1字节大小的数据。遇到困难的地方是s上方cx的填写,即循环次数的控制,起初尝试将ip的值赋给cx,但是ip不可被访问,汇编时报错。之后尝试了将程序长cx赋值给cx,出于不知道的原因,在复制完后汇编程序会陷入死循环。找到两种处理方式,一是基于反汇编看出需要复制的指令长度,人为赋值0015h给cx;第二种使用offset a,即a的偏移地址赋给cx。
6. 实验任务6
第一步:在vi编辑器中编写汇编程序
第二步:放弃
五、实验总结
1. 本次试验使用dosbox完成,使用masm等工具之前需要先把他们所在相应的路径作为磁盘mount到虚拟机上,即可使用edit编辑,masm汇编和link链接。
2. s:一行开始前给cx赋值是为了控制loop的次数,像实验4中需要目标地址偏移从0到3f,总共有64次循环,cx赋值为40h而非3fh。
3. 在汇编程序中,数据不能以字母开头,如果数据最高位是字母,需要在前面加上0。