2013-02-24 10 views
7

私はVisual C++ 2010とMASMをx64-Assemblerとして使用しています。私はこれをやっている理由は、私は別の呼び出し規約を学ぶことができるである__cdecl、__stdcall、__fastcallはまったく同じ方法で呼ばれますか?

; 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 

// 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; 
} 

そして、私のアセンブリコード:
これは私のC++コードです。 sumの呼び出し規約stdcallを作成し、asmコードを変更して "stdcall"のようにsumを呼び出します。私がそれを働かせたら、私はそれをfastcallとし、それをasmで "fastcall"と呼んでいます。

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

質問:__cdecl、__stdcall、および__fastcallは、どのように、まったく同じ方法で呼び出すことができますか?

答えて

10

問題は、x64ターゲット用にコンパイルしていることです。 MSDN拡大レジスタセットを考えると

からは、x64のは、ちょうど 大会とRISCベースの例外処理モデルを呼び出す__fastcallを使用しています。 __fastcall モデルは、最初の4つの引数にレジスタを使用し、スタックフレーム は他のパラメータを渡します。

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

+3

"Microsoftのツールを使用しているかどうかに関係なく、Windowsのコンテキストでx64アーキテクチャ用にコンパイルする場合、ここで説明したように、stdcall、thiscall、cdecl、fastcallなどの呼び出し規約は1つしかありません。今はすべて同じものです」 http://en.wikipedia.org/wiki/X86_calling_conventions –

+0

さて、私はx86に切り替えて、さまざまな呼び出し規則をコンパイルし、結果が何であるかを確認してみましょう。やってそれがうまくいくと、私はあなたの答えを受け入れるでしょう:) – Aaron

+0

恐ろしい、x86に変わった。どうもありがとう! – Aaron

3

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

関連する問題