首页
社区
课程
招聘
[原创]深入理解C语言二-函数调用约定
发表于: 2021-7-5 23:26 5024

[原创]深入理解C语言二-函数调用约定

2021-7-5 23:26
5024

调用者和被调用者关于栈上参数传递和清理栈空间的一种约定,用来清理参数占用的栈空间,恢复栈平衡。栈平衡是编译器在汇编时完成的,不需要手动完成。

系统中的寄存器,存储CPU要读取的指令地址,CPU通过eip寄存器读取即将要执行的指令,每次CPU执行完相应的汇编指令后,eip的值就会增加。栈中的返回地址存放在eip中,供当前函数执行完后,CPU执行程序的下一条语句。

栈指针寄存器,一直指向系统栈最上面一个栈帧的栈顶,是CPU机制决定的,push、pop指令会自动调整esp的值。

基址指针寄存器,一直指向系统栈最上面一个栈帧的栈底,ebp只存取某时刻的esp,这个时刻是指进入一个函数内部后,CPU会将esp的值赋值给ebp,此时就可以通过ebp对栈进行操作,比如获取函数参数、局部变量等。
esp在函数运行时会不断变化,所以保存一个进入某个函数的esp到ebp,方便访问参数和局部变量,还方便调试器分析函数调用过程中的堆栈情况。

  • 参数入栈顺序:从右向左
  • 调用者修改栈,恢复栈平衡,所以可以支持变参函数
  • 参数入栈顺序:从右向左
  • 被调用者自身修改栈,恢复栈平衡
  • 参数入栈顺序:函数的第一、第二个参数通过ecx、edx寄存器传递,剩余参数从右向左入栈
  • 被调用者自身修改栈,恢复栈平衡
  • x64传递参数时比x86多了两个寄存器r8、r9
  • x64参数入栈对齐到8个字节,x86是4个字节
  • x64函数的前4个参数通过rcx、rdx、r8、r9四个寄存器传递
  • x64会在栈上预留4个字节的内存空间
  • x64调用者恢复栈平衡,支持变参函数
  • x64栈整体大小要能被16整除
  • x64局部变量空间的分配和初始化由调用者完成
  1. cdecl(C语言默认,变参函数)
  2. stdcall(Windows API,内核驱动)
  3. fastcall(x64平台)
  • cdecl(C语言默认,变参函数)
  • stdcall(Windows API,内核驱动)
  • fastcall(x64平台)
  • 参数入栈顺序:从右向左

  • [注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

    收藏
    免费 1
    支持
    分享
    最新回复 (0)
    游客
    登录 | 注册 方可回帖
    返回
    //