四、实验结论
任务一:
用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又是如何把普通的内存空间和栈空间分隔的呢?或许这些问题等我对汇编语言更加深入学习之后,能够得到解答。