函数调用约定

调用者--调用函数的一方

被调用者--被调用的函数

原有三种方式:

__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访问寄存器的速度明显快于访问内存。

 

posted @ 2020-09-04 12:31  Flag{Just_For_Fun}  阅读(180)  评论(0)    收藏  举报