2013-02-24 22 views
7

Sto usando Visual C++ 2010 e MASM come x64-Assembler.
Questo è il mio codice C++:__cdecl, __stdcall e __fastcall sono tutti chiamati nello stesso modo?

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

E il mio codice assembly:

; 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 

La ragione per cui sto facendo questo è così posso imparare le diverse convenzioni di chiamata. Vorrei fare la convenzione di chiamata di somma stdcall e modificare il codice asm in modo che chiamasse sum il modo "stdcall". Una volta che ho funzionato, lo farei, diciamo, fastcall, e poi lo chiamerei in "fast call".

Ma guarda il mio codice assembly in questo momento. Quando uso quel codice, non importa se sum è stdcall, fastcall o cdecl, verrà compilato, eseguito correttamente e stampato 25 come somma.

La mia domanda: come e perché __cdecl, __stdcall e __fastcall possono essere chiamati esattamente nello stesso modo?

risposta

10

Il problema è che si sta compilando per destinazioni x64. Da MSDN

Dato il set di registro esteso, x64 utilizza solo il __fastcall chiamando di convenzione e un modello di gestione delle eccezioni RISC. Il modello __fastcall utilizza registri per i primi quattro argomenti e il frame dello stack per passare gli altri parametri.

Passa alla compilazione per destinazioni x86 e dovresti essere in grado di vedere le varie convenzioni di chiamata in azione.

+3

"Durante la compilazione per l'architettura x64 in un contesto Windows (sia che si utilizzino strumenti Microsoft o non Microsoft), esiste una sola convenzione di chiamata, quella descritta qui, in modo che stdcall, thiscall, cdecl, fastcall, ecc., ora sono tutto uguale. " http://en.wikipedia.org/wiki/X86_calling_conventions –

+0

Okay ... Passerò semplicemente a x86 e cercherò di compilare con diverse convenzioni di chiamata e vedere quali sono i risultati, solo per verificare se questo è ciò che è facendo. Quando funzionerà, accetterò la tua risposta :) – Aaron

+0

Impressionante, passando a x86 funzionante. Molte grazie! – Aaron

3

Per quanto ne so x64 utilizza solo la convenzione __fastcall. __cdecl e stdcall verranno semplicemente compilati come __fastcall.