函数调用约定
调用者--调用函数的一方
被调用者--被调用的函数
原有三种方式:
__cdecl,调用者负责清理栈空间
__stdcall,被调用者负责清理栈空间
__fastcall,前两个参数必须由寄存器ecx, edx进行传递。
x86(x32)默认使用的cdecl方式进行函数调用
x64 废弃了x86(x32)既有的调用约定,默认情况下使用fastcall的调用约定。
x64:
fastcall,整型传参时,前四个参数将被保存在RCX, RDX, R8, R9中,后面的参数将存放于堆栈上
void func(int a, int b, int c, int d) ->RCX, RDX, R8, R9
fastcall,浮点数传参时,前四个参数将被保存在XMM0, XMM1, XMM2, XMM3中,后面的参数将存放于堆栈上
void func(float a, float b, float c, float d)->XMM0, XMM1. XMM2, XMM3
| 参数类型 | 第 5 个和更高位置 | 第 4 个 | 第3 个 | 第 2 个 | 最左侧 |
|---|---|---|---|---|---|
| 浮点 | 堆栈 | XMM3 | XMM2 | XMM1 | XMM0 |
| 整数 | 堆栈 | R9 | R8 | RDX | RCX |
聚合(8、16、32 或 64 位)和 __m64 |
堆栈 | R9 | R8 | RDX | RCX |
| 其他聚合,作为指针 | 堆栈 | R9 | R8 | RDX | RCX |
__m128,作为指针 |
堆栈 | R9 | R8 | RDX | RCX |
参考链接:https://docs.microsoft.com/zh-cn/cpp/build/x64-calling-convention?view=vs-2019
后话:
x64使用的__fastcall的原因可能有以下原因:
1.寄存器数量整型和浮点型各有16个,在数量上满足了传参的需要。
2.CPU访问寄存器的速度明显快于访问内存。
浙公网安备 33010602011771号