浅析栈帧
来源:互联网 发布:软件著作权范本 编辑:程序博客网 时间:2024/05/22 09:05
栈帧(stack Frame):即为函数的调用过程。我们知道每一次函数调用都是一个过程。
这个过程我们通常称之为函数的调用过程。这个过程要为函数开辟栈空间,用于本次函数的调用中临时变量的保存、现场保护。这块栈空间我们称之为函数栈帧。
一次函数调用包括将数据和控制从代码的一个部分传递到另外一个部分,栈帧与某个过程调用一一映射。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低址地)。
入栈操作:push eax; 等价于 esp=esp-4,eax->[esp];如下图:
出栈操作:pop eax; 等价于 [esp]->eax,esp=esp+4;如下图:
下面通过一个简单的实例来深入研究一下函数的调用过程:
#include<stdio.h>
intAdd(intx,inty)
{
intz =0;
z = x + y;
returnz;
}
intmain()
{
inta =10;
intb =20;
intret = Add(a, b);
printf("ret = %d\n", ret);
return0;
}
当程序调试的时候,可以查看【调用堆栈】,如下图:
可以发现其实main函数是在__tmainCRTStartup函数中调用的,
而__tmainCRTStartup函数是在mainCRTStartup中被调用的。
栈帧的维护必须了解ebp和esp两个寄存器。在函数调用的过程中这两个寄
存器存放了维护这个栈的栈底指针和栈顶指针。
比如:
调用main函数,我们为main函数分配栈帧空间,那么栈帧维护如下:
要详细研究函数的调用过程,必须得对应汇编代码。
1.从main函数开始,要展开main函数的调用就得为main函数创建栈
帧,下面先来看main函数栈帧的创建,如下图:
2.接下来是Add函数的调用。
参数传递过程如下图:
执行call指令的时候按F11,来到了这里,如下图:
再按F11就进入Add函数的执行代码处,如下图:
剩下的就是函数返回部分,如下图:
注:栈帧的实现在不同的编译器上存在差异,但是思想都是一致的。
栈帧部分已经描述了函数参数的保存位置,即保存在调用者栈帧的尾部固定长度偏移位置,程序运行时就根据函数的定义和该位置取参数进行相应的运算。
注:这里函数调用的参数显然存储在函数调用者的栈帧中,而不是被调用函数的栈帧中。
- 浅析栈帧结构
- 浅析栈帧
- 浅析栈帧
- 栈帧结构浅析记录
- 以太网帧浅析!
- oSIP协议栈浅析
- 浅析堆和栈
- oSIP协议栈浅析
- 栈浅析[解密回文]
- 浅析函数调用栈
- 浅析函数调用栈
- 浅析C++程序栈
- struts2 值栈浅析
- 单调栈浅析
- 浅析
- 浅析
- 浅析函数栈帧、变量的创建与销毁
- WAP1.x协议栈浅析
- 阿里支付宝和腾讯微信,最终谁会成为中国Market big brother?
- 剑指offer经典编程(七)
- 《JAVA与模式》之适配器模式
- 火狐浏览器Firebug控制台显示本页面不包含 javascript的解决方案
- ORACLE数据库安装手册(Oracle 11g 64位版本)
- 浅析栈帧
- 2D游戏工具
- 使用Gradle发布Android开源项目到JCenter
- 彻底掌握Android多分包技术MultiDex-用Ant和Gradle分别构建(一)
- matlab中kmeans简单使用
- spring boot 使用docker在阿里云容器服务部署
- HDU 1402 A * B Problem Plus FFT
- 制作文字阴影
- mongodb 命令行