一、实验结论:
1.实验任务2:PC机主板上的ROM中有一个生产时期,在内存FFF00H ~ FFFFFH的某几个单元中,请找到这个生产时
期,并试图修改它
在debug中,使用d命令查看生产日期:
使用e命令尝试修改(并查看修改后的结果):
发现该日期并未修改,因为此操作是修改只读存储器中的内容,是无法实现的,只读存储器在内存的地址为C0000~ FFFFFH。
2.实验任务3:在debug中,使用e命令,向内存单元填写数据
显示如左上角
在debug中,使用f命令,向内存单元批量填写数据,显示在编辑器底部一行:
自己尝试改变内存地址和存入的数据,结果如下(显示出现在编辑器左侧中部的位置):
3 .实验任务4:已知内存单元00201H ~ 00207H分别存放数据(如下图所示),00220H ~ 0022fH用作栈空间。
在debug环境中,按顺序录入以下内容,单步跟踪调试,观察寄存器和内存空间00200H~00207H,以
及,栈空间00220 ~ 0022fH内容变化情况。记录实验结果。回答问题,验证和你的理论分析结果是否一
致。
(1)填空
-a mov ax, 20 mov ds, ax mov ss, ax mov sp, 30 push [0] ; 执行后,寄存器(sp) = __002E__ push [2] ; 执行后,寄存器(sp) = __002C__ push [4] ; 执行后,寄存器(sp) = __002A__ push [6] ; 执行后,寄存器(sp) = _0028___ pop [6] ; 执行后,寄存器(sp) = _002A___ pop [4] ; 执行后,寄存器(sp) = __002C__ pop [2] ; 执行后,寄存器(sp) = __002E__ pop [0] ; 执行后,寄存器(sp) = __0030__
(2)问题1:题目要求是把00220H ~ 0022fH用作栈空间。指令 mov ss, ax 和 mov sp, 30 执行后,栈顶的逻辑地址和物理地址分别是?
sp逻辑地址:0030
物理地址:0022fH
(3)问题2:单步调试到汇编指令 push [6] 执行结束, pop [6] 执行之前,使用 d 20:20 2f 查看此时栈空间数据,给出实验截图。
(4)问题3:汇编指令 pop [0] 执行结束后, pop [0] 指令执行结束后,使用d命令 d 20:0 7 查看此
时数据空间内的数据是否有变化。给出实验截图。
(5)问题4:如果把最后四条指令改成截图中的顺序, pop [6] 指令执行结束后,使用d命令 d 20:0 7
查看此时数据空间内的数据是否有变化。给出实验截图
4.实验任务5:在debug环境中,实践以下内容:
(1)问题1:使用t命令单步执行 mov ss, ax 时,是单步执行完这一条指令就暂停了吗?后面的指令 mov sp, 30 是什么时候执行的?
观察debug操作,发现单步执行mov ss, ax后,mov sp, 30就执行了,可以看到sp已经等于0030了。
(2)问题2:根据汇编指令,前三条指令执行后,00220H ~ 0022fH被设置为栈空间。并且,初始时,已通过f命令将初始栈空间全部填充为0。观察单步调试时,栈空间00220H ~ 0022fH内存单元值的变化,特
别是图示中黄色下划线表示出的数据值(073F:0108)。根据实验观察,尝试思考和分析原因。
我继续往下运行下去,再查看-d 20:20 2f
出现以下改变:
则可推出,栈空间内内存单元可以存储下一条指令的位置,即CS和IP寄存器的值。
5.实验任务6:使用任何一款文本编辑器,编写8086汇编程序源码
assume cs:code code segment start: mov cx, 10 mov dl, '0' s: mov ah, 2 int 21h add dl, 1 loop s mov ah, 4ch int 21h code ends end start
使用masm、link,汇编、链接,得到可执行文件task5.exe。运行程序。结合程序运行结果,理解程序
功能。
masm、link命令在前(没有截到)
使用debug工具,调试task5.exe。根据第4章所学知识,任何可执行程序在执行时,都有一个引导程序
负责将其加载到内存,并将CPU控制权移交给它,也即将CS:IP指向可执行程序中第一条机器指令。在加
载可执行程序时,可执行前面512字节是程序段前缀PSP(Program Segment Prefix),用于记录程序一些
相关信息。
在debug中,使用d命令,查看task5.exe的程序段前缀,观察这256个字节的内容,验证前两个字节是
否是CD 20。
查看程序段前缀,前两个字节是CD 20:
6.实验任务7:下面程序的功能是,完成自身代码的自我复制:把 mov ax, 4c00h 之前的指令复制到内存0:200开始的连续的内存单元。补全程序,并在debug中调试验证,确认是否正确实现了复制要求。
assume cs:code code segment mov ax, _____ mov ds, ax mov ax, 0020h mov es, ax mov bx, 0 mov cx, _____ s: mov al, [bx] mov es:[bx], al inc bx loop s mov ax, 4c00h int 21h code ends end
可知是要将一定的代码段内容填入指定内存单元,ex(0020h):[bx]作为目标地址,则代码段地址作为源地址,我把第一个空填 cs;
先随便填一个cx,我先填0001h,在debug用u命令查看, mov ax, 4c00h指令停留在0017h,我有些不确定,决定尝试0015和0017;
0015h并没有在目的地址存储完整的代码,
0017则完整拷贝了,
最后补全后的代码为:
assume cs:code code segment mov ax, cs mov ds, ax mov ax, 0020h mov es, ax mov bx, 0 mov cx, 0017h s: mov al, [bx] mov es:[bx], al inc bx loop s mov ax, 4c00h int 21h code ends end
二、实验总结
1、字节是固定的单位,等于八个二进制位,而字是计算机进行数据处理和运算的单位,用字长来表示大小,字长为若干个字节,不同的机器字长可能不同,在8086CPU中字长为16位,即两个字节,8086的几个数据寄存器是16位寄存器,每一个 16 位寄存器就可以当做 2 个独立的 8 位寄存器来使用了,所以在8086系统中,既可以将一个字存入寄存器内,也可以将字节存入,而且可以指定实在16进制的高二位还是第二位,在显示的时候,而在机器读取的时候从低位开始读,字的地址是低位的地址,我总是忘记,导致操作就不熟练甚至出现错误。