只是一个测试__cdecl
调用约定。
这是一个 cmake 项目,只有 1 个源文件:
#include <stdio.h>
#define CALL_CONVENTION __cdecl
void CALL_CONVENTION f(int a, int b)
{
printf("%d, %d", a, b);
}
int main()
{
f(1, 2);
return 0;
}
我在用着set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /FA")
输出汇编代码。
当我用cmake -G "Visual Studio 15"
,它正在构建一个 32 位应用程序,一切都在预料之中:
...
; Line 12
push ebp
mov ebp, esp
; Line 13
push 2 ; <------- argument 2
push 1 ; <------- argument 1
call _f ; <------- call function
add esp, 8
; Line 15
xor eax, eax
; Line 16
cmp ebp, esp
call __RTC_CheckEsp
pop ebp
ret 0
_main ENDP
...
你可以看到参数被传递了push 2
and push 1
说明,它是__cdecl
调用约定。
但如果我使用cmake -G "Visual Studio 15 Win64"
要构建 64 位应用程序,__cdecl
注释似乎不起作用(参数未通过堆栈传递):
...
; Line 12
$LN3:
push rdi
sub rsp, 32 ; 00000020H
mov rdi, rsp
mov ecx, 8
mov eax, -858993460 ; ccccccccH
rep stosd
; Line 13
mov edx, 2 ; <------ argument 2
mov ecx, 1 ; <------ argument 1
call f ; <------ call function
; Line 15
xor eax, eax
; Line 16
add rsp, 32 ; 00000020H
pop rdi
ret 0
main ENDP
...
参数通过寄存器传递edx
and ecx
,不通过堆栈传递。
那么为什么即使我指定,参数在 x64 中也不会通过堆栈传递__cdecl
如果我想在 x64 环境中做同样的事情我应该做什么。