vectorcall 是微软在VS2015中增加的 https://msdn.microsoft.com/zh-cn/library/dn375768.aspx
目的是用来优化浮点向量运算,intel处理器种有很多浮点向量寄存器,传统的调用约定(stdcall cdecl fastcall thiscall) 都是通过通用寄存器(ecx edx /rcx rdx r8 r9)以及堆栈进行参数传递,所以调用的时候,浮点参数需要从栈获取 例如:
float __stdcall addf0(float a, float b, float c)
{
return a + b + c;
}
的调用时float c = addf0(1, 2, 3);
float c = addf0(1, 2, 3);
00076EE0 push ecx
00076EE1 movss xmm0,dword ptr [__real@40400000 (080CDCh)]
00076EE9 movss dword ptr [esp],xmm0
00076EEE push ecx
00076EEF movss xmm0,dword ptr [__real@40000000 (080CC8h)]
00076EF7 movss dword ptr [esp],xmm0
00076EFC push ecx
00076EFD movss xmm0,dword ptr [__real@3f800000 (080CC4h)]
00076F05 movss dword ptr [esp],xmm0
00076F0A call addf0 (0711A4h)
00076F0F fstp dword ptr [c]
可以看出是通过栈传递的(push ecx 随便压入栈一个数,然后用mov写栈顶)再看看vectorcall
float __vectorcall addf3v(float a, float b, float c)
{
return a + b + c;
}
调用的汇编代码(可以看出直接通过寄存器传递参数,这样就是比通过栈快)
float c = addf3v(1, 2, 3);
003AB550 movss xmm2,dword ptr [__real@40400000 (03B0CDCh)]
003AB558 movss xmm1,dword ptr [__real@40000000 (03B0CC8h)]
003AB560 movss xmm0,dword ptr [__real@3f800000 (03B0CC4h)]
003AB568 call addf3v (03A170Dh)
003AB56D movss dword ptr [c],xmm0
微软的解释大概是vectorcall 继承于fastcall 但对于fastcall中的整数仍然按照fastcall规则传递 而浮点以及向量将通过寄存器传递
例如
float __vectorcall addvi3f3(int a, float b, int c, float d, int e, float f)
{
return a + b + c + d + e + f;
}
调用float c = addvi3f3(1, 2, 3, 4, 5, 6);
float c = addvi3f3(1, 2, 3, 4, 5, 6);
0023B5C0 push 5
0023B5C2 movss xmm2,dword ptr [__real@40c00000 (0240CE8h)]
0023B5CA movss xmm1,dword ptr [__real@40800000 (0240CE0h)]
0023B5D2 mov edx,3
0023B5D7 movss xmm0,dword ptr [__real@40000000 (0240CC8h)]
0023B5DF mov ecx,1
0023B5E4 call addvi3f3 (0231712h)
0023B5E9 movss dword ptr [c],xmm0
可以看到 1 3 5 符合fastcall调用 而2 4 6 则通过寄存器传递的,这样vectorcall 比传统调用约定更加快速