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