__cdecl、__stdcall和__fastcall的调用方式完全相同

__cdecl, __stdcall and __fastcall are all called the exact same way?

本文关键字:方式完 调用 fastcall cdecl stdcall      更新时间:2023-10-16

我使用Visual C++2010和MASM作为我的x64汇编程序
这是我的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。一旦我做到了,我就会打,比如说,快速呼叫,然后用asm的"快速呼叫"方式来称呼它。

但现在看看我的汇编代码。当我使用该代码时,无论sum是stdcall、fastcall还是cdecl,它都会编译、执行fine,并将25打印为我的sum。

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

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

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

切换到针对x86目标的编译,您应该能够看到各种调用约定的作用。

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

相关文章: