调用者--调用函数的一方
被调用者--被调用的函数
原有三种方式:
__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访问寄存器的速度明显快于访问内存。