什么是栈帧(Stack Frame)?
栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构。
每一次函数的调用,都会在调用栈(call stack)上维护一个独立的栈帧(stack frame).每个独立的栈帧一般包括:
- 函数的返回地址和参数
- 临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量
- 函数调用的上下文
栈是从高地址向低地址延伸,一个函数的栈帧用EBP和ESP这两个寄存器来划定范围。EBP指向当前栈帧的底部,ESP始终指向栈帧的顶部。
- EBP寄存器又被称为帧指针(Frame Pointer)
- ESP寄存器又被称为栈指针(Stack Pointer)

函数调用的过程
- 参数入栈。参数按照调用约定依次压入系统栈中,在C语言中是按照自右向左的顺序
- 保存现在位置。将当前代码区调用指令的下一条指令地址压入栈中,供函数返回时继续执行
- 跳转到子函数
其中栈帧调整的过程:
- EBP帧指针入栈:保存当前栈帧状态值,方便函数返回之后的现场恢复
- 将ESP栈指针值装入EBP帧指针,更新栈帧底部:目的是将当前栈帧切换到新栈帧 这时EBP帧指针指向栈顶,而此时栈顶就是图中的OLD EBP
- 给新栈帧分配空间:把ESP减去所需空间的大小(因为栈是从高地址向低地址),抬高栈顶
函数返回时栈帧的操作
- 保存被调用函数的返回值到寄存器中
- 给ESP加上栈帧的大小,降低栈顶,回收当前栈帧的空间(即弹出当前帧)
- 将当前栈帧底部保存的前栈帧EBP值弹入EBP寄存器,恢复出旧栈帧。
- 弹出当前栈顶元素,从栈中取到返回地址,并跳转到该位置
参考