8

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 コードを変更して、sum を "stdcall" の方法で呼び出すようにします。それが機能するようになったら、たとえばfastcallにしてから、asmで「fastcall」の方法で呼び出します。

しかし、今私のアセンブリ コードを見てください。そのコードを使用すると、sum が stdcall、fastcall、または cdecl のいずれであっても、コンパイル、正常に実行され、合計として 25 が出力されます。

私の質問: __cdecl、__stdcall、および __fastcall をまったく同じ方法で呼び出す方法と理由は何ですか?

4

2 に答える 2

12

問題は、x64ターゲット用にコンパイルしていることです。MSDNから

拡張されたレジスタセットが与えられると、x64は__fastcall呼び出し規約とRISCベースの例外処理モデルを使用するだけです。__fastcallモデルは、最初の4つの引数にレジスターを使用し、スタックフレームを使用して他のパラメーターを渡します。

x86ターゲットのコンパイルに切り替えると、さまざまな呼び出し規約が実際に動作していることがわかります。

于 2013-02-24T01:50:05.973 に答える
5

私の知る限り、x64 は __fastcall 規則のみを使用します。__cdecl と stdcall は __fastcall としてコンパイルされます。

于 2013-02-24T01:55:46.163 に答える