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

Aar*_*ron 7 c++ assembly masm calling-convention visual-c++

我使用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;
}
Run Code Online (Sandbox Code Playgroud)

我的汇编代码:

; 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
Run Code Online (Sandbox Code Playgroud)

我这样做的原因是我可以学习不同的调用约定.我会使sum的调用约定为stdcall,并修改asm代码,以便将"stdcall"方式称为sum.一旦我开始工作,我就会把它变成fastcall,然后以"fastcall"的方式调用它.

但是现在看看我的汇编代码.当我使用该代码时,无论sum是stdcall,fastcall还是cdecl,它都会编译,执行正常,并打印25作为我的总和.

我的问题:如何以及为什么__cdecl,__ stdcall和__fastcall都可以完全相同的方式调用?

Pra*_*ian 11

问题是你正在编译x64目标.来自MSDN

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

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

  • "在Windows上下文中编译x64架构时(无论是使用Microsoft还是非Microsoft工具),只有一个调用约定 - 这里描述的那个,所以stdcall,thiscall,cdecl,fastcall等现在都是一个一个." http://en.wikipedia.org/wiki/X86_calling_conventions (3认同)

use*_*078 5

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