GCC的调用约定

GCC的调用约定

x32的调用约定
  • IA-32
    在32位的体系结构中,有3种调用约定,分别是cdeclstdcallfastcall,GCC的默认调用约定为cdecl。参数从右向左压栈,调用者负责在调用后清理堆栈,返回值保存在eax寄存器中,非易失寄存器为ebpespebxesiedi
    参考 C Calling Convention

cdecl 调用约定

在这个约定中,调用者自己清理堆栈上的参数(arguments),这样就允许了可变参数列表的实现,如printf()。

cdecl(C declaration,即C声明)是源起C语言的一种调用约定,也是C语言的事实上的标准。在x86架构上,其内容包括:

  • 函数实参在线程栈上按照从右至左的顺序依次压栈
  • 函数结果保存在寄存器EAX/AX/AL中。
  • 浮点型结果存放在寄存器ST0中。
  • 编译后的函数名前缀以一个下划线字符。
  • 调用者负责从线程栈中弹出实参(即清栈)。
  • 8比特或者16比特长的整形实参提升为32比特长。
  • 函数调用影响的寄存器(volatile registers):EAX, ECX, EDX, ST0 - ST7, ES, GS
  • 不受函数调用影响的寄存器: EBX, EBP, ESP, EDI, ESI, CS, DS
  • RET指令从函数被调用者返回到调用者(实质上是读取寄存器EBP所指的线程栈之处保存的函数返回地址并加载到IP寄存器)
x64的调用约定

X86上的一些调用惯例需要通过栈来传递参数,对于X64来说,多数调用惯例都是通过寄存器来传递参数。

  • X86-64
    x64的调用约定只有一种,遵守system v ABI的规范。但是Linux和windows却有一些差别。在windows X64中,前4个参数通过rcxrdxr8r9来传递,其余的参数按照从右向左的顺序压栈。在Linux上,则是前6个参数通过rdirsirdxrcxr8r9传递,其余的参数按照从右向左的顺序压栈。
    更详细的信息参考另一篇文章 system V ABI

参考资料
函数属性(GCC手册)

发布了42 篇原创文章 · 获赞 18 · 访问量 7543

猜你喜欢

转载自blog.csdn.net/weixin_44395686/article/details/105036297
今日推荐