2010-09-13 19 views
5

वर्तमान में मैं कुछ असेंबली भाषा प्रक्रियाएं लिख रहा हूं। जैसा कि कुछ सम्मेलन कहते हैं, जब मैं कॉलर को कुछ मूल्य वापस करना चाहता हूं, तो एक पूर्णांक कहें, मुझे इसे ईएक्स रजिस्टर में वापस करना चाहिए। अब मैं सोच रहा हूं कि क्या मैं एक फ्लोट, एक डबल, एक enum, या यहां तक ​​कि एक जटिल संरचना वापस करना चाहता हूँ। इन प्रकार के मूल्यों को कैसे वापस करें?एक जटिल वापसी मूल्य वापस कैसे करें?

मैं ईएक्स में एक पता लौटने के बारे में सोच सकता हूं जो स्मृति में वास्तविक मूल्य को इंगित करता है। लेकिन क्या यह मानक तरीका है?

बहुत धन्यवाद ~~~

+2

यदि आप "मानक तरीका" जानना चाहते हैं, तो आपको अपना मंच निर्दिष्ट करना होगा। क्या हार्डवेयर, ओएस, और आप किस कंपाइलर का उपयोग कर रहे हैं? –

+0

@StephenCanon मुझे नहीं पता था कि जब मैंने प्रश्न पोस्ट किया था तो उनसे संबंधित हैं। धन्यवाद। – smwikipedia

उत्तर

10

कॉलर आपका कोड है, तो यह सब आपके ऊपर है। यदि कॉलर आपके नियंत्रण में नहीं है, तो आपको या तो अपने मौजूदा सम्मेलन का पालन करना होगा या अपने स्वयं के सम्मेलन को एक साथ विकसित करना होगा।

उदाहरण के लिए, x86 प्लेटफ़ॉर्म पर जब फ़्लोटिंग-पॉइंट अंकगणित एफपीयू निर्देशों द्वारा संसाधित किया जाता है, तो फ़ंक्शन का परिणाम एफपीयू रजिस्टर स्टैक पर शीर्ष मान के रूप में वापस कर दिया जाता है। (यदि आप जानते हैं, x86 एफपीयू रजिस्ट्रारों को "सर्कुलर स्टैक" प्रकार में व्यवस्थित किया जाता है)। उस समय यह न तो float और न ही double है, यह आंतरिक एफपीयू परिशुद्धता (जो float या double से अधिक हो सकता है) के साथ संग्रहीत मूल्य है और यह कॉलर की जिम्मेदारी एफपीयू स्टैक के शीर्ष से उस मूल्य को पुनर्प्राप्त करने और इसे जो कुछ भी परिवर्तित करने के लिए है इच्छाओं को टाइप करें। असल में, यह एक सामान्य एफपीयू निर्देश कैसे काम करता है: यह एफपीयू स्टैक के शीर्ष से अपने तर्क लेता है और परिणाम को वापस एफपीयू स्टैक पर धक्का देता है। अपने कार्य को उसी तरह कार्यान्वित करके, आप अनिवार्य रूप से अपने कार्य के साथ "जटिल" एफपीयू निर्देश का अनुकरण करते हैं - इसे करने का एक प्राकृतिक तरीका।

जब फ्लोटिंग-पॉइंट अंकगणित एसएसई निर्देशों द्वारा संसाधित किया जाता है, तो आप उसी उद्देश्य के लिए कुछ एसएसई रजिस्टर चुन सकते हैं (xmm0 का उपयोग करें जैसे कि आप पूर्णांक के लिए EAX का उपयोग करते हैं)।

जटिल संरचनाओं के लिए (यानी जो एक रजिस्टर या रजिस्टरों की एक जोड़ी से बड़े हैं), कॉलर सामान्य रूप से फ़ंक्शन में आरक्षित बफर को पॉइंटर पास करेगा। और समारोह परिणाम को बफर में डाल देगा। दूसरे शब्दों में, हुड के तहत, कार्य वास्तव में बड़ी वस्तुओं को "वापस" नहीं करते हैं, बल्कि उन्हें कॉलर द्वारा प्रदत्त मेमोरी बफर में बनाते हैं।

बेशक, आप किसी भी प्रकार के मानों को वापस करने के लिए इस "मेमोरी बफर" विधि का उपयोग कर सकते हैं, लेकिन छोटे मानों के साथ, यानी स्केलर प्रकार के मान, स्मृति स्थान की तुलना में रजिस्टरों का उपयोग करना अधिक कुशल है। यह बीटीडब्ल्यू, छोटे संरचनाओं के लिए भी लागू होता है।

Enums आमतौर पर कुछ पूर्णांक प्रकार पर एक वैचारिक आवरण होते हैं। तो, एक enum या एक पूर्णांक लौटने के बीच कोई अंतर नहीं है।

