
实验任务
(1)使用Debug,将下面的程序段写入内存,逐条执行,根据指令执行后的实际运行情况填空。
书上实验内容:
1 | mov ax,ffff |
运行结果:
程序分析:
首先,我使用的是Mac 系统下 DOSBox 的debug 环境。
不同的系统运行结果是不是一样呢?有可能吧~ 主要考虑他的原理。
逐步分析:
首先,前两行代码将ds指向了FFFF段内存,也就是数据段是ffffH:00开始的内存单元了。
然后,建立一个栈结构,ss指向2200H段的内存,初始化栈顶指针是100H,ss:sp指向栈底后面第一个单元(目前栈结构是空);也就是说这个栈结构栈底后面第一个单元地址是2200:100H(物理地址:22100H)
1 | mov ax,[0] //ax=C0EA; |
1 | push ax //将ax=C0FC压入栈中;sp=sp-2=0100-2=00FE; |
对比实验:
1 | mov ax,2100 |
可以看出尽管修改了数据,但是基本的原理都还相同。
程序理解:
【1】创建了一个栈的结构,它的实质就是一段连续的内存空间,只不过访问内存的方式不像我们原来的CPU寻址方式,使用push和pop访问。
【2】栈使用的实际空间是随着sp指针的指向而发生改变的,它和最大使用空间是有区别的。栈空,sp=100H,栈满,sp=0。
【3】栈操作的对象基本单位是字单元(2个字节),对应的内存就是2个内存单元。
(2) 仔细观察图中的实验过程,然后分析:为什么2000:0~2000:f中的内容会发生改变。
可能要再做些实验才能发现其中的规律。如果你在这里就正确回答了这个问题,那么要恭喜你,因为你有很好的悟性。大多数的学习者对这个问题还是比较迷惑的,不过不要紧,因为随着课程的进行,这个问题的答案将逐渐变得显而易见。
- 前三行指令的功能为:
将2000进入ax寄存器中
将ax中的值赋值给ss
将sp的值改为0010。
- 变化的原因为:
在用t指令进行调试时,会产生中断。cpu将先把标志寄存器进栈,再把当前的cs的值进栈,IP的值最后进栈。
总结体会:
初始没有执行这段代码时,使用d命令观察2000:00内存,都是00,怎么创建栈结构指向这段内存时,我们发现有些数据了。这些数据是什么?
发现呢这里面有cs值、ip值、ax值(这个容易看出来),还有bp值(00 00),还有那个一排英文字符。
了解一下之后呢,发现:t命令实际是引发了单步中断,执行中断例程时,CPU会将一些中断例程使用的的寄存器变量自动压栈到栈中,此例中就包括了上述的寄存器变量的值。
注意:由于t命令必须保存寄存器变量的值(这个是中断程序定义的。)它也占用一定的空间。可能我们定义的栈空间比较小;频繁的使用push指令,为了避免栈顶超界,我们尽量使栈空间大些,就像此程序,设定栈空间是100H。