栈帧步骤解读
来源:互联网 发布:unity3d控制物体跳跃 编辑:程序博客网 时间:2024/06/05 10:46
各寄存器,指令:
ebp:栈底指针
esp:栈顶指针
eip:程序计数器,为cpu指向下一条应该执行的语句
move:后值赋给前值
push:入栈
pop+ ? :出栈,并将出栈内容赋给后面的寄存器
call:(1)将当前call命令的下一条指令的地址以入栈的方式保存起来,用作恢复
(2)以jmp方式跳转
ret:将当前元素进行出栈处理,并将值赋给eip
下面以一段代码为例:
#include<stdio.h>int fun(int a,int b){ int c=a+b; return c;}int main(){ int a=10; int b=20; int c=fun(a,b); printf("hehe\n"); return 0;}
1.对ebp进行入栈操作,令esp先等于ebp,再另esp减16进制数字0e4h,在esp与ebp之间形成了一段数据空间,此段空间为main函数的栈帧空间。
2.依次初始化元素a,b,并存储在ebp-4,ebp-8处(先定义的元素存在高地址,后定义的元素存在低地址)。
3.接下来就到了调用函数fun这一步了,在调用函数前,先要定义形参(形参实体化),定义的形参以入栈的形式存在main函数栈帧的下方。
(1);定义形参时,总是从右向左定义,即先b后a
(2);每进行一次入栈操作,栈顶指针均下移,根据不同的数据类型下移不同的字节大小,此处均为4字节
4.为了保证函数调用结束以后cpu仍然能执行main函数的下一步语句,此处故使用call指令
call:(1)将当前call命令的下一条指令的地址以入栈的方式保存起来,用作恢复(2)以jmp方式跳转。
此处call存储了printf(“hehe\n”);语句的地址。
5.上述步骤均做完以后,就可以正式的进入函数调用了,首先与main函数一样,只要函数被调用,就要为他分配一段空间作为栈帧空间:
(1)先对ebp做入栈操作,ebp是指向main函数栈底的指针,此处入栈就是为了保存main函数栈底的位置,为ebp后期返回原处做好标记
(2)令ebp指向esp所指向的位置
(3)esp减OCCh。(add—-加 sub—-减 mul—-乘 div—-除)
此时fun函数的栈帧空间也就分配完毕了。
6.令a的值存入寄存器,在用add指令将a与b加起来,仍然存在寄存器中
7.将a+b的值存在ebp+4处,此句即int c=a+b;
8将c存入寄存器,用做返回值。
9.进行到这一步,fun函数的调用就算结束了。接下来要释放fun函数占用的栈帧空间:令esp指向ebp所指向的地址。
10.做出栈操作,并将出栈元素存储在ebp中(刚好,栈顶元素为最初main函数栈底的地址,此处出栈,令ebp还原的最初的状态—-指向main函数的栈底)
11.最后执行ret操作,刚好栈顶元素是在调用fun函数前存的main函数中的下一条地址。所以cpu会重新返回到main函数执行调用fun的下一条语句,esp+8是栈顶指针也还原到调用函数之前的位置。
- 栈帧步骤解读
- DAGScheduler核心步骤解读
- C语言声明解读步骤
- C语言声明解读步骤
- 深入解读EDM邮件营销推广步骤
- nginx 安装部署 步骤 及配置解读
- git分支上传文件步骤解读
- 解读支付宝实现的步骤
- 信息模块打线步骤及技巧解读
- 解读OpenGL ES 2.0绘制一个三角形的步骤
- 解读thchs30/s5/run.sh的主要步骤
- 802.11关联帧解读
- Android任务栈解读
- 值栈解读
- 解读
- 2010-07-09 12:03 全面解读.Net Framework源码调试详细步骤
- e良师益友为大家解读PPT文件转换为视频格式的步骤及注意事项:
- 步骤
- Bugly 安卓ios符号表配置,手动上传
- codeforces 546e Soldier and Traveling
- 类加载时机与过程
- 2017年支付宝红包活动 最新支付宝红包口令
- js监听css3动画实现
- 栈帧步骤解读
- 支付宝如何领口令红包 支付宝复制口令领红包
- 虚拟机系统下安装centos7及桌面系统
- LeetCode Merge k Sorted Lists
- SQL With(递归 CTE 查询)
- Ambari 整合 Presto
- 进程,PCB,task_struct
- Ambari 整合 Azkaban
- js逻辑