कॉल स्टैक
This article needs additional citations for verification. (September 2012) (Learn how and when to remove this template message) |
कंप्यूटर विज्ञान में, एक कॉल स्टैक एक स्टैक (अमूर्त डेटा प्रकार) डेटा संरचना है जो कंप्यूटर प्रोग्राम के सक्रिय उपनेमकाओं के बारे में जानकारी संग्रहीत करता है। इस तरह के स्टैक को निष्पादन स्टैक, प्रोग्राम स्टैक, कंट्रोल स्टैक, रन-टाइम स्टैक या मशीन स्टैक के रूप में भी जाना जाता है, और अक्सर इसे केवल स्टैक तक छोटा कर दिया जाता है। यद्यपि अधिकांश सॉफ़्टवेयर के समुचित कार्य के लिए कॉल स्टैक का रखरखाव महत्वपूर्ण है, विवरण आमतौर पर उच्च-स्तरीय प्रोग्रामिंग भाषाओं में छिपे और स्वचालित होते हैं। कई कंप्यूटर निर्देश सेट ढेर में हेरफेर करने के लिए विशेष निर्देश प्रदान करते हैं।
एक कॉल स्टैक का उपयोग कई संबंधित उद्देश्यों के लिए किया जाता है, लेकिन एक होने का मुख्य कारण उस बिंदु का ट्रैक रखना है जिस पर प्रत्येक सक्रिय सबरूटीन को निष्पादन पूरा होने पर नियंत्रण वापस करना चाहिए। एक सक्रिय उपनेमका वह है जिसे बुलाया गया है, लेकिन अभी तक निष्पादन पूरा नहीं हुआ है, जिसके बाद कॉल के बिंदु पर नियंत्रण वापस सौंप दिया जाना चाहिए। सबरूटीन्स की ऐसी सक्रियता किसी भी स्तर पर नेस्टेड हो सकती है (एक विशेष मामले के रूप में पुनरावर्ती), इसलिए स्टैक संरचना। उदाहरण के लिए, यदि कोई सबरूटीन DrawSquare
सबरूटीन कहता है DrawLine
चार अलग-अलग जगहों से DrawLine
पता होना चाहिए कि जब इसका निष्पादन पूरा हो जाए तो कहां लौटना है। इसे पूरा करने के लिए स्मृति पता को निर्देश (कंप्यूटर साइंस) के बाद जंप करता है DrawLine
, वापसी पता (कंप्यूटिंग), प्रत्येक कॉल के साथ कॉल स्टैक के शीर्ष पर धकेल दिया जाता है।
विवरण
चूंकि कॉल स्टैक को स्टैक (अमूर्त डेटा प्रकार) के रूप में व्यवस्थित किया जाता है, कॉलर रिटर्न एड्रेस को स्टैक पर धकेलता है, और सबरूटीन कहा जाता है, जब यह समाप्त हो जाता है, पॉप (कंप्यूटर प्रोग्रामिंग) कॉल स्टैक से वापसी पता और नियंत्रण स्थानांतरित करता है वह पता। यदि एक तथाकथित सबरूटीन किसी अन्य सबरूटीन पर कॉल करता है, तो यह कॉल स्टैक पर एक और रिटर्न एड्रेस को पुश करेगा, और इसी तरह, सूचना के स्टैकिंग और अनस्टैकिंग के साथ प्रोग्राम तय करता है। यदि पुशिंग कॉल स्टैक के लिए आवंटित सभी स्थान का उपभोग करता है, तो स्टैक ओवरफ़्लो नामक एक त्रुटि होती है, जो आम तौर पर प्रोग्राम को क्रैश (कंप्यूटिंग) कर देती है। कॉल स्टैक में सबरूटीन की प्रविष्टि को जोड़ना कभी-कभी वाइंडिंग कहलाता है; इसके विपरीत, प्रविष्टियों को हटाना अनवाइंडिंग है।
आमतौर पर एक रनिंग प्रोग्राम (या अधिक सटीक रूप से, प्रत्येक कार्य (कंप्यूटर) या एक प्रक्रिया (कंप्यूटिंग) के थ्रेड (कंप्यूटर विज्ञान) के साथ) से जुड़ा एक कॉल स्टैक होता है, हालांकि सिग्नल (कंप्यूटिंग) हैंडलिंग के लिए अतिरिक्त स्टैक बनाए जा सकते हैं या सहकारी मल्टीटास्किंग (setcontext के साथ)। चूंकि इस महत्वपूर्ण संदर्भ में केवल एक ही है, इसे स्टैक के रूप में संदर्भित किया जा सकता है (निहित रूप से, कार्य का); हालाँकि, [[चौथी प्रोग्रामिंग भाषा]] में डेटा स्टैक या पैरामीटर स्टैक को कॉल स्टैक की तुलना में अधिक स्पष्ट रूप से एक्सेस किया जाता है और इसे आमतौर पर स्टैक के रूप में संदर्भित किया जाता है (नीचे देखें)।
उच्च-स्तरीय प्रोग्रामिंग भाषाओं में, कॉल स्टैक की बारीकियां आमतौर पर प्रोग्रामर से छिपी होती हैं। उन्हें केवल कार्यों के एक सेट तक पहुंच दी जाती है, न कि ढेर पर स्मृति। यह मतिहीनता (कंप्यूटर विज्ञान) का एक उदाहरण है। दूसरी ओर, अधिकांश असेम्बली भाषाओं में स्टैक में हेरफेर करने के लिए प्रोग्रामर को शामिल करने की आवश्यकता होती है। प्रोग्रामिंग भाषा में स्टैक का वास्तविक विवरण संकलक, ऑपरेटिंग सिस्टम और उपलब्ध निर्देश सेट पर निर्भर करता है।
कॉल स्टैक के कार्य
जैसा ऊपर बताया गया है, कॉल स्टैक का प्राथमिक उद्देश्य रिटर्न पतों को स्टोर करना है। जब एक सबरूटीन को कॉल किया जाता है, तो निर्देश का स्थान (पता) जिस पर कॉलिंग रूटीन बाद में फिर से शुरू हो सकता है, उसे कहीं सेव करने की आवश्यकता होती है। रिटर्न एड्रेस को बचाने के लिए स्टैक का उपयोग करने से कुछ वैकल्पिक कॉलिंग सम्मेलनों पर महत्वपूर्ण फायदे होते हैं, जैसे कि कॉल किए गए सबरूटीन या किसी अन्य निश्चित स्थान की शुरुआत से पहले रिटर्न एड्रेस को सहेजना। एक यह है कि प्रत्येक कार्य का अपना ढेर हो सकता है, और इस प्रकार उपनेमका थ्रेड सुरक्षा हो सकती है। थ्रेड-सुरक्षित, यानी अलग-अलग कार्यों के लिए एक साथ सक्रिय हो सकती है। एक अन्य लाभ यह है कि पुनर्वित्त (कंप्यूटिंग) प्रदान करके, रिकर्सन (कंप्यूटर विज्ञान) स्वचालित रूप से समर्थित है। जब कोई फ़ंक्शन स्वयं को पुनरावर्ती रूप से कॉल करता है, तो फ़ंक्शन के प्रत्येक सक्रियण के लिए एक वापसी पता संग्रहीत करने की आवश्यकता होती है ताकि इसे बाद में फ़ंक्शन सक्रियण से वापस आने के लिए उपयोग किया जा सके। ढेर संरचनाएं स्वचालित रूप से यह क्षमता प्रदान करती हैं।
भाषा, ऑपरेटिंग सिस्टम और मशीन के वातावरण के आधार पर, कॉल स्टैक अतिरिक्त उद्देश्यों को पूरा कर सकता है, उदाहरण के लिए:
- स्थानीय डेटा भंडारण
- स्थानीय चर के मूल्यों को संग्रहीत करने के लिए एक सबरूटीन को अक्सर मेमोरी स्पेस की आवश्यकता होती है, चर जो केवल सक्रिय सबरूटीन के भीतर ही ज्ञात होते हैं और इसके वापस आने के बाद मूल्यों को बनाए नहीं रखते हैं। इस उपयोग के लिए स्थान आवंटित करना अक्सर सुविधाजनक होता है, बस स्टैक के शीर्ष को स्थान प्रदान करने के लिए पर्याप्त रूप से स्थानांतरित करके। गतिशील स्मृति आवंटन की तुलना में यह बहुत तेज है, जो हीप (प्रोग्रामिंग) का उपयोग करता है। ध्यान दें कि सबरूटीन के प्रत्येक अलग सक्रियण को स्थानीय लोगों के लिए स्टैक में अपना अलग स्थान मिलता है।
- पैरामीटर गुजर रहा है
- सबरूटीन्स के लिए अक्सर यह आवश्यक होता है कि पैरामीटर (कंप्यूटर साइंस) के मान उन्हें उस कोड द्वारा प्रदान किए जाएं जो उन्हें कॉल करता है, और यह असामान्य नहीं है कि कॉल स्टैक में इन पैरामीटरों के लिए स्थान निर्धारित किया जा सकता है। आम तौर पर यदि केवल कुछ छोटे पैरामीटर हैं, तो प्रोसेसर रजिस्टरों का उपयोग मूल्यों को पारित करने के लिए किया जाएगा, लेकिन यदि इस तरह से अधिक पैरामीटर हैं, तो स्मृति स्थान की आवश्यकता होगी। कॉल स्टैक इन मापदंडों के लिए एक जगह के रूप में अच्छी तरह से काम करता है, विशेष रूप से चूंकि प्रत्येक कॉल एक उपनेमका के लिए, जिसमें पैरामीटर के लिए अलग-अलग मान होंगे, उन मानों के लिए कॉल स्टैक पर अलग स्थान दिया जाएगा।
- मूल्यांकन ढेर
- अंकगणितीय या तार्किक संक्रियाओं के लिए संक्रियाएँ प्रायः रजिस्टरों में रखी जाती हैं और वहाँ पर संचालित की जाती हैं। हालाँकि, कुछ स्थितियों में ऑपरेंड को मनमाना गहराई तक ढेर किया जा सकता है, जिसका अर्थ है कि रजिस्टरों से अधिक कुछ का उपयोग किया जाना चाहिए (यह रजिस्टर आवंटन # स्पिलिंग का मामला है)। ऐसे ऑपरेंड के ढेर, बल्कि आरपीएन कैलकुलेटर में जैसे, मूल्यांकन स्टैक कहा जाता है, और कॉल स्टैक में जगह ले सकता है।
- सूचक (कंप्यूटर प्रोग्रामिंग) वर्तमान उदाहरण के लिए
- कुछ वस्तु उन्मुख भाषा (जैसे, C ++), इस (कंप्यूटर साइंस) को फंक्शन आर्ग्युमेंट्स के साथ कॉल स्टैक में स्टोर करते हैं, जब मेथड इनवोक करते हैं। यह पॉइंटर ऑब्जेक्ट (कंप्यूटर साइंस) इंस्टेंस (कंप्यूटर साइंस) की ओर इशारा करता है, जिसे लागू करने की विधि से जुड़ा है।
- उपनेमका संदर्भ संलग्न करना
- कुछ प्रोग्रामिंग लैंग्वेज (जैसे, पास्कल (प्रोग्रामिंग भाषा) और एडा (प्रोग्रामिंग लैंग्वेज)) नेस्टेड फ़ंक्शन की घोषणा का समर्थन करती हैं, जिन्हें उनके संलग्न रूटीन के संदर्भ तक पहुंचने की अनुमति है, यानी बाहरी के दायरे के भीतर पैरामीटर और स्थानीय चर दिनचर्या। इस तरह के स्थिर नेस्टिंग को दोहराया जा सकता है (एक फ़ंक्शन के भीतर घोषित एक फ़ंक्शन ...) कार्यान्वयन को एक साधन प्रदान करना चाहिए जिसके द्वारा किसी दिए गए स्थिर नेस्टिंग स्तर पर एक कॉल किया गया फ़ंक्शन प्रत्येक एनक्लोजिंग नेस्टिंग स्तर पर एन्क्लोजिंग फ्रेम को संदर्भित कर सकता है। आम तौर पर यह संदर्भ एक सूचक द्वारा संलग्न फ़ंक्शन के सबसे हाल ही में सक्रिय उदाहरण के फ्रेम के लिए कार्यान्वित किया जाता है, जिसे डाउनस्टैक लिंक या स्थिर लिंक कहा जाता है, इसे गतिशील लिंक से अलग करने के लिए जो तत्काल कॉलर को संदर्भित करता है (जो स्थिर नहीं होना चाहिए माता-पिता का कार्य)।
- एक स्थिर लिंक के बजाय, संलग्न स्थिर फ़्रेमों के संदर्भों को पॉइंटर्स की एक सरणी में एकत्रित किया जा सकता है जिसे डिस्प्ले के रूप में जाना जाता है जिसे वांछित फ्रेम का पता लगाने के लिए अनुक्रमित किया जाता है। रूटीन के लेक्सिकल नेस्टिंग की गहराई एक ज्ञात स्थिरांक है, इसलिए रूटीन के डिस्प्ले का आकार निश्चित है। साथ ही, ट्रैवर्स करने के लिए युक्त स्कोप की संख्या ज्ञात है, डिस्प्ले में इंडेक्स भी निश्चित है। आम तौर पर रूटीन का डिस्प्ले अपने स्वयं के स्टैक फ्रेम में स्थित होता है, लेकिन बरोज़ बड़े सिस्टम ने हार्डवेयर में ऐसे डिस्प्ले को लागू किया जो स्थिर नेस्टिंग के 32 स्तरों तक का समर्थन करता था।
- कॉल करने वाले के प्रदर्शन के उपयुक्त उपसर्ग से स्कोप युक्त प्रदर्शन प्रविष्टियाँ प्राप्त की जाती हैं। एक आंतरिक दिनचर्या जो पुनरावृत्ति करती है, प्रत्येक मंगलाचरण के लिए अलग-अलग कॉल फ्रेम बनाती है। इस मामले में, आंतरिक दिनचर्या के सभी स्थिर लिंक एक ही बाहरी नियमित संदर्भ की ओर इशारा करते हैं।
- अन्य वापसी राज्य
- रिटर्न एड्रेस के अलावा, कुछ वातावरणों में अन्य मशीन या सॉफ़्टवेयर स्टेट्स हो सकते हैं जिन्हें एक सबरूटीन के वापस आने पर पुनर्स्थापित करने की आवश्यकता होती है। इसमें विशेषाधिकार स्तर, अपवाद-हैंडलिंग जानकारी, अंकगणितीय मोड आदि जैसी चीज़ें शामिल हो सकती हैं। जरूरत पड़ने पर, इसे रिटर्न एड्रेस की तरह ही कॉल स्टैक में स्टोर किया जा सकता है।
विशिष्ट कॉल स्टैक का उपयोग रिटर्न एड्रेस, लोकल और पैरामीटर (कॉल फ्रेम के रूप में जाना जाता है) के लिए किया जाता है। कुछ वातावरणों में कॉल स्टैक को अधिक या कम कार्य सौंपे जा सकते हैं। फोर्थ (प्रोग्रामिंग भाषा) में, उदाहरण के लिए, आमतौर पर केवल रिटर्न एड्रेस, गिने हुए लूप पैरामीटर और इंडेक्स, और संभवतः स्थानीय चर कॉल स्टैक पर संग्रहीत होते हैं (जो उस वातावरण में रिटर्न स्टैक का नाम है), हालांकि कोई भी डेटा हो सकता है जब तक कॉल और रिटर्न की जरूरतों का सम्मान किया जाता है, तब तक विशेष रिटर्न-स्टैक हैंडलिंग कोड का उपयोग करके अस्थायी रूप से वहां रखा जाता है; पैरामीटर आमतौर पर एक अलग डेटा स्टैक या पैरामीटर स्टैक पर संग्रहीत होते हैं, आमतौर पर फोर्थ शब्दावली में स्टैक कहा जाता है, हालांकि कॉल स्टैक होता है क्योंकि इसे आमतौर पर अधिक स्पष्ट रूप से एक्सेस किया जाता है। कुछ फ़ोर्थ में तैरनेवाला स्थल पैरामीटर के लिए तीसरा स्टैक भी होता है।
संरचना
एक कॉल स्टैक स्टैक फ़्रेमों से बना होता है (जिसे एक्टिवेशन रिकॉर्ड या एक्टिवेशन फ़्रेम भी कहा जाता है)। ये मशीन पर निर्भर और अनुप्रयोग बाइनरी इंटरफ़ेस पर निर्भर डेटा संरचनाएँ हैं जिनमें सबरूटीन राज्य की जानकारी होती है। प्रत्येक स्टैक फ्रेम एक सबरूटीन के लिए एक कॉल से मेल खाता है जो अभी तक वापसी के साथ समाप्त नहीं हुआ है। उदाहरण के लिए, यदि एक सबरूटीन नाम दिया गया है DrawLine
वर्तमान में चल रहा है, एक उपनेमका द्वारा बुलाया गया है DrawSquare
, कॉल स्टैक के शीर्ष भाग को बगल के चित्र की तरह रखा जा सकता है।
इस तरह का आरेख किसी भी दिशा में तब तक खींचा जा सकता है जब तक कि शीर्ष की नियुक्ति, और इसलिए ढेर वृद्धि की दिशा समझी जाती है। इसके अलावा, इससे स्वतंत्र रूप से, आर्किटेक्चर भिन्न होते हैं कि क्या कॉल स्टैक उच्च पतों की ओर बढ़ता है या निम्न पतों की ओर। आरेख का तर्क संबोधित करने के विकल्प से स्वतंत्र है।
स्टैक के शीर्ष पर स्टैक फ्रेम वर्तमान में निष्पादित दिनचर्या के लिए है, जो किसी भी क्रम में अपने फ्रेम (जैसे पैरामीटर या स्थानीय चर) के भीतर जानकारी तक पहुंच सकता है।[1] स्टैक फ्रेम में आमतौर पर कम से कम निम्नलिखित आइटम शामिल होते हैं (पुश क्रम में):
- तर्क (पैरामीटर मान) रूटीन को पास किया गया (यदि कोई हो);
- रूटीन के कॉलर को वापसी का पता (उदाहरण के लिए
DrawLine
ढेर फ्रेम, में एक पताDrawSquare
का कोड); तथा - दिनचर्या के स्थानीय चर के लिए स्थान (यदि कोई हो)।
स्टैक और फ्रेम पॉइंटर्स
जब स्टैक फ्रेम आकार भिन्न हो सकते हैं, जैसे कि विभिन्न कार्यों के बीच या किसी विशेष फ़ंक्शन के इनवोकेशन के बीच, स्टैक से फ्रेम को पॉप करने से स्टैक पॉइंटर की निश्चित कमी नहीं होती है। फ़ंक्शन रिटर्न पर, स्टैक पॉइंटर को इसके बजाय फ़्रेम पॉइंटर में पुनर्स्थापित किया जाता है, फ़ंक्शन कॉल करने से ठीक पहले स्टैक पॉइंटर का मान। प्रत्येक स्टैक फ्रेम में तुरंत नीचे फ्रेम के शीर्ष पर एक स्टैक पॉइंटर होता है। स्टैक पॉइंटर एक म्यूटेबल रजिस्टर है जिसे सभी इनवोकेशन के बीच साझा किया जाता है। किसी फ़ंक्शन के दिए गए आमंत्रण का एक फ्रेम पॉइंटर स्टैक पॉइंटर की एक प्रति है जैसा कि फ़ंक्शन लागू होने से पहले था।[2] फ्रेम में अन्य सभी क्षेत्रों के स्थानों को या तो फ्रेम के शीर्ष के सापेक्ष परिभाषित किया जा सकता है, स्टैक पॉइंटर के नकारात्मक ऑफसेट के रूप में, या फ्रेम पॉइंटर के सकारात्मक ऑफसेट के रूप में नीचे फ्रेम के शीर्ष के सापेक्ष। फ़्रेम पॉइंटर का स्थान स्वाभाविक रूप से स्टैक पॉइंटर के नकारात्मक ऑफ़सेट के रूप में परिभाषित किया जाना चाहिए।
=== कॉलर के फ्रेम === में पता संग्रहीत करना
अधिकांश प्रणालियों में एक स्टैक फ्रेम में फ्रेम पॉइंटर रजिस्टर के पिछले मान को समाहित करने के लिए एक फ़ील्ड होता है, वह मान जो कॉलर के निष्पादन के दौरान था। उदाहरण के लिए, का ढेर फ्रेम DrawLine
फ्रेम पॉइंटर वैल्यू रखने वाली मेमोरी लोकेशन होगी DrawSquare
उपयोग (ऊपर चित्र में नहीं दिखाया गया है)। उपनेमका में प्रवेश पर मान सहेजा जाता है। स्टैक फ्रेम में एक ज्ञात स्थान में इस तरह के एक क्षेत्र होने से कोड को वर्तमान में निष्पादित रूटीन के फ्रेम के नीचे क्रमिक रूप से प्रत्येक फ्रेम तक पहुंचने में सक्षम बनाता है, और नियमित रूप से कॉल करने वाले के फ्रेम में फ्रेम पॉइंटर को आसानी से बहाल करने की अनुमति देता है, इससे पहले कि वह वापस आ जाए।
लेक्सिकली नेस्टेड रूटीन
नेस्टेड समारोह का समर्थन करने वाली प्रोग्रामिंग भाषाओं में कॉल फ्रेम में एक फ़ील्ड भी होता है जो उस प्रक्रिया के नवीनतम सक्रियण के स्टैक फ्रेम को इंगित करता है जो कैली को सबसे निकट से घेरता है, यानी कैली का तत्काल दायरा। इसे एक एक्सेस लिंक या स्टैटिक लिंक कहा जाता है (क्योंकि यह डायनेमिक और रिकर्सिव कॉल के दौरान स्टैटिक नेस्टिंग का ट्रैक रखता है) और रूटीन प्रदान करता है (साथ ही साथ कोई अन्य रूटीन जो इसे लागू कर सकता है) प्रत्येक नेस्टिंग पर इसके एनकैप्सुलेटिंग रूटीन के स्थानीय डेटा तक पहुंच प्रदान करता है। स्तर। कुछ आर्किटेक्चर, कंपाइलर, या ऑप्टिमाइज़ेशन मामले प्रत्येक संलग्न स्तर के लिए एक लिंक संग्रहीत करते हैं (न केवल तुरंत संलग्न), ताकि गहराई से नेस्टेड रूटीन जो उथले डेटा तक पहुँचते हैं, उन्हें कई लिंक पार करने की ज़रूरत नहीं है; इस रणनीति को अक्सर डिस्प्ले कहा जाता है।[3] एक्सेस लिंक को तब अनुकूलित किया जा सकता है जब कोई आंतरिक फ़ंक्शन एनकैप्सुलेशन में किसी भी (गैर-स्थिर) स्थानीय डेटा तक नहीं पहुंचता है, जैसा कि केवल तर्कों और वापसी मूल्यों के माध्यम से संचार करने वाले शुद्ध कार्यों के मामले में होता है, उदाहरण के लिए। कुछ ऐतिहासिक कंप्यूटर, जैसे कि इलेक्ट्रोलॉजिका X8 और कुछ समय बाद बरोज लार्ज सिस्टम में, नेस्टेड कार्यों का समर्थन करने के लिए विशेष डिस्प्ले रजिस्टर थे, जबकि अधिकांश आधुनिक मशीनों के लिए कंपाइलर (जैसे सर्वव्यापी x86) पॉइंटर्स के लिए स्टैक पर कुछ शब्द आरक्षित करते हैं। , जैसी जरूरत थी।
ओवरलैप
कुछ उद्देश्यों के लिए, एक सबरूटीन और उसके कॉलर के स्टैक फ्रेम को ओवरलैप माना जा सकता है, ओवरलैप में वह क्षेत्र होता है जहां कॉल करने वाले से कैली तक पैरामीटर पारित किए जाते हैं। कुछ वातावरणों में, कॉल करने वाला प्रत्येक तर्क को स्टैक पर धकेलता है, इस प्रकार इसके स्टैक फ्रेम को बढ़ाता है, फिर कैली को आमंत्रित करता है। अन्य वातावरणों में, कॉल करने वाले के पास अपने स्टैक फ्रेम के शीर्ष पर एक पूर्व-आवंटित क्षेत्र होता है, जो उन तर्कों को होल्ड करने के लिए होता है, जो वह अन्य सबरूटीन्स को कॉल करता है। इस क्षेत्र को कभी-कभी निवर्तमान तर्क क्षेत्र या कॉलआउट क्षेत्र कहा जाता है। इस दृष्टिकोण के तहत, क्षेत्र के आकार की गणना संकलक द्वारा की जाती है, जिसे किसी भी सबरूटीन के लिए सबसे बड़ी आवश्यकता होती है।
प्रयोग
कॉल साइट प्रोसेसिंग
आम तौर पर एक सबरूटीन को कॉल की साइट पर आवश्यक कॉल स्टैक मैनिपुलेशन न्यूनतम होता है (जो अच्छा है क्योंकि प्रत्येक सबरूटीन को कॉल करने के लिए कई कॉल साइट हो सकती हैं)। कॉल साइट पर वास्तविक तर्कों के मूल्यों का मूल्यांकन किया जाता है, क्योंकि वे विशेष कॉल के लिए विशिष्ट होते हैं, और या तो स्टैक पर धकेल दिए जाते हैं या रजिस्टरों में रखे जाते हैं, जैसा कि प्रयुक्त कॉलिंग सम्मेलन द्वारा निर्धारित किया जाता है। वास्तविक कॉल निर्देश, जैसे कि शाखा और लिंक, को आमतौर पर लक्ष्य उपनेमका के कोड पर नियंत्रण स्थानांतरित करने के लिए निष्पादित किया जाता है।
उपनेमका प्रविष्टि प्रसंस्करण
तथाकथित उपनेमका में, पहले निष्पादित कोड को आमतौर पर फ़ंक्शन प्रस्तावना कहा जाता है, क्योंकि यह दिनचर्या के बयानों के लिए कोड से पहले आवश्यक हाउसकीपिंग करता है।
इंस्ट्रक्शन सेट आर्किटेक्चर के लिए जिसमें एक सबरूटीन को कॉल करने के लिए उपयोग किया जाने वाला इंस्ट्रक्शन रिटर्न एड्रेस को स्टैक पर धकेलने के बजाय एक रजिस्टर में डालता है, प्रस्तावना आमतौर पर कॉल स्टैक पर वैल्यू को पुश करके रिटर्न एड्रेस को सेव करेगा, हालाँकि अगर कॉल किया जाता है उपनेमका किसी अन्य रूटीन को कॉल नहीं करता है, यह रजिस्टर में मूल्य छोड़ सकता है। इसी तरह, मौजूदा स्टैक पॉइंटर और/या फ्रेम पॉइंटर वैल्यू को पुश किया जा सकता है।
यदि फ्रेम पॉइंटर्स का उपयोग किया जा रहा है, तो प्रस्तावना आमतौर पर स्टैक पॉइंटर से फ्रेम पॉइंटर रजिस्टर का नया मान सेट करेगा। स्थानीय चर के लिए स्टैक पर स्थान तब स्टैक पॉइंटर को बढ़ाकर आवंटित किया जा सकता है।
द फोर्थ (प्रोग्रामिंग लैंग्वेज) कॉल स्टैक की स्पष्ट वाइंडिंग की अनुमति देता है (जिसे वहां रिटर्न स्टैक कहा जाता है)।
रिटर्न प्रोसेसिंग
जब एक सबरूटीन वापस जाने के लिए तैयार होता है, तो यह एक उपसंहार को क्रियान्वित करता है जो प्रस्तावना के चरणों को पूर्ववत करता है। यह आम तौर पर स्टैक फ्रेम से सहेजे गए रजिस्टर वैल्यू (जैसे फ्रेम पॉइंटर वैल्यू) को पुनर्स्थापित करेगा, स्टैक पॉइंटर वैल्यू को बदलकर स्टैक से पूरे स्टैक फ्रेम को पॉप करेगा, और अंत में वापसी पते पर निर्देश को ब्रांच करेगा। कई कॉलिंग सम्मेलनों के तहत उपसंहार द्वारा स्टैक से पॉप किए गए आइटम में मूल तर्क मान शामिल होते हैं, इस मामले में आमतौर पर कोई और स्टैक जोड़तोड़ नहीं होता है जिसे कॉलर द्वारा करने की आवश्यकता होती है। कुछ कॉलिंग सम्मेलनों के साथ, हालांकि, रिटर्न के बाद स्टैक से तर्कों को हटाने के लिए कॉल करने वाले की ज़िम्मेदारी है।
खोलना
बुलाए गए फ़ंक्शन से लौटने से स्टैक से शीर्ष फ्रेम पॉप हो जाएगा, शायद रिटर्न वैल्यू छोड़कर। कार्यक्रम में कहीं और निष्पादन को फिर से शुरू करने के लिए स्टैक से एक या एक से अधिक फ़्रेमों को पॉप करने के अधिक सामान्य कार्य को स्टैक अनवाइंडिंग कहा जाता है और इसे तब किया जाना चाहिए जब गैर-स्थानीय नियंत्रण संरचनाओं का उपयोग किया जाता है, जैसे कि सॉफ्टवेयर में अपवाद हैंडलिंग # अपवाद हैंडलिंग के लिए उपयोग किया जाता है। इस स्थिति में, किसी फ़ंक्शन के स्टैक फ़्रेम में एक या अधिक प्रविष्टियाँ होती हैं जो अपवाद संचालकों को निर्दिष्ट करती हैं। जब एक अपवाद को फेंका जाता है, तो स्टैक तब तक खुला रहता है जब तक कि एक हैंडलर नहीं मिल जाता है जो फेंके गए अपवाद के प्रकार को संभालने (पकड़ने) के लिए तैयार होता है।
कुछ भाषाओं में अन्य नियंत्रण संरचनाएँ होती हैं जिनके लिए सामान्य अनइंडिंग की आवश्यकता होती है। पास्कल प्रोग्रामिंग भाषा वैश्विक के लिए जाओ स्टेटमेंट को नेस्टेड फ़ंक्शन से बाहर और पहले से लागू बाहरी फ़ंक्शन में नियंत्रण स्थानांतरित करने की अनुमति देती है। इस ऑपरेशन के लिए स्टैक को खोलने की आवश्यकता होती है, संलग्न बाहरी फ़ंक्शन के भीतर लक्ष्य कथन पर नियंत्रण स्थानांतरित करने के लिए उचित संदर्भ को पुनर्स्थापित करने के लिए आवश्यक कई स्टैक फ्रेम को हटा दें। इसी प्रकार, C के पास setjmp.h| हैsetjmp
तथा longjmp
ऐसे कार्य जो गैर-स्थानीय गोटो के रूप में कार्य करते हैं। सामान्य लिस्प नियंत्रण की अनुमति देता है कि क्या होता है जब स्टैक का उपयोग करके खोल दिया जाता है unwind-protect
विशेष संचालिका।
निरंतरता लागू करते समय, स्टैक (तार्किक रूप से) अनवाउंड होता है और फिर निरंतरता के स्टैक के साथ रिवाउंड होता है। निरंतरता लागू करने का यही एकमात्र तरीका नहीं है; उदाहरण के लिए, एकाधिक, स्पष्ट स्टैक का उपयोग करके, एक निरंतरता का अनुप्रयोग बस इसके स्टैक को सक्रिय कर सकता है और पारित होने के लिए मान को हवा दे सकता है। स्कीम (प्रोग्रामिंग लैंग्वेज) मनमाना थंक (कार्यात्मक प्रोग्रामिंग) को निर्दिष्ट बिंदुओं पर निष्पादित करने की अनुमति देती है, जब एक निरंतरता लागू की जाती है, तो कंट्रोल स्टैक को खोलना या रिवाइंड करना।
निरीक्षण
प्रोग्राम चलने के दौरान कभी-कभी कॉल स्टैक का निरीक्षण किया जा सकता है। प्रोग्राम कैसे लिखा और संकलित किया जाता है, इसके आधार पर, स्टैक पर जानकारी का उपयोग मध्यवर्ती मान और फ़ंक्शन कॉल ट्रेस निर्धारित करने के लिए किया जा सकता है। इसका उपयोग ठीक-ठाक स्वचालित परीक्षण उत्पन्न करने के लिए किया गया है,[4] और रूबी और स्मॉलटाक जैसे मामलों में, प्रथम श्रेणी की निरंतरता को लागू करने के लिए। एक उदाहरण के रूप में, जीएनयू डीबगर (जीडीबी) चल रहे, लेकिन रुके हुए, सी प्रोग्राम के कॉल स्टैक के इंटरैक्टिव निरीक्षण को लागू करता है।[5] कॉल स्टैक के नियमित-समय के नमूने लेना कार्यक्रमों के प्रदर्शन की रूपरेखा तैयार करने में उपयोगी हो सकता है, क्योंकि यदि एक सबरूटीन का सूचक कॉल स्टैक नमूनाकरण डेटा पर कई बार दिखाई देता है, तो यह संभवतः एक कोड अड़चन है और प्रदर्शन समस्याओं के लिए इसका निरीक्षण किया जाना चाहिए।
सुरक्षा
फ्री पॉइंटर्स या नॉन-चेक्ड ऐरे राइट्स (जैसे सी में) वाली भाषा में, कंट्रोल फ्लो डेटा का मिश्रण जो कोड के निष्पादन को प्रभावित करता है (रिटर्न एड्रेस या सेव्ड फ्रेम पॉइंटर्स) और सिंपल प्रोग्राम डेटा (पैरामीटर या रिटर्न वैल्यू) ) कॉल स्टैक में एक सुरक्षा जोखिम है, संभवतः ढेर बफर अतिप्रवाह के माध्यम से बफ़र अधिकता के सबसे सामान्य प्रकार के रूप में शोषण (कंप्यूटर सुरक्षा)।
इस तरह के हमलों में से एक में मनमाने ढंग से निष्पादन योग्य कोड के साथ एक बफर भरना शामिल है, और फिर उसी या कुछ अन्य बफर को एक मान के साथ कुछ वापसी पते को ओवरराइट करने के लिए बहता है जो सीधे निष्पादन योग्य कोड को इंगित करता है। परिणामस्वरूप, जब फ़ंक्शन वापस आता है, तो कंप्यूटर उस कोड को निष्पादित करता है। इस तरह के हमले को W^X से आसानी से रोका जा सकता है।[citation needed] इसी तरह के हमले W^X सुरक्षा सक्षम होने पर भी सफल हो सकते हैं, जिसमें रिटर्न-टू-लिबक हमला या वापसी-उन्मुख प्रोग्रामिंग से आने वाले हमले शामिल हैं। विभिन्न शमन प्रस्तावित किए गए हैं, जैसे कि सरणी को रिटर्न स्टैक से पूरी तरह से अलग स्थान पर संग्रहीत करना, जैसा कि फोर्थ प्रोग्रामिंग भाषा में मामला है।[6]
यह भी देखें
संदर्भ
- ↑ Krzyzanowski, Paul (February 16, 2018). "स्टैक फ्रेम". Rutgers University. Archived from the original on 2021-08-28. Retrieved December 19, 2021.
- ↑ "ढेर को समझना". cs.umd.edu. 2003-06-22. Archived from the original on 2013-02-25. Retrieved 2014-05-21.
- ↑ Alternative Microprocessor Design
- ↑ McMaster, S.; Memon, A. (2006). जीयूआई टेस्ट-सूट कटौती के लिए कॉल स्टैक कवरेज (PDF). 17th International Symposium on Software Reliability Engineering (ISSRE '06). pp. 33–44. CiteSeerX 10.1.1.88.873. doi:10.1109/ISSRE.2006.19. ISBN 0-7695-2684-5.
- ↑ "जीडीबी के साथ डिबगिंग: स्टैक की जांच करना". chemie.fu-berlin.de. 1997-10-17. Retrieved 2014-12-16.
- ↑ Doug Hoyte. "The Forth Programming Language - Why YOU should learn it".
अग्रिम पठन
- Dijkstra, E. W. (1960). "Recursive Programming". Numerische Mathematik. 2 (1): 312–318. doi:10.1007/BF01386232.
- Wilson, P. R.; Johnstone, M. S.; Neely, M.; Boles, D. (1995). "Dynamic storage allocation: A survey and critical review". Memory Management. Lecture Notes in Computer Science. Vol. 986. pp. 1–116. CiteSeerX 10.1.1.47.275. doi:10.1007/3-540-60368-9_19. ISBN 978-3-540-60368-9.
- "2.4. The Stack". MCS-4 Assembly Language Programming Manual - The INTELLEC 4 Microcomputer System Programming Manual (PDF) (Preliminary ed.). Santa Clara, California, USA: Intel Corporation. December 1973. pp. 2-7–2-8. MCS-030-1273-1. Archived (PDF) from the original on 2020-03-01. Retrieved 2020-03-02. (NB. Intel's 4-bit processor 4004 implements an internal stack rather than an in-memory stack.)
इस पेज में लापता आंतरिक लिंक की सूची
- उच्च स्तरीय प्रोग्रामिंग भाषा
- निर्देश समुच्चय
- ढेर (सार डेटा प्रकार)
- निर्देश (कंप्यूटर विज्ञान)
- वापसी का पता (कंप्यूटिंग)
- सभा की भाषा
- धागा (कंप्यूटर विज्ञान)
- टास्क (कंप्यूटर)
- कॉलिंग कन्वेंशन
- पुनः प्रवेश (कम्प्यूटिंग)
- धागा सुरक्षा
- पैरामीटर (कंप्यूटर विज्ञान)
- सी ++
- वस्तु (कंप्यूटर विज्ञान)
- एडा (प्रोग्रामिंग भाषा)
- उदाहरण (कंप्यूटर विज्ञान)
- बरोज़ लार्ज सिस्टम्स
- समारोह प्रस्तावना
- योजना (प्रोग्रामिंग भाषा)
- विस्तार
बाहरी संबंध
- Function Calling and Frame Pointer Operations in 68000 Archived 2010-07-24 at the Wayback Machine
- The libunwind project - a platform-independent unwind API