2012-02-12 10 views
8

http://en.wikipedia.org/wiki/Stack_pointer#Structureरिटर्न पते की तुलना में कॉल स्टैक पर पहले फ़ंक्शन पैरामीटर क्यों धक्का दिए गए हैं?

enter image description here

से मैं क्यों एक समारोह के लिए वापसी पता है कि समारोह के लिए मानकों से ऊपर रखा गया है सोच रहा हूँ?

इसे और अधिक समझ में आता है वापसी पता Drawline के लिए ढेर पर धकेल दिया इससे पहले कि पैरामीटर क्योंकि मापदंडों किसी भी अधिक की आवश्यकता नहीं है जब वापसी पता बुला कार्य करने के लिए वापस लौटने के लिए पॉप है है।

उपरोक्त आरेख में दिखाए गए कार्यान्वयन को प्राथमिकता देने के कारण क्या हैं?

+3

कृपया जान लें कि यह व्यवस्था ** + ** सी ++ मानक का हिस्सा नहीं है। यह एक व्यक्तिगत सीपीयू, कंपाइलर, और/या ऑपरेटिंग वातावरण के लिए विशिष्ट है। उस आलेख में वर्णित स्थिति सामान्य है, और जीसीसी/एक्स 86 के लिए सटीक है, लेकिन इसका कोई मतलब सार्वभौमिक नहीं है। –

+0

दोनों पैरामीटर और स्थानीय लोगों की संख्या तय नहीं की जा सकती है। अगर वापसी का पता मध्य में नहीं था तो आप सभी 3 का पता कैसे निर्धारित कर सकते हैं? – Pubby

+0

@ पब्बी: मेरे पास जवाब नहीं है, लेकिन यह स्थिति ** DrawSquare ** के ** लोकल ** और ** DrawLine ** के पैरामीटर के साथ भी हो रही है। – Lazer

उत्तर

5

वापसी पता आमतौर पर call मशीन कमांड के माध्यम से धकेल दिया जाता है, [जो मूल भाषा के instruction set] में होता है जबकि पैरामीटर और चर कई मशीन कमांड के साथ धकेलते हैं - जो संकलक बनाता है।

इस प्रकार, वापसी पता कॉलर द्वारा धक्का दिया गया अंतिम सामान है, और कैली द्वारा धक्का दिया गया कुछ भी [स्थानीय चर] से पहले।

पैरामीटर सभी को वापसी पते से पहले धक्का दिया जाता है, क्योंकि वास्तविक फ़ंक्शन पर कूद और स्टैक पर वापसी पते का सम्मिलन उसी मशीन कमांड में किया जाता है।

इसके अलावा, एक अन्य कारण यह है कि कॉलर पैरामीटर के लिए ढेर पर एक आवंटित स्थान है - यह [कॉलर] भी इसे साफ़ करने वाला व्यक्ति होना चाहिए।

+0

"यह [कॉलर] भी वह व्यक्ति होना चाहिए जो इसे साफ़ करता है।" - असल में, लगभग किसी भी कॉलिंग कन्वेंशन में जो वैरैडिक पैरामीटर (जैसे 'stdcall') का समर्थन नहीं करता है, सफाई जिम्मेदारी निष्पादन योग्य आकार को कम करने के लिए कैली तक है (सफाई के लिए कोड केवल फ़ंक्शन के अंत में लिखा जाता है प्रत्येक फंक्शन कॉल के लिए एक बार)। –

1

कारण सरल है: फ़ंक्शन तर्क कॉलिंग फ़ंक्शन द्वारा स्टैक पर धकेल दिए जाते हैं (जो केवल ऐसा ही कर सकता है क्योंकि केवल इसकी आवश्यक जानकारी हो; ऐसा करने के पूरे बिंदु के बाद पास करना है बुलाया समारोह के लिए वह जानकारी)। रिटर्न पता फ़ंक्शन कॉल मैकेनिज्म द्वारा स्टैक पर धक्का दिया जाता है। के बाद फ़ंक्शन को कहा जाता है, कॉलिंग फ़ंक्शन ने पैरामीटर सेट अप किए हैं, क्योंकि कॉल के बाद यह निष्पादित फ़ंक्शन है जिसे कॉल किया जाता है, कॉलिंग नहीं।

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

यह भी ध्यान दें कि यह पैरामीटर को साफ करने के सवाल से स्वतंत्र है। सिद्धांत रूप में, बुलाया गया फ़ंक्शन तर्क के कॉल विनाशकों को कॉल कर सकता है भले ही शारीरिक रूप से वे कॉलर के स्टैक फ्रेम में हों।इसके अलावा, कई प्रोसेसर (x86 सहित) में निर्देश होते हैं जो रिटर्न पर रिटर्न पते के ऊपर स्वचालित रूप से अतिरिक्त स्थान पॉप करते हैं (उदाहरण के लिए, पास्कल कंपाइलर्स आमतौर पर ऐसा करते हैं क्योंकि पास्कल में आपके पास स्मृति लौटने से परे कोई क्लीनअप नहीं होता है, और कम से कम fr उस समय के प्रोसेसर, प्रोसेसर निर्देश के साथ इसे साफ करने के लिए और अधिक कुशल था (मुझे नहीं पता कि यह आधुनिक प्रोसेसर के लिए अभी भी सही है)। हालांकि सी ने परिवर्तनीय-लंबाई तर्क सूचियों के कारण उस तंत्र का उपयोग नहीं किया: उन लोगों के लिए, तंत्र लागू नहीं था क्योंकि आपको संकलन समय पर कितनी अतिरिक्त जगह रिलीज करने की आवश्यकता होगी, और के & आरसी को विविधता कार्यों को आगे बढ़ाने की आवश्यकता नहीं थी (सी 8 9 करता है, लेकिन कुछ अगर किसी भी कंपाइलर्स इसका लाभ उठाते हैं, पुराने कोड के साथ संगतता के कारण), इसलिए कॉलिंग फ़ंक्शन को यह जानने का कोई तरीका नहीं था कि तर्कों को साफ करना है या नहीं, जब तक कि उसे हमेशा ऐसा न करना पड़े।