栈帧就是一个函数执行的环境。实际上,栈帧可以简单理解为:栈帧就是存储在用户栈上的(当然内核栈同样适用)每一次函数调用涉及的相关信息的记录单元。
栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。
对于一个简单的C程序的执行过程是怎么样的?
我们先认识几个寄存器:
eax:累加(Accumulator)寄存器,常用于函数返回值。
ebx:基址(Base)寄存器,以它为基址访问内存。
ecx:计数器(Counter)寄存器,常用作字符串和循环操作中的计数器。
edx:数据(Data)寄存器,常用于乘除法和I/O指针。
esp:堆栈(Stack)指针寄存器,指向堆栈顶部。
ebp:基址指针寄存器,指向当前堆栈底部。
eip:指令寄存器,指向下一条指令的地址。
int fun1(int a, int b)
{
int c = a + b;
return c;
}
int main()
{
int a = 10;
int b = 20;
int c;
c = fun1(a, b);
return 0;
}
我们开始执行上述代码,转到反汇编。
首先是给main函数开辟栈帧并初始化(main函数是在_tmainCRTStartup函数中调用的,所以也许开辟栈帧)
然后局部变量赋值和fun1函数形参的赋值:
下来是call调用:(为开辟新的栈帧做准备)将下一行指令地址压入栈帧,将main函数的ebp入栈,esp指向ebp。进入Fun1函数的栈帧,初始化同main函数。
fun1函数栈帧的初始化
fun1函数运行:
fun1函数调用完毕,清理fun1函数栈帧:三个寄存器出栈,esp退到ebp位置,ebp指向main函数栈底。
回到main函数,esp+8找到下一行指令,继续执行
然后是清理main函数栈帧,