0

आमतौर पर आप ढेर

+1

सी एबीआई का उपयोग करके आप ढेर का उपयोग करते हैं। सी ++ में यह अनिर्धारित है जिससे संकलक निर्माताओं को अधिक प्रभावशाली तंत्र चुनने की अनुमति मिलती है (यदि वे चाहते हैं)। –

0

का प्रयोग करेंगे आप सी या एक और उच्च स्तर की भाषा के साथ इंटरफेस करने की योजना बना रहे हैं, तो आम तौर पर आप के रूप में एक स्मृति बफर के पते को स्वीकार करेंगे आपके फ़ंक्शन के लिए एक तर्क और उस बफर को पॉप्युलेट करके अपना जटिल मान वापस कर दें। यदि यह केवल असेंबली है, तो आप अपने स्वयं के सम्मेलन को किसी भी रजिस्ट्रार के सेट का उपयोग करके परिभाषित कर सकते हैं, हालांकि आमतौर पर आप केवल ऐसा ही करेंगे यदि आपके पास कोई विशिष्ट कारण है (उदा।, प्रदर्शन)।

6

स्टैक में पहली वस्तु के रूप में एक डबल वापस किया जाना चाहिए।

double sqrt(double n) 
{ 
    _asm fld n 
    _asm fsqrt 
} 

आप मैन्युअल रूप से ढेर प्रबंधन करने के लिए (कुछ CPU चक्र बचत) पसंद करते हैं:

double inline __declspec (naked) __fastcall sqrt(double n) 
{ 
    _asm fld qword ptr [esp+4] 
    _asm fsqrt 
    _asm ret 8 
} 

जटिल प्रकार के लिए, आप पास करना चाहिए

यहाँ एक सी ++ कोड उदाहरण (x86) है एक सूचक, या एक सूचक वापस।

+0

यदि आप कहते हैं कि आपको कंपाइलर (विह संस्करण) और ओएस (संस्करण के साथ) निर्दिष्ट करने की आवश्यकता है, हालांकि आपको शायद अपने कंपाइलर के लिए एबीआई दस्तावेज़ निर्दिष्ट करना चाहिए। ऐसा इसलिए है क्योंकि सभी सी ++ कंपाइलर्स ऐसा नहीं करते हैं। सभी सी संकलक करेंगे क्योंकि सी एबीआई अच्छी तरह परिभाषित है। –

+0

दाएं। यह Win32, VC++ 2008 के लिए है। लेकिन शायद सभी वीसी संस्करणों के लिए काम करेगा। –

1

सी 99 में जटिल जटिल डेटा प्रकार (_Complex) है। तो यदि आपके पास सी 99 अनुपालन कंपाइलर है, तो आप केवल कुछ फ़ंक्शन संकलित कर सकते हैं जो एक जटिल लौटाता है और इसे असेंबलर में संकलित करता है (आमतौर पर -S विकल्प के साथ)। वहां आप जो सम्मेलन लिया जाता है उसे देख सकते हैं।

+0

'-वेव-टेम्पस' के साथ भी प्रयास करें। –

2

जब आपके पास सम्मेलनों या असेंबली भाषा को कॉल करने के बारे में कोई प्रश्न हैं, तो उच्च स्तरीय भाषा (एक अलग फ़ाइल में) में एक साधारण कार्य लिखें। इसके बाद, क्या आपका कंपाइलर असेंबली भाषा सूची उत्पन्न करता है या आपका डीबगर डिस्प्ले "इंटरलीव किए गए असेंबली" को प्रदर्शित करता है।

न केवल सूची आपको बताएगी कि संकलक कोड कैसे लागू करता है, बल्कि आपको कॉलिंग सम्मेलन भी दिखाता है। एसओ को पोस्ट करने से बहुत आसान और आमतौर पर तेज़। ;-)

1

यह एबीआई पर निर्भर करता है। उदाहरण के लिए, x86 पर लिनक्स Sys V ABI का उपयोग करता है, जो Intel386 Architecture Processor Supplment, Fourth Edition में निर्दिष्ट है।

अनुभाग फ़ंक्शन कॉलिंग अनुक्रम अनुभाग में जानकारी है कि मूल्यों को कैसे वापस किया जाना है। संक्षेप में, इस एपीआई में:

  • कार्य scalars लौटने या कोई मूल्य नहीं %eax का उपयोग करें;
  • फ्लोटिंग पॉइंट मान लौटने वाले फ़ंक्शन %st(0) का उपयोग करते हैं;
  • struct या union प्रकारों पर लौटने वाले कार्यों के लिए, कॉलर वापसी मूल्य के लिए स्थान प्रदान करता है और अपना पता छुपा, पहला तर्क के रूप में पास करता है। कैली इस पते को %eax में वापस कर देता है।
संबंधित मुद्दे