实验结论
1.实验任务2
①查看ROM生产日期,命令为:-d ffff:0 ff ,截图如下:
可以看到生产日期在FFFF0~FFFFF这个地址中,日期为01/01/92。
②尝试用e命令修改这个生产日期,截图如下:
发现这个生产日期无法随意修改,可以推断出地址FFFF0~FFFFF的内存单元为只读存储器,写入数据操作是无效的。
2.实验任务3
①使用e命令,向内存单元填写数据,命令为:-e b800:0 03 04 03 04 03 04 03 04 03 04 ,结果如下图:
②使用f命令,向内存单元批量填写数据,命令为:-f b800:0f00 0f9f 03 04 ,结果如下图:
③对b800:0进行数据修改,命令为-e b800:0 03 03 03 03 03 03 03 03 03 03 ,结果如下图:
发现内存数据修改成功,图案由红色变为蓝色。
3.实验任务4
在dos中输入下面命令:
-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
问题1:答:逻辑地址为:230H,物理地址为:0022fH。
问题2:答:push [6] 执行结束, pop [6] 执行之前,使用 d 20:20 2f 查看此 时栈空间数据,截图如下:
问题3:答:pop [0] 指令执行结束后,使用d命令 d 20:0 7 查看此时数据空间内的数据,截图如下:
可以发现数据空间内的数据没有变化。
问题4:答:把最后四条指令改成截图中的顺序, pop [6] 指令执行结束后,使用d命令 d 20:0 7 查看此时数据空间内的数据,截图如下:
可以发现随着最后出栈顺序的不同,数据空间内的数据发生了变化。
4.实验任务5
问题1:答:使用t命令单步执行 mov ss,ax 时,不是单步执行完这一条指令就暂停了。在用t命令执行 mov ss, ax 时,后面的下一条指令 mov sp, 30 紧跟着执行了。
从图中可以看出,执行完 mov ss,ax后一条待执行的指令跳到了 mov ax,2021,而sp由00FD变成了0030,而能将sp设为30的指令只有mov sp,30,由此得到在用t命令执行 mov ss, ax 时,后面的下一条指令 mov sp, 30 紧跟着执行了。
问题2:答:图中的073F对应cs寄存器内的值,0180对应ip寄存器内的值,继续执行接下来几条指令可以发现同一现象。因此可以推断出:栈空间内存单元值发生变化的原因是在用t指令执行命令时会产生中断,cpu为了保护现场,会先将IP、CS两个寄存器的值入栈。
5.实验任务6
程序源码为:
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 task6.asm; 对程序进行编译,如下图:
用命令 link task6.obj; 进行连接,如下图:
由于psp存放于内存区的前256个字节中,所以进入debug模式后用命令 d 075a:0 ff 来查看psp中的内容,如下图所示:
可以看到psp的前两个字节正是CD 20。
6.实验任务7
程序补全后代码为:
assume cs:code code segment mov ax, cs mov ds, ax mov ax, 0020h mov es, ax mov bx, 0 mov cx, 17h s: mov al, [bx] mov es:[bx], al inc bx loop s mov ax, 4c00h int 21h code ends end
第一个空填cs,原因是题中要求复制 mov ax, 4c00h 之前的指令,也就是从代码段开始到 mov ax, 4c00h 的所有指令,故将代码段起始地址cs赋给数据段。
第二个空填17h,原因是要完成复制必须要确定要复制的指令的字节数,也即循环次数cx,于是只要数出待复制指令所占的字节数即可。为了得到指令字节数,我先随便赋给cx一个值,然后编译连接后在debug中用u命令显示所有的命令,如下图,接着便可以数出待复制指令的字节数,数出来是23个字节,转换为16进制便是17h,因此将17h赋给cx。
对于第二个空我觉得也可以将这条指令改为 sub cx 5 ,因为cx也可以表示该程序的所有字节总数,故将cx减去不用被复制的指令的字节数就能得到需要被复制指令的字节数,不需要被复制的指令有mov ax,4c00h 和 int 21h ,占5个字节,所以应将cx-5,这样就没有必要一个个去数,更加简单。
在debug中调试,使用g命令将程序执行到 loop s 之后、 mov ax, 4c00h 之前,用 u0:200 216 反汇编命令查看,发现已经成功复制指令,如下图:
实验结论
通过本次实验,我收获了以下知识点:
(1)地址C0000~FFFFF的内存单元为只读存储器,写入数据操作是无效的。
(2)地址A0000~BFFFF为显存地址空间,向其中写入数据,这些数据会被输出带显示器上。
(3)栈底总是在地址较大的一侧,每入栈一次,sp对应减去入栈的字节数,每出栈一次,sp对应加上出栈的字节数,出栈顺序与入栈顺序相反。
(4)程序存放的内存区域的前256个字节用作程序前缀(PSP),用作dos和程序的通信。
在调试程序的过程中,我还有了以下几个发现:
(1)在用t指令执行命令时会产生中断,cpu为了保护现场,会先将IP、CS两个寄存器的值入栈。
(2)在执行了修改ss的mov指令后,后面的修改sp的mov指令会紧跟着一起执行,其原因我觉得可能是为了保护栈,控制栈段大小。
(3)mov命令用于寄存器之间传送数据时是占2个字节,用在寄存器和数据之间时占3个字节。