我使用的是Visual C ++ 2010,MASM是我的x64-Assembler。
这是我的C ++代码:
// include directive
#include "stdafx.h"
// functions
extern "C" int Asm();
extern "C" int (convention) sum(int x, int y) { return x + y; }
// main function
int main()
{
// print asm
printf("Asm returned %d.\n", Asm());
// get char, return
_getch();
return EXIT_SUCCESS;
}
我的汇编代码:
; external functions
extern sum : proc
; code segment
.code
Asm proc
; create shadow space
sub rsp, 20o
; setup parameters
mov ecx, 10
mov edx, 15
; call
call sum
; clean-up shadow space
add rsp, 20o
; return
ret
Asm endp
end
我这样做的原因是我可以学习不同的调用约定。 我会使sum的调用约定为stdcall,并修改asm代码,以便将“stdcall”方式称为sum。一旦我开始工作,我就会把它变成fastcall,然后以“fastcall”的方式调用它。
但是现在看看我的汇编代码。当我使用该代码时,无论sum是stdcall,fastcall还是cdecl,它都会编译,执行正常,并打印25作为我的总和。
我的问题:为什么__cdecl,__ stdcall和__fastcall都可以用同样的方式调用?
答案 0 :(得分:11)
问题在于您正在为x64目标进行编译。来自MSDN
鉴于扩展的寄存器集,x64只使用__fastcall调用 约定和基于RISC的异常处理模型。 __fastcall model使用寄存器作为前四个参数和堆栈帧 传递其他参数。
切换到编译x86目标,你应该能够看到各种调用约定。
答案 1 :(得分:4)
据我所知,x64只使用__fastcall约定。 __cdecl和stdcall将被编译为__fastcall。