यह सभी इंटेल प्लेटफार्मों पर बीपी / ईबीपी / आरबीपी रजिस्टर के बारे में है। स्टैक सेगमेंट के लिए यह रजिस्टर डिफॉल्ट करता है (स्टैक सेगमेंट तक पहुंचने के लिए एक विशेष उपसर्ग की आवश्यकता नहीं है)।
ईबीपी स्टैक के भीतर डेटा संरचनाओं, चर और गतिशील रूप से आवंटित कार्य स्थान तक पहुंचने के लिए रजिस्टर का सबसे अच्छा विकल्प है। ईबीपी का उपयोग अक्सर वर्तमान टीओएस के सापेक्ष स्टैक पर एक निश्चित बिंदु के सापेक्ष स्टैक पर तत्वों तक पहुंचने के लिए किया जाता है। यह आमतौर पर वर्तमान प्रक्रिया के लिए स्थापित वर्तमान स्टैक फ्रेम के आधार पते की पहचान करता है। जब EBP का उपयोग ऑफसेट गणना में आधार रजिस्टर के रूप में किया जाता है, तो ऑफसेट की गणना वर्तमान स्टैक सेगमेंट (अर्थात, वर्तमान में एसएस द्वारा चयनित खंड) में की जाती है। क्योंकि एसएस को स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता नहीं है, ऐसे मामलों में निर्देश एन्कोडिंग अधिक कुशल है। EBP का उपयोग अन्य सेगमेंट रजिस्टरों के माध्यम से पता लगाने वाले खंडों में अनुक्रमित करने के लिए भी किया जा सकता है।
(स्रोत - http://css.csail.mit.edu/6.858/2017/readings/i386/s02_03.htm )
चूंकि अधिकांश 32-बिट प्लेटफॉर्म पर, डेटा सेगमेंट और स्टैक सेगमेंट समान हैं, इसलिए स्टैक के साथ EBP / RBP का यह जुड़ाव अब कोई समस्या नहीं है। तो 64-बिट प्लेटफार्मों पर है: 2003 में AMD द्वारा प्रस्तुत x86-64 आर्किटेक्चर, ने 64-बिट मोड में विभाजन के लिए समर्थन को काफी हद तक गिरा दिया है: खंड के चार रजिस्टर: CS, SS, DS और ES को 0 पर मजबूर किया जाता है। । X86 32-बिट और 64-बिट प्लेटफ़ॉर्म की इन परिस्थितियों का अनिवार्य रूप से मतलब है कि ईबीपी / आरबीपी रजिस्टर का उपयोग मेमोरी को एक्सेस करने वाले प्रोसेसर निर्देशों में बिना किसी उपसर्ग के किया जा सकता है।
तो आपके द्वारा लिखा गया संकलक विकल्प बीपी / ईबीपी / आरबीपी को अन्य साधनों के लिए उपयोग करने की अनुमति देता है, जैसे कि स्थानीय चर।
"यह फ्रेम पॉइंटर्स को बचाने, सेट करने और पुनर्स्थापित करने के निर्देशों से बचा जाता है" का अर्थ प्रत्येक फ़ंक्शन के प्रवेश पर निम्नलिखित कोड से बचने से है:
push ebp
mov ebp, esp
या enter
अनुदेश, जो इंटेल 80286 और 80386 प्रोसेसर पर बहुत उपयोगी था।
फ़ंक्शन वापसी से पहले, निम्न कोड का उपयोग किया जाता है:
mov esp, ebp
pop ebp
या leave
निर्देश।
डिबगिंग टूल स्टैक डेटा को स्कैन कर सकते हैं और लोकेट करते समय इन पुश किए गए ईबीपी रजिस्टर डेटा का उपयोग कर सकते हैं call sites
, अर्थात फ़ंक्शन के नाम और उन्हें क्रमबद्ध रूप से बुलाया जाने वाले तर्कों को प्रदर्शित करने के लिए।
प्रोग्रामर में स्टैक फ्रेम के बारे में प्रश्न हो सकते हैं, एक व्यापक शब्द में नहीं है (यह स्टैक में एक एकल इकाई है जो केवल एक फ़ंक्शन कॉल प्रदान करता है और रिटर्न पता, तर्क और स्थानीय चर) रखता है लेकिन एक संकीर्ण अर्थ में - जब शब्द stack frames
में उल्लेख किया गया है संकलक विकल्पों का संदर्भ। संकलक के दृष्टिकोण से, एक स्टैक फ्रेम रूटीन के लिए केवल प्रविष्टि और निकास कोड है , जो स्टैक के लिए एक लंगर को धक्का देता है - जिसका उपयोग डिबगिंग के लिए और अपवाद हैंडलिंग के लिए भी किया जा सकता है। डिबगिंग टूल स्टैक डेटा को स्कैन कर सकते हैं और इन एंकरों का उपयोग बैक-ट्रेसिंग के लिए कर सकते हैं, जबकि call sites
स्टैक में पता लगाने के लिए, अर्थात उन्हें फंक्शन के नाम प्रदर्शित करने के लिए, जिसे उन्हें पदानुक्रम कहा गया है।
इसलिए प्रोग्रामर के लिए यह समझना बहुत महत्वपूर्ण है कि कंपाइलर विकल्पों के संदर्भ में स्टैक फ्रेम क्या है - क्योंकि कंपाइलर इस कोड को जेनरेट करने के लिए नियंत्रित कर सकता है या नहीं।
कुछ मामलों में, स्टैक फ्रेम (रूटीन के लिए प्रवेश और निकास कोड) को कंपाइलर द्वारा छोड़ा जा सकता है, और चर को सीधे आधार पॉइंटर (बीपी /) के बजाय स्टैक पॉइंटर (एसपी / ईएसपी / आरएसपी) के माध्यम से एक्सेस किया जाएगा। ईएसपी / आरएसपी)। एक कंपाइलर के लिए कुछ कार्यों के लिए स्टैक फ़्रेम को छोड़ना अलग हो सकता है, उदाहरण के लिए: (1) फ़ंक्शन एक पत्ती फ़ंक्शन है (यानी एक अंत-इकाई जो अन्य कार्यों को कॉल नहीं करती है); (2) कोई अपवाद उपयोग नहीं किया जाता है; (3) स्टैक पर आउटगोइंग मापदंडों के साथ कोई रूटीन नहीं कहा जाता है; (4) फ़ंक्शन का कोई पैरामीटर नहीं है।
स्टैक फ्रेम (नियमित के लिए प्रवेश और निकास कोड) को कोड को छोटा और तेज बनाया जा सकता है, लेकिन स्टैक में डेटा को वापस ट्रेस करने और प्रोग्रामर को प्रदर्शित करने की डिबगर्स की क्षमता को नकारात्मक रूप से प्रभावित कर सकता है। ये संकलक विकल्प हैं जो निर्धारित करते हैं कि किन परिस्थितियों में एक फ़ंक्शन को संकलक को स्टैक फ्रेम प्रविष्टि और निकास कोड के साथ पुरस्कृत करने के लिए संतुष्ट करना चाहिए। उदाहरण के लिए, एक कंपाइलर के पास निम्न मामलों में कार्यों के लिए इस तरह के प्रवेश और निकास कोड को जोड़ने के विकल्प हो सकते हैं: (ए) हमेशा, (बी) कभी नहीं, (सी) जब आवश्यक हो (शर्तों को निर्दिष्ट करते हुए)।
सामान्यताओं से वापस विशिष्टताओं पर लौटना: यदि आप -fomit-frame-pointer
जीसीसी संकलक विकल्प का उपयोग करेंगे , तो आप रूटीन के लिए प्रवेश और निकास कोड दोनों पर जीत सकते हैं, और एक अतिरिक्त रजिस्टर होने पर (जब तक कि यह पहले से ही डिफ़ॉल्ट रूप से चालू न हो या दूसरे के साथ निहित हो) विकल्प, इस मामले में, आप पहले से ही ईबीपी / आरबीपी रजिस्टर का उपयोग करने के लाभ से लाभान्वित हो रहे हैं और इस विकल्प को स्पष्ट रूप से निर्दिष्ट करके कोई अतिरिक्त लाभ प्राप्त नहीं किया जाएगा यदि यह पहले से ही निहित है)। कृपया ध्यान दें, हालांकि, 16-बिट और 32-बिट मोड में, बीपी रजिस्टर में 8-बिट भागों को एक्सेस करने की क्षमता नहीं है जैसे कि AX (AL और AH) है।
इस विकल्प के बाद से, संकलनकर्ता को अनुकूलन में ईबीपी को सामान्य प्रयोजन रजिस्टर के रूप में उपयोग करने की अनुमति देने के अलावा, स्टैक फ्रेम के लिए निकास और प्रवेश कोड को उत्पन्न करने से रोकता है जो डीबगिंग को जटिल करता है - यही कारण है कि जीसीसी प्रलेखन स्पष्ट रूप से कहता है (असामान्य रूप से बोल्ड के साथ जोर देते हुए) शैली) जो इस विकल्प को सक्षम करता है, कुछ मशीनों पर डिबगिंग को असंभव बनाता है
कृपया यह भी जान लें कि डिबगिंग या ऑप्टिमाइज़ेशन से संबंधित अन्य संकलक विकल्प, -fomit-frame-pointer
विकल्प को चालू या बंद कर सकते हैं।
मुझे gcc.gnu.org पर कोई आधिकारिक जानकारी नहीं मिली है कि -fomit-frame-pointer
x86 प्लेटफार्मों पर अन्य विकल्प कैसे प्रभावित करते हैं , https://gcc.gnu.org/oniltocs/gcc-3.4.4/gcc/Optimize-Options.html केवल निम्नलिखित बताता है:
-O ऐसी मशीनों पर भी ऑन-ऑफोमेट-फ्रेम-पॉइंटर को चालू करता है जहां ऐसा करने से डिबगिंग में हस्तक्षेप नहीं होता है।
तो यह प्रति से प्रलेखन से स्पष्ट नहीं है कि क्या -fomit-frame-pointer
चालू किया जाएगा यदि आप -O
x86 प्लेटफॉर्म पर एक ही विकल्प के साथ संकलन करते हैं । यह अनुभवजन्य रूप से परीक्षण किया जा सकता है, लेकिन इस मामले में जीसीसी डेवलपर्स से कोई प्रतिबद्धता नहीं है कि भविष्य में इस विकल्प के व्यवहार को नोटिस के बिना नहीं बदला जाए।
हालांकि, पीटर कॉर्डेस ने टिप्पणियों में बताया है कि -fomit-frame-pointer
x86-16 प्लेटफार्मों और x86-32 / 64 प्लेटफार्मों के बीच डिफ़ॉल्ट सेटिंग्स के लिए एक अंतर है।
यह विकल्प - -fomit-frame-pointer
- इंटेल C ++ कम्पाइलर 15.0 के लिए भी प्रासंगिक है , न केवल GCC के लिए:
इंटेल कंपाइलर के लिए, इस विकल्प में एक उपनाम है /Oy
।
यहाँ इंटेल ने इसके बारे में क्या लिखा है:
ये विकल्प निर्धारित करते हैं कि ईबीपी का उपयोग अनुकूलन में एक सामान्य-उद्देश्य रजिस्टर के रूप में किया जाता है या नहीं। विकल्प -fomit- फ्रेम-पॉइंटर और / Oy इस उपयोग की अनुमति देते हैं। विकल्प -fno-omit- फ्रेम-पॉइंटर और / Oy- इसे अस्वीकृत करें।
कुछ डीबगर्स ईबीपी को स्टैक फ्रेम पॉइंटर के रूप में उपयोग करने की उम्मीद करते हैं, और जब तक ऐसा नहीं होता तब तक स्टैक बैकट्रेस का उत्पादन नहीं किया जा सकता है। -Fno-omit- फ्रेम-पॉइंटर और / Oy- ऑप्शन कंपाइलर को निर्देश देते हैं कि वह कोड बनाए जो ईबीपी को सभी कार्यों के लिए स्टैक फ्रेम पॉइंटर के रूप में बनाए रखता है और उपयोग करता है ताकि एक डीबगर अभी भी निम्नलिखित किए बिना स्टैक बैकट्रेस का उत्पादन कर सके:
Forfno-omit-फ़्रेम-पॉइंटर: -O0 के साथ ऑप्टिमाइज़ेशन बंद करना / Oy के लिए: - बंद करना / O1, / O2, या / O3 ऑप्टिमाइज़ेशन -fno-omit-फ़्रेम-पॉइंटर विकल्प सेट है जब आप विकल्प निर्दिष्ट करते हैं - O0 या -g विकल्प। जब आप विकल्प -O1, -O2, या -O3 निर्दिष्ट करते हैं -fomit- फ्रेम-पॉइंटर विकल्प सेट किया जाता है।
जब आप / O1, / O2, या / O3 विकल्प निर्दिष्ट करते हैं तो / Oy विकल्प सेट किया जाता है। जब आप / Od विकल्प निर्दिष्ट करते हैं तो विकल्प / Oy- सेट किया जाता है।
-Fno-omit-फ़्रेम-पॉइंटर या / Oy- विकल्प का उपयोग करने से उपलब्ध सामान्य-उद्देश्य रजिस्टरों की संख्या 1 से कम हो जाती है और परिणामस्वरूप थोड़ा कम कुशल कोड हो सकता है।
नोट लिनक्स * सिस्टम के लिए: वर्तमान में GCC 3.2 अपवाद हैंडलिंग के साथ एक समस्या है। इसलिए, इंटेल कंपाइलर इस विकल्प को नजरअंदाज कर देता है जब C ++ के लिए GCC 3.2 स्थापित किया जाता है और अपवाद हैंडलिंग चालू होता है (डिफ़ॉल्ट)।
कृपया ध्यान रखें कि उपरोक्त उद्धरण केवल इंटेल C ++ 15 संकलक के लिए प्रासंगिक है, जीसीसी के लिए नहीं।