C / C ++ में फ़ंक्शन कॉल के स्टैक फ्रेम को समझना?


19

मैं यह समझने की कोशिश कर रहा हूं कि स्टैक फ्रेम कैसे बनाए जाते हैं और कौन से चर (परम) को किस क्रम में स्टैक करने के लिए धकेल दिया जाता है? कुछ खोज परिणामों से पता चला कि C / C ++ कंपाइलर एक फ़ंक्शन के भीतर किए गए ऑपरेशनों के आधार पर निर्णय लेता है। उदाहरण के लिए, यदि फ़ंक्शन को केवल 1 द्वारा पारित मान में इंट्रोड्यूस करना था (++ ऑपरेटर के समान) और इसे वापस करना है, तो यह फ़ंक्शन के सभी मापदंडों और स्थानीय चर को रजिस्टरों में डाल देगा।

मैं सोच रहा हूं कि कौन से रजिस्टर लौटाए जाते हैं या वैल्यू पैरामीटर्स से पास होते हैं। संदर्भ कैसे लौटाए जाते हैं? कंपाइलर ईएक्स, ईबेक्स, ईएक्सएक्स और एडएक्स के बीच कैसे चुनता है?

फ़ंक्शन कॉल के दौरान रजिस्टरों, स्टैक और हीप संदर्भों का उपयोग, निर्माण और नष्ट होने के तरीके को समझने के लिए मुझे क्या जानने की आवश्यकता है?


यह पढ़ना कठिन है (पाठ की दीवार)। क्या आप अपने पोस्ट को बेहतर आकार में संपादित करना चाहेंगे ?
gnat

1
यह प्रश्न मुझे व्यापक लगता है। इसके अलावा, क्या यह बहुत ही प्लेटफॉर्म-विशिष्ट नहीं है?
काज़ार्क

SO पर भी प्रश्न पूछा गया: stackoverflow.com/questions/16088040/…
वेन कॉनराड

जवाबों:


11

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

इसलिए, फ़ंक्शन A से किसी फ़ंक्शन "B" को सामान्य "सामान्य" सिस्टम पर कॉल करने से निम्नलिखित चरण शामिल हो सकते हैं:

  • फ़ंक्शन A:
    • वापसी मूल्य के लिए जगह धक्का
    • धक्का मापदंडों
    • रिटर्न एड्रेस को पुश करें
  • समारोह में कूदो बी
  • समारोह बी:
    • पिछले स्टैक फ्रेम के पते को धक्का दें
    • रजिस्टरों के पुश मान जो इस फ़ंक्शन का उपयोग करते हैं (ताकि उन्हें पुनर्स्थापित किया जा सके)
    • स्थानीय चर के लिए स्थान धक्का
    • आवश्यक गणना करें
    • रजिस्टर को पुनर्स्थापित करें
    • पिछले स्टैक फ्रेम को पुनर्स्थापित करें
    • फ़ंक्शन परिणाम संग्रहीत करें
    • वापसी पते पर जाएं
  • फ़ंक्शन A:
    • मापदंडों पॉप
    • वापसी मूल्य पॉप

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


"पुश" का यहां वास्तव में क्या मतलब है? मुझे नहीं पता कि इसका क्या बनाना है।
टॉम ज़ातो -

2
@ TomášZato pushऔर popएक स्टैक पर दो मौलिक संचालन हैं। एक स्टैक किताबों के ढेर की तरह एक अंतिम-इन-पहली संरचना है। जब आप push, आप ढेर के ऊपर एक नई वस्तु डाल रहे हैं; जब आप popस्टैक के ऊपर से कोई ऑब्जेक्ट ले रहे हों। आपको ऑब्जेक्ट्स को बीच में डालने या निकालने की अनुमति नहीं है, आप केवल स्टैक के शीर्ष पर काम कर सकते हैं। आप आमतौर पर ढेर के बारे में अधिक पढ़ सकते हैं और विशेष रूप से विकिपीडिया पर कार्यक्रम को ढेर कर सकते हैं
कालेब

11

यह उपयोग किए जा रहे कॉलिंग कन्वेंशन पर निर्भर करता है। जो भी बुलाए गए सम्मेलन को परिभाषित करता है वह यह निर्णय ले सकता है लेकिन वे चाहते हैं।

