__cdecl,__ stdcall和__fastcall都被称为完全相同的方式?

时间:2013-02-24 01:40:53

标签: c++ visual-c++ assembly masm calling-convention

我使用的是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都可以用同样的方式调用?

2 个答案:

答案 0 :(得分:11)

问题在于您正在为x64目标进行编译。来自MSDN

  

鉴于扩展的寄存器集,x64只使用__fastcall调用   约定和基于RISC的异常处理模型。 __fastcall   model使用寄存器作为前四个参数和堆栈帧   传递其他参数。

切换到编译x86目标,你应该能够看到各种调用约定。

答案 1 :(得分:4)

据我所知,x64只使用__fastcall约定。 __cdecl和stdcall将被编译为__fastcall。