实验2
Posted xyl744188
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实验2相关的知识,希望对你有一定的参考价值。
(1)使用DEBUG,将上面的程序段写入内存,逐条执行,根据指令执行后的实际运行情况填空。
1 mov ax,ffff //另外,这里的ffff改为0021,也许有人会有疑问,为什么这两行指令不能简化成一句mov ds,0021,事实是,8086CPU不支持将数据直接送入段寄存器的操作 2 mov ds,ax 3 4 mov ax,2200 //同样的,ss也是段寄存器,用以存放栈顶的段地址 5 mov ss,ax 6 7 mov sp,0100 //sp是栈顶的偏移地址 8 9 mov ax,[0] ;ax=3130H //[...]是内存单元,...是偏移地址,其段地址存放在ds中 10 add ax,[2] ;ax=6462H
11 mov bx,[4] ;bx=3534H 12 add bx,[6] ;bx=6C6AH 13 14 push ax ;sp=00FEH,修改的内存单元地址是2200:00FEH内容为6462H//压栈 15 push bx ;sp=00FCH ,修改的内存单元地址是2200:00FCH内容为6C6AH 16 pop ax ;sp=00FEH,ax=6C6AH
17 pop bx ;sp=0100H,bx=6462H //弹栈,并将值赋给后面的操作数 18 19 push [4] ;sp=00FEH,修改的内存单元地址是2200:00FEH 内容为3534H 20 push [6] ;sp=00FCH,修改的内存单元地址是2200:00FCH内容为3736H
在上图的代码中我给出了详细的说明。
我用红笔标出了各个值得变化情况。
单步调试如下:
也许有人会对14~17行的代码有疑问,下面我用几张图来简单说一下:
这是执行push ax后,栈的表示
压栈分为2步:首先,sp=sp-2;其次,执行push ax.
执行push bx.
这是执行pop ax,栈的表示
弹栈也分为2步:首先,sp=sp+2;其次,执行pop ax.
执行pop bx
此时栈为空。
栈的取值机制遵循FILO(即先进后出)
我有个问题不是很明白:
为什么sp=sp-2而不是sp=sp-1?
在单步调试的时候,为什么mov sp,0100被跳过执行了它的下一步,此时sp的值已经被改变了。
(2)仔细观察图3.19中的实验过程然后分析:为什么2000:0~2000:f中的内容会发生改变?
最后一行的66 33 23 13 是通过两个压栈指令得到的。
通过以上两张图可以发现:同样是执行到073F:0110,一次是单步执行,还有一次是一下子执行到那。
两次查看2000:0~f中的值是不同的,这是为什么呢?还有一些值明明没有入栈又为什么会出现在栈中呢?
对于第二个问题,我们可以发现这些值是寄存器里的值,虽然不知道它是怎么进去的。
我看了这个实验的答案,说实话不是很明白。
因为在debug使用T等指令引发了中断造成的,中断过程使用当前栈空间存放cpu关键数据,所以,你的栈里就有些不是你操作的数据了。 (答案)
总结:不知道该说些什么,有很多地方不是很明白,对栈的理解十分粗浅,但它又确实很重要,从C/C++/JAVA中我们都会谈及它。通过这次实验,对push,pop指令可以正确使用。
以上是关于实验2的主要内容,如果未能解决你的问题,请参考以下文章
使用 React 实验性中继片段:缺少属性 '"$fragmentRefs"'
[NTUSTISC pwn LAB 7]Return to libc实验(puts泄露libc中gadget片段定位)