C语言调用规约之函数入参顺序

结论

  • 在 IA-32 平台上有三种入参方式,stdcall、cdecl、fastcall,前两种参数入参顺序均为从右至左压栈,fastcall 前两个参数使用寄存器,后面参数从右至左压栈。
    C/C++ 默认使用 cdecl 方式,MSVC 编译器默认使用 stdcall 。

  • x64 平台只有一种入参方式,即 fastcall 方式,前四个参数使用寄存器保存,后面参数后从右至左压栈。

  • ARM 32位平台,前四个参数使用寄存器保存,后面参数后从右至左压栈。

  • ARM 64位平台,前8个参数使用寄存器保存 ,后面参数从右往左入栈。

  • 使用浮点数时,同上规则使用浮点寄存器,不占用对应的整型寄存器。

  • 如果参数大小小于芯片位长,则会自动提升为位长对应大小。

  • 参数中包含结构体时,且大小大于芯片位长时,x64 会将参数压入栈中,并在寄存器中保存指向该内存的指针。

  • 参数中包含结构体时,且大小大于芯片位长时,ARM 在剩余寄存器可用时,将结构体放入连续寄存器。否则将剩余参数压入栈中。

  • 以上所有结构体在栈中会按芯片位长进行对齐。

  • 以上所有平台函数返回值使用前两个寄存器,当返回结果小于芯片位长时使用第一个寄存器,小于芯片位长两倍时使用前两个寄存器。
    返回结构体,且结构体大小大于芯片位长两倍时,返回结果保存在栈中,并在第一个寄存器中保存执行该内存的指针。

参考链接

aapcs32 调用规约文档
https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aapcs32/aapcs32.rst#6the-base-procedure-call-standard

aapcs64 调用规约文档
https://github.com/ARM-software/abi-aa/blob/2bcab1e3b22d55170c563c3c7940134089176746/aapcs64/aapcs64.rst#6the-base-procedure-call-standard

MSVC 关于不同平台的调用文档:
https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160

Intel 调用规约文档:
https://www.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/c-c-calling-conventions.html

wikipedia x86 调用规约介绍
https://zh.wikipedia.org/wiki/X86%E8%B0%83%E7%94%A8%E7%BA%A6%E5%AE%9A


C语言调用规约之函数入参顺序
https://gary-hobson.github.io/2022/09/04/C语言调用规约之函数入参顺序/
作者
非典型技术宅
发布于
2022年9月4日
许可协议