栈帧 stack frame
每一次函数调用都会维护一个栈帧(stack frame),栈帧主要用于传递参数、保存返回地址、保存局部变量等。先直接上一个《深入理解计算机系统》上的原图。
其中,%rsp 指向栈顶位置,%rbp 指向栈底位置。并且栈是由高地址向地址方向增长。
局部变量的布局是由编译器决定的,可能是由个高地址到低地址,也可能由低地址到高地址。
被调函数的前6个参数将由寄存器传入,超过6个的部分将通过栈传入。这里需要注意的是,在被调函数中为了能够对入参进行取地址,被调函数将会将前6个参数压入被调函数的栈中。
函数调用过程:
- 参数入栈。将参数按照一定的顺序将超过6个后的参数入栈。
- 返回地址入栈。将当前代码的一条指令地址压入栈中,函数返回时继续执行。
- 跳入被调函数地址。
- EBP入栈,保存当前栈帧状态值。
- ESP值赋给EBP。
- 分配当前栈帧。
函数返回过程:
- 保存被调用函数的返回值到 EAX 寄存器中。
- 恢复 ESP。
- 将被调函数底部保存的调用函数栈帧EBP值弹入EBP寄存器,恢复调用函数栈帧。
- 弹出当前栈顶元素,从栈中取到返回地址。
下面以一个例子来验