第二十二课_堆栈图2

前言

昨天,说了一个简单的加法函数的堆栈图,看了源码的同学会发现:在C语言中简单的几行代码,在汇编中却做了很多事情。今天也是说堆栈图,今天说的是三个参数的函数,今天就不一句一句的画了,我们开始一片一片的画。

说明:源码和exe执行程序已经放网盘,地址在文末。编译器用的是VC6,exe是Debug版的。今天讲的会比较简陋,看不懂的,可以看看昨天这篇文章《第二十一课_堆栈图1》。

具体步骤

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

2、根据OD中的内容绘制调用函数前的堆栈情况。

绘制的堆栈图,(为省空间,栈顶、栈底之间的空间中一个格表示)。

3、下面的三个指令:PUSH 0,PUSH 2,PUSH 5,看过昨天文章的同学应该知道这就是函数的参数,这三个指令都是压栈的操作。(学过C后,可以看源码,比较汇编中的顺序和C语言中调用时参数的顺序)

在OD中按F8运行这三条指令,跟我们画的一样。

4、下一条指令是call指令,这条指令会把call的下一条指令的地址压入栈中(作用是,当call的函数执行完成后,可以返回到当前call的下一条指令)。

按F7运行,可以看到call的下一条指令的地址被压入栈中。

5、下一条是JMP指令,该指令修改EIP,不会修改栈,直接按F8运行。

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

按F8运行,结果与我们画的一样。

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

按F8运行的结果如下:

8、下一条指令:SUB ESP,40,这里的40是十六进制的,栈顶被提升了0x40,以4个地址为一格,就要画16格。

按F8运行,可以看到栈顶确实提升了。

9、下面三条指令:PUSH EBX,PUSH ESI,PUSH EDI,这三条指令是保存现场,说明EBX,ESI,EDI这些寄存器后面有指令可能(注意是可能)会对他们进行修改。当函数功能完成后,把他们从栈中弹出来,还原成现在的样子。

按F8运行这三条指令

10、下面的指令:LEA EDI,DWORD PTR SS:[EBP-40],MOV ECX,10,MOV EAX CCCCCCCC,REP STOS DWORD PTR ES:[EDI],这四条指令是把刚才提升的栈的空间填充CCCCCCCC,为了避免程序缓冲区溢出。

按F8运行这四条指令。

11、下面的指令:MOV EAX,DWORD PTR SS:[EBP+8],ADD EAX,DWORD PTR SS:[EBP+C],SUB EAX,DWORD PTR SS:[EBP+10],这三条指令就是这个函数的主要功能,使用栈底加偏移的方式读取参数,先把两个参数相加,然后把相加的结果减到第三个参数,结果保存到EAX寄存器中。即:5 + 2 - 0 = 7,所以最后EAX中保存的是7。按F8运行这三条指令,结果跟预想的一样。

12、下面的三条指令:POP EDI,POP ESI,POP EBX,这三条指令就是还原现场,这跟步骤9中的顺序相反,即先入栈的后出。

按F8运行,可以看到栈中的内容确实弹出到相应的寄存器中。

13、下一条指令:MOV ESP,EBP,降低栈,修改ESP。

按F8运行。

14、下一条指令:POP EBP,把步骤6压入的栈底弹出的EBP中,还原原来的栈底。

按F8运行的结果。

15、下一条指令:TETN,返回指令,会把步骤4call指令时压入栈的call的下一行指令的地址弹出到EIP中,让当前程序运行到调用call的下一行指令。

按F8运行。

16、还有一条指令:ADD ESP,0C,这是平衡堆栈的。让栈还原成调用函数前的样子。

按F8运行。

全部图片:

资料:

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

提取码:dh3b

 

写于2020.6.27 23:46

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值