C函数的调用过程

函数调用过程

  1. 当主函数调用子函数的时候:
  • 在主函数中,将子函数的参数按照一定调用约定(参考调用约定),一般是从右向左把参数push到栈中;
  • 然后把下一条指令地址,即返回地址(return address)push入栈(隐藏在call指令中);
  • 然后跳转到子函数地址处执行: call 子函数;
  1. 此时子函数执行:
  • push %rbp; 把当前rbp的值保持在栈中;
  • mov %rsp, %rbp; 把rbp移到最新栈顶位置,即开启子函数的新帧;
  • [可选] sub $xxx, %esp; 在栈上分配XXX字节的临时空间。(即抬高栈顶,编译器根据函数中的局部变量的总大小确定临时空间的大小)
  • [可选] push XXX; 保存(push)一些寄存器的值;
  1. 子函数调用返回:
  • 保持返回值:一般将函数函数值保持在eax寄存器中;
  • [可选] 恢复(pop)一些寄存器的值;
  • mov %rbp,%rsp; 收回栈空间,恢复主函数的栈顶;
  • pop %rbp; 恢复主函数的栈底;
  • ret; 从栈顶获取之前保持的返回地址(return address),并跳转到此位置执行;

函数帧

image.png

栈的状态变化

image.png

你可能感兴趣的:(C函数的调用过程)