第二十五课_堆栈图5

前言

今天算是汇编的结束篇的文章吧,今天说的也是堆栈图,不过今天说的是栈中栈,即一个函数中调用另一个函数。可以说当你会画堆栈图的时候,C语言中的很多问题都可以自己去看汇编,了解他们的本质,即使是指针、虚函数等很难懂的知识点,都可以自己进行检验。

说明:本节中用到的exe可执行文件的C语言的源码都放到网盘了,地址在文末。

具体步

1、打网盘中下载的yiDaChengXuYuan_stack5.exe拖到OD中打开,按Ctrl+G,在弹出的对话框中输入“004010C8”,在定位到的行按F2设置断点,然后点击上方蓝色的小三角按钮,让程序运行到刚设置的断点处。

2、查看当前OD中的栈顶、栈底。

根据OD中的内容绘制当前的栈。(为节省空间,栈顶、底之间的空间就用一个格表示)。

3、下面的三条指令:PUSH 2,PUSH 5,入栈。

按F8运行的结果。

4、下一条指令是call指令,执行这条指令会把call的下一条指令的地址压入栈中。

F7运行。

5、下一条是JMP指令,没有改变栈,直接按F8运行就可以了

6、下一条指令是:PUSH EBP,该指令把当前的栈底压入栈中。

按F8运行的结果如下

7、下一条指令是:MOV EBP,ESP,修改栈底。

按F8运行的结果

8、下一条指令是:SUB ESP,40,提升栈顶,这里的40是十六进制的,因为画图时是4个地址为一个格,所以要画16个格。

按F8运行的结束。

 

9、下面三条指令:PUSH EBX,PUSH ESI,PUSH EDI,保存现场,把可能会修改的寄存器的值压入栈中。

按F8运行。

10、下面的指令:LEA EDI,DWORD PTR SS:[EBP-40],MOV ECX,10,MOV EAX,CCCCCCCC,REP STOS DWORD PTR ES:[EDI],这几条指令就是填充提升的栈空间。

按F8运行这几条指令

11、从这里开始,准备调用另一个call,即另一个函数。下一条指令MOV EAX,DWORD PTR SS:[EBP+C],即把参数2,放到寄存器EAX中。

12、下一条指令:PUSH EAC,PUSH 4,将两个参数入栈。

按F8运行。

13、下一条指令又是一条Call指令,执行这条指令会把call的下一条指令的地址压入栈中。

F7运行。

14、下一条是JMP指令,没有改变栈,直接按F8运行就可以了。

15、可以看到这又是一个新的函数,跟刚才的画的堆栈方式很相似。为了节省篇幅,前面的部分,提升堆栈,保存现场,填充提升的栈空间等部分就不一一赘述了,用一张图略过吧。

16、下一条指令:MOV EAX,DWORD PTR SS:[EBP+8],其实就是把参数4放到寄存器EAX

17、下一条指令:SUB EAX,DWORD PTR SS:[EBP+C],其实就是参数4和参数2相减。

18、后面的是还原现场,降低堆栈等也只用一个图略过。

在OD中的运行结果。

19、下一条指令是RETN指令,返回到调用该call的下一条指令的地址。

按F8运行。

20、下一条指令:ADD ESP,8,是平衡堆栈的.

在OD中运行的结果。

21、下一条指令:MOV ECX,DWORD PTR SS:[EBP+8],就是把参数5放到寄存器ECX中。

22、下一条指令:ADD EAX,ECX,就是把刚才调用call指令的结果与参数5相加,最后的结果保存到EAX中。

23、后面的就是还原现场,降低堆栈,就不一一细说的,前面画过那么多,应该都知道怎么弄。用一张图略过吧。

24、大家还看到如下的几条指令,不用管它,这是编译器加的,因为我们函数中调用了其他函数,为了避免函数调用后堆栈乱了。

好了就写这么多吧。

资料网盘地址:

链接:https://pan.baidu.com/s/1bBxpU7chc4OqGuyJ8xbhtA

提取码:99xp

 

写于2020.7.13 1:15