函数栈帧创建与销毁那些事儿
来源:互联网 发布:linux for循环用法 编辑:程序博客网 时间:2024/06/07 04:50
程序的执行过程可看作连续的函数调用。当一个函数执行完毕时,程序要回到调用指令的下一条指令(紧接call指令)处继续执行。
函数调用过程通常使用堆栈实现,每个用户态进程对应一个调用栈结构(callstack)。编译器使用堆栈传递函数参数、保存返回地址、临时保存寄存器原有值(即函数调用的上下文)以备恢复以及存储本地局部变量就是所谓的保护现场。
为了浅显易懂,直接抛代码看反汇编~
int Add(int x, int y){ int z = 0; z = x + y; return z;}int main(){ int sum = 0; int a = 2; int b = 3; sum = Add(a, b); return 0;}
我们一步一步通过反汇编来剖析调用过程:
反汇编码:
int sum = 0;0034532E C7 45 F8 00 00 00 00 mov dword ptr [sum],0 int a = 2;00345335 C7 45 EC 02 00 00 00 mov dword ptr [a],2 int b = 3;0034533C C7 45 E0 03 00 00 00 mov dword ptr [b],3
分析:
接下来看到调用Add函数:
sum = Add(a, b);00345343 8B 45 E0 mov eax,dword ptr [b] 00345346 50 push eax 00345347 8B 4D EC mov ecx,dword ptr [a] 0034534A 51 push ecx 0034534B E8 BE BD FF FF call Add (034110Eh) 00345350 83 C4 08 add esp,8 00345353 89 45 F8 mov dword ptr [sum],eax
具体分析:
函数出栈的反汇编:
return z;010637BE 8B 45 F8 mov eax,dword ptr [z] }010637C1 5F pop edi //edi返回 弹出栈010637C2 5E pop esi //esi返回010637C3 5B pop ebx //esi返回010637C4 8B E5 mov esp,ebp //将原来的ebp的值给esp010637C6 5D pop ebp //弹出ebp,使得ebp的值指向之前保存好的main函数的ebp,esp向下指向保存的地址处,此时esp和ebp维护到main函数的栈帧010637C7 C3 ret //隐藏的pop,使Add函数栈底的地址弹出。
下面是函数出栈的图解解析(黑色线条标记)
回到call指令的下一条指令
00345350 83 C4 08 add esp,8 //将形参返回弹出栈00345353 89 45 F8 mov dword ptr [sum],eax
至此,esp,ebp维护到main函数的栈帧,Add函数出栈。。。
阅读全文
0 0
- 函数栈帧创建与销毁那些事儿
- 函数的栈帧创建与销毁
- 函数栈帧的创建与销毁
- 函数的执行过程-栈帧的创建与销毁
- 浅析函数栈帧、变量的创建与销毁
- 函数的调用过程,栈帧的创建与销毁
- 函数的调用过程,栈帧的创建和销毁
- 函数的调用过程,栈帧的创建和销毁。
- 函数的调用,栈帧的创建和销毁
- 浅谈函数的调用,栈帧的创建和销毁
- 函数的调用过程,栈帧的创建和销毁
- 函数的调用及栈帧的创建和销毁
- 函数的调用过程、栈帧的创建以及销毁
- 函数调用过程,栈帧的创建和销毁
- 函数的调用(栈帧的创建和销毁)
- 函数的调用过程,栈帧的创建和销毁。
- 函数的调用过程,栈帧的创建和销毁
- 函数的调用过程,栈帧的创建和销毁
- PAT乙级1037. 在霍格沃茨找零钱(20)
- Java算数运算符、关系运算符、逻辑运算符
- PAT乙级1038. 统计同成绩学生(20)
- Java字符串等于判断
- PAT乙级1039. 到底买不买(20)
- 函数栈帧创建与销毁那些事儿
- js实现简单拖拽案例
- git安装及配置github
- PAT乙级1040. 有几个PAT(25)
- 移动端 触摸事件 ontouchstart、ontouchmove、ontouchend、ontouchcancel
- PAT乙级1041. 考试座位号(15)
- PAT乙级1042. 字符统计(20)
- PAT乙级1043. 输出PATest(20)
- PAT乙级1046. 划拳(15)