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

四、实验结论

任务一:

用debug将一段程序段写入内存,逐条执行,根据情况填空

1.使用e命令修改要求写入的内存单元,并用d命令查看写入情况

  成功向内存单元中写入数据

2.使用a命令输入任务给出的汇编指令

成功写入汇编指令

3.使用t命令分步调试程序

由于cs:ip初始状态下已经为我们所需执行汇编指令的地址,所以不需要进行cs:ip的改动

 分步调试如下

①查看寄存器初始值

②开始分步调试

 ③对于调试过程中几个寄存器变化的表格

  汇编指令  ax=  bx=  ss=  sp=
1 mov ax,0021  0021  0000  073F  0100
2 mov ds,ax  0021  0000  073F  0100
3 mov ax,2200  2200  0000  073F  0100
4 mov ss,ax  2200  0000  2200  0100
5 mov sp,0100  2200  0000  2200  0100
6 mov ax,[0]  3130  0000  2200  0100
7 add ax,[2]  6462  0000  2200  0100
8 mov bx,[4]  6462  3534  2200  0100 
9 add bx,[6]   6462  6C6A  2200  0100
10 push ax  6462  6C6A  2200  00FE
11 push bx  6462  6C6A  2200  00FC
12 pop ax   6C6A  6C6A  2200  00FE
13 pop bx  6C6A  6462  2200  0100
14 push [4]   6C6A  6462  2200  00FE
15 push [6]   6C6A  6462  2200  00FC

4.总结:

通过表格可以看出

1--5步是对于内存空间地址的配置及栈的空间分配

6--9步是内存和寄存器之间的数据传输

10--15步是寄存器和栈之间的数据传输(栈自身内存单元的修改,入栈出栈操作)

结果与理论分析结果一致

任务二:

按照要求进行操作,思考2000:0~2000:f中内容变化的原因

1.用a命令输入汇编指令,用e命令修改2000:0~2000:f的值,用d命令进行查看修改后的内存单元值

 

可以看到,我们已经成功将2000:0~2000:f的值修改为了0.

2.进行两步编译后查看内存单元值是否发生改变

从这里我们可以看到,内存单元的值已经发生了改变,这是为什么呢?

我们既没有对内存单元进行赋值操作,同样也没有把栈的头指针指向该位置(栈的头指针此时指向2000:0010)。那么,是什么使得内存单元的值发生了改变呢?

 下面我们来逐步分析

执行第一步的时候

内存单元没有发生变化,第一步是对ax赋值,是影响不到内存单元的

下面进行第二次调试(对ss:sp进行赋值)

我们发现,内存单元值发生了改变!这一步是用来给栈分配内存空间的步骤,由此看来,内存空间的改变应该是和栈内存空间的分配有关

 栈操作(入栈丶出栈)的过程中,只有sp变化,我们知道,栈的内存空间大小为16字节的倍数,栈顶的变化范围为0~10H

3.思考

①初始栈顶为2000:10,栈底为2000:10

mov sp,10的含义是确定了栈顶的位置,栈顶的地址为2000:10

②为何会发生内存单元的改变?

由2中的分析,我认为是系统分配这一段空间作为栈空间时,使得存放栈的内存单元发生了改变,内存单元改变的内容似乎与cs和ip等寄存器内容有关,似乎是暂时保存了此类信息??(只能推测到这里了)

五、总结与体会

1.对于“mov sp,10”汇编指令的执行,课本p73给出了一定的解释,要想彻底了解其中的道理还要等到后面课程学习了“中断机制”才能明白

2.对于栈空间的具体分配有些疑惑,比如为什么栈空间的分配会影响到内存单元数据的变化?在分配栈空间时,我们只是定义了栈空间的栈顶位置(ss:sp),栈空间的大小我们并没有明确定义,那么,cpu是如何明白我们划分了多大的栈空间呢?cpu又是如何把普通的内存空间和栈空间分隔的呢?或许这些问题等我对汇编语言更加深入学习之后,能够得到解答。

 

猜你喜欢

转载自www.cnblogs.com/xihongqing/p/9838781.html