实验2 用机器指令和汇编指令编程

四、实验结论

任务一:

(1)使用e命令将内存单元0021:0~0021:7连续8个字节数据改为30H, 31H, 32H, 33H,34H,35H,36H,37H。

 

(2)将从0021:0开始修改8个内存单元后利用d命令查看修改后内存中的值,查看内存中是否已经修改完成;

(3)利用debug,将以下程序段写入内存;

(4)在还没有执行程序之前,利用r命令查看当前CS:IP的指向;

从当前CS:IP的值来看,指向的就是我们所需要执行命令的开始位置,所以不需要修改CS:IP的值或者利用t命令的有参形式进行单部调试,可以直接利用t命令执行

(5)用t命令进行单部调试

执行 mov ax,0021;

执行 mov ds,ax;

执行 mov ax,2000;

执行 mov ss,ax;

Question:执行mov ax,[0]之前我们还有一条命令 mov sp,0100 但是在执行完mov ss,ax之后就显示下一条命令是mov ax,[0],但与此同时mov sp,0100这条指令是执行了的且SP寄存器中改变到了相对应的值。

通过查阅相关资料得知:当我在用t命令执行mov ss,ax之后,它的下一条指令mov sp,10也紧接着执行了。这个和“中断机制”有关,现在我们需要记住的是:Debug的t命令在执行修改SS的指令时,下一条指令也紧接着指令。对于mov ss,bx pop ss等指令都会发生上述的类似情况!

执行 mov ax,[0];

此时从0地址字单元中读取一个字3130H,所以此时AX寄存器中的值为3130H;

执行 add ax,[2];

先读取2地址单元中读取一个字3332H,然后将3332H与3130H相加的到6462H后送回寄存器AX;

执行 mov bx,[4];

此时从4地址字单元中读取一个字3534H,所以此时BX寄存器中的值为3534H;

执行 add bx,[6];

先读取6地址单元中读取一个字3736H,然后将3736H与3534H相加的到6C6AH后送回寄存器BX;

执行 push ax;

SP的值为00FE,SS的值为2200,所以此时栈结构修改的内存单元为:2200:00FE,内容为6462H;

执行 push bx;

SP的值为00FC,SS的值为2200,所以此时栈结构修改的内存单元为:2200:00FC,内容为6C6AH;

执行 pop ax;

SP的值为00FE,AX的值为6C6A;

执行 pop bx;

SP的值为0100,BX的值为6462;

执行 push [4];

SP的值为00FE,SS的值为2200,所以此时栈结构修改的内存单元为:2200:00FE,内容为6C6AH;

执行 push [6];

SP的值为00FC,SS的值为2200,所以此时栈结构修改的内存单元为:2200:00FC,内容为3736H;


任务二:

仔细观察图3.19中的实验过程,然后分析:为什么2000:0~2000:f中的内容会发生改变?

(1)首先按照题目要求完成指令

 

(2)查看未执行命令之前2000:0~2000:f中的内容,此时这段内存中的数据全都是0;

(3)查看当前个寄存器的值;

(4)利用t命令单部执行;

 

注:同样的在执行mov ss,ax之后就执行了mov sp,10这条命令;

通过查阅相关的资料得知:两条指令执行后靠近栈顶的10个字节中值立即有了变化,是对定义栈段时部分运行环境变量进行暂存,靠近栈顶的10个字节中的暂存数据分别是SS、IP、 CS 等的值。

mov sp,10 必须跟在 mov ss,ax 之后,这样的规定是便于控制栈段的大小,防止在有子程序调用时出错。(不太确定)

初始栈顶为2000:0010  初始栈底为2000:0010


五、总结与体会

存在的问题:

如上述命令mov sp,10必须跟在mov ss,ax之后,查阅资料得知这样的规定是便于控制栈段的大小,防止在有子程序调用时出错。但是具体是如何控制栈段的大小,我认为的是栈段的大小是由我们所定义的,然后实际在栈中读入数据的时候,需要我们自己注意是否超出了栈的范围。

Conclusion:

1、在进行单部调试程序的时候,最好把中间过程全部都输出,比如某一段的数据以及当前各个寄存器中存储的值,这样我们可以更加理解这些操作具体在做什么,在完成什么任务。

2、在调试的时候根据自己的理解先猜测下一步哪些内容会发生改变,然后再将执行结果输出,然后将两个结果进行比对。

原文地址:https://www.cnblogs.com/Sun-Yiwen-blog/p/9832393.html