2013-02-24 45 views
7

मैं विजुअल सी ++ 2010 का उपयोग कर रहा हूं, और एमएएसएम को अपने x64-Assembler के रूप में उपयोग कर रहा हूं।__cdecl, __stdcall और __fastcall सभी को ठीक उसी तरह कहा जाता है?

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

कारण मैं यह कर रहा हूं तो मैं अलग बुला सम्मेलनों सीख सकते है। मैं योग का कॉलिंग कन्वेंशन स्टडकॉल बनाउंगा, और एएसएम कोड को संशोधित करूंगा ताकि यह "stdcall" तरीके को कॉल करेगा। एक बार जब मैं काम कर रहा हूं, तो मैं इसे कहूंगा, फास्टकॉल कहूंगा, और फिर उसे "फास्टकॉल" तरीके से कॉल कर दूंगा।

लेकिन अभी मेरे असेंबली कोड को देखें। जब मैं उस कोड का उपयोग करता हूं, कोई फर्क नहीं पड़ता कि अगर sum stdcall, fastcall या cdecl है, तो यह संकलित होगा, ठीक निष्पादित करेगा, और 25 को मेरे योग के रूप में प्रिंट करेगा।

मेरा प्रश्न: कैसे, और क्यों __cdecl, __stdcall और __fastcall सभी को ठीक उसी तरह कहा जा सकता है?

उत्तर

10

समस्या यह है कि आप x64 लक्ष्यों के लिए संकलित कर रहे हैं। MSDN

विस्तार रजिस्टर सेट को देखते हुए से, 64 बस __fastcall सम्मेलन और एक RISC आधारित अपवाद-हैंडलिंग मॉडल बुला उपयोग करता है। __fastcall मॉडल दूसरे पैरामीटर को पार करने के लिए पहले चार तर्कों और स्टैक फ्रेम के लिए रजिस्टरों का उपयोग करता है।

x86 लक्ष्यों के लिए संकलन करने के लिए स्विच करें, और आप कार्रवाई में विभिन्न कॉलिंग सम्मेलनों को देखने में सक्षम होना चाहिए।

+3

"विंडोज संदर्भ में x64 आर्किटेक्चर के लिए संकलन करते समय (चाहे माइक्रोसॉफ्ट या गैर-माइक्रोसॉफ्ट टूल्स का उपयोग कर रहे हों), केवल एक कॉलिंग सम्मेलन है - यहां वर्णित एक, ताकि stdcall, thiscall, cdecl, fastcall, आदि, अब सब एक और एक ही हैं। " http://en.wikipedia.org/wiki/X86_calling_conventions –

+0

ठीक है ... मैं सिर्फ x86 पर स्विच करने जा रहा हूं और विभिन्न कॉलिंग सम्मेलनों के साथ संकलन करने की कोशिश करता हूं और देखता हूं कि परिणाम क्या हैं, यह जांचने के लिए कि क्या यह है करते हुए। जब यह संभवतः काम करता है, तो मैं आपका जवाब स्वीकार करूंगा :) – Aaron

+0

बहुत बढ़िया, x86 में बदल रहा है। आपका बहुत बहुत धन्यवाद! – Aaron

3

जहां तक ​​मुझे पता है कि x64 केवल __fastcall सम्मेलन का उपयोग करता है। __cdecl और stdcall को सिर्फ __fastcall के रूप में संकलित किया जाएगा।