X86 पर सबसे आम कॉलिंग कन्वेंशन में, रजिस्टरों को मापदंडों को पारित करने के लिए उपयोग नहीं किया जाता है; मापदंडों को सबसे अच्छे पैरामीटर से शुरू होने वाले स्टैक पर धकेल दिया जाता है। रिटर्न वैल्यू को eax में रखा गया है और अगर अतिरिक्त जगह की जरूरत है तो edx का उपयोग कर सकते हैं। संदर्भ और संकेत, दोनों को एक पते के रूप में eax में लौटाया गया है।


5

यदि आप स्टैक को बहुत अच्छी तरह से समझते हैं तो आप समझेंगे कि मेमोरी प्रोग्राम में कैसे काम करती है और यदि आप समझते हैं कि प्रोग्राम में मेमोरी कैसे काम करती है तो आप समझ पाएंगे कि प्रोग्राम में कैसे स्टोर होता है और यदि आप समझते हैं कि प्रोग्राम में फ़ंक्शन स्टोर कैसे होता है तो आप समझ पाएंगे कि रिकर्सिव फ़ंक्शन कैसे काम करता है और यदि आप समझते हैं कि पुनरावर्ती कार्य कैसे काम करता है आप समझेंगे कि संकलक कैसे काम करता है और यदि आप समझते हैं कि संकलक कैसे काम करता है तो आपका दिमाग संकलक के रूप में काम करेगा और आप किसी भी कार्यक्रम को बहुत आसानी से डीबग करेंगे

मुझे बताएं कि स्टैक कैसे काम करता है:

सबसे पहले आपको यह जानना होगा कि स्टैक में फ़ंक्शन स्टोर कैसे किया जाता है:

हीप स्टोर डायनेमिक मेमोरी एलोकेशन वैल्यू। स्टैक स्टोर स्वचालित आवंटन और विलोपन मान।

यहाँ छवि विवरण दर्ज करें

आइए उदाहरण के साथ समझते हैं:

def hello(x):
    if x==1:
        return "op"
    else:
        u=1
        e=12
        s=hello(x-1)
        e+=1
        print(s)
        print(x)
        u+=1
    return e

hello(4)

अब इस कार्यक्रम के कुछ हिस्सों को समझें:

यहाँ छवि विवरण दर्ज करें

अब देखते हैं कि स्टैक क्या है और स्टैक पार्ट्स क्या हैं:

यहाँ छवि विवरण दर्ज करें

स्टैक का आवंटन:

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

यहाँ छवि विवरण दर्ज करें

ब्लॉक का निपटान:

इसलिए अब जब भी कोई फ़ंक्शन रिटर्न स्टेटमेंट पाता है तो वह स्टैक से करंट फ्रेम को हटा देता है।

स्टैक वैल्यू से लौटते समय रिवर्स ऑर्डर ऑफ ऑर्डर में वापस आ जाएगा जिसमें उन्हें स्टैक में आवंटित किया गया था।

यहाँ छवि विवरण दर्ज करें

ये बहुत ही संक्षिप्त विवरण हैं और यदि आप स्टैक के बारे में और अधिक गहराई से जानना चाहते हैं और इस ब्लॉग की दो पोस्ट पढ़ते हैं:

स्टेप स्टेप बाय स्टेप के बारे में अधिक

स्टैक के साथ कदम से दुगुनी पुनरावृत्ति के बारे में अधिक


3

आप जिस चीज की तलाश कर रहे हैं उसे एप्लीकेशन बाइनरी इंटरफेस - ABI कहा जाता है ।

प्रत्येक कंपाइलर के लिए एक विनिर्देश है जो एबीआई को मंत्र देता है।

प्रत्येक प्लेटफ़ॉर्म आमतौर पर और एबीआई को संकलक के बीच अंतर को समर्थन देने के लिए निर्दिष्ट करेगा। उदाहरण के लिए, x86 कॉलिंग कन्वेंशन x86 और x86-64 के लिए विशिष्ट कॉलिंग कन्वेंशन को मंत्र देते हैं। मैं हालांकि विकिपीडिया की तुलना में अधिक आधिकारिक दस्तावेज की उम्मीद करूंगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.