实验2 汇编源程序编写与汇编、调试
1. 实验任务1
此部分书写内容:
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工具汇编、链接的命令行及运行结果截图
汇编

链接

运行和运行结果


给出使用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。

浙公网安备 33010602011771号