2012-02-10 13 views
16
  1. जब कोई सी प्रोग्राम संकलित होता है और ऑब्जेक्ट फ़ाइल (ईएलएफ) बनाई जाती है। ऑब्जेक्ट फ़ाइल में बीएसएस, डेटा, टेक्स्ट और अन्य सेगमेंट जैसे विभिन्न अनुभाग होते हैं। मैं समझ गया कि ईएलएफ के ये वर्ग वर्चुअल मेमोरी एड्रेस स्पेस का हिस्सा हैं। क्या मैं सही हू? अगर मैं गलत हूं कृपया मुझे सही।भौतिक स्मृति से संबंधित ढेर, ढेर, पाठ जैसे विभिन्न सेगमेंट कैसे हैं?

  2. इसके अलावा, संकलित प्रोग्राम से जुड़े वर्चुअल मेमोरी और पेज टेबल भी होंगे। पृष्ठ तालिका प्रोग्राम लोड करते समय ईएलएफ में वास्तविक वर्चुअल मेमोरी एड्रेस में मौजूद वर्चुअल मेमोरी एड्रेस को जोड़ती है। क्या मेरी समझ सही है?

  3. मैंने पढ़ा है कि बनाई गई ईएलएफ फ़ाइल में, बीएसएस अनुभाग केवल अनियंत्रित वैश्विक चर का संदर्भ रखता है। यहां अनियंत्रित ग्लोबल वेरिएबल का अर्थ है, वे चर जो घोषणा के दौरान अंतर्निहित नहीं हैं?

  4. इसके अलावा, मैंने पढ़ा है कि स्थानीय चर को रन टाइम (यानी, स्टैक में) स्थान आवंटित किया जाएगा। फिर ऑब्जेक्ट फ़ाइल में उनका संदर्भ कैसे दिया जाएगा?

  5. यदि प्रोग्राम में, गतिशील रूप से स्मृति आवंटित करने के लिए कोड का विशेष अनुभाग उपलब्ध है। ऑब्जेक्ट फ़ाइल में इन चरों का संदर्भ कैसे दिया जाएगा?

मैं उलझन में है कि वस्तु फ़ाइल के इन विभिन्न वर्गों (पाठ की तरह, rodata, डेटा, बीएसएस, ढेर और ढेर) भौतिक स्मृति (RAM) है, जहां सभी कार्यक्रमों क्रियान्वित कर रहे हैं का हिस्सा हैं हूँ। लेकिन मुझे लगता है कि मेरी समझ गलत है। प्रक्रिया या प्रोग्राम निष्पादन में होने पर भौतिक स्मृति से संबंधित ये अलग-अलग सेगमेंट कैसे होते हैं?

उत्तर

2

सभी विभिन्न वर्गों के पते (.text, .bss, .data, आदि) आपको दिखाई देने वाले आकार कमांड के साथ एक ELF का निरीक्षण:

$ size -A -x my_elf_binary 

आभासी पते हैं। ऑपरेटिंग सिस्टम के साथ एमएमयू वर्चुअल पतों से रैम भौतिक पते पर अनुवाद करता है।

1

4. आप जीसीसी द्वारा उत्पन्न एक कोडांतरक कोड को देखें, तो आपको लगता है कि स्मृति स्थानीय चर देख सकते हैं आदेश push के माध्यम से या रजिस्टर ESP का मूल्य बदलने के माध्यम से ढेर में आवंटित किया जाता है। फिर उन्हें mov या उसके जैसा कुछ आदेश दिया गया है।

3

मुझे यकीन है कि अगर 1, 2 और 3 सही हैं नहीं कर रहा हूँ, लेकिन मैं 4 और 5.

व्याख्या कर सकते हैं: वे ढेर के ऊपर से ऑफसेट द्वारा संदर्भित कर रहे हैं। फ़ंक्शन निष्पादित करते समय, स्थानीय चर के लिए स्थान आवंटित करने के लिए स्टैक का शीर्ष बढ़ाया जाता है। कंपाइलर स्टैक में स्थानीय चर के क्रम को निर्धारित करता है ताकि कंपाइलर न हो, स्टैक के शीर्ष से चर के ऑफसेट क्या है।

भौतिक स्मृति में ढेर ऊपर की ओर स्थित है। ढेर की शुरुआत में आमतौर पर उच्चतम स्मृति पता उपलब्ध होता है। स्थानीय चर के लिए ढेर decrements के शीर्ष की पता स्थान आवंटित करता है (और संभवत: अतिप्रवाह ढेर करने के लिए नेतृत्व कर सकते हैं - कम पतों पर खंडों के साथ ओवरलैप कर :-)) कार्यक्रमों रन के रूप में और

: संकेत का उपयोग करना - का पता गतिशील रूप से आवंटित चर (स्थानीय) चर में संग्रहीत किया जाता है। यह सी में पॉइंटर्स का उपयोग करने के अनुरूप है।

मैं पाया है अच्छा यहाँ स्पष्टीकरण: http://www.ualberta.ca/CNS/RESEARCH/LinuxClusters/mem.html

16

1. सही है, ELF फ़ाइल एक प्रक्रिया का वर्चुअल ऐड्रेस स्पेस है कि ऑपरेटिंग सिस्टम ELF फ़ाइल सामग्री की प्रतिलिपि चाहिए में पूर्ण या संबंधित स्थानों बाहर देता है में। (बीएसएस सिर्फ एक स्थान और आकार है, क्योंकि यह सभी शून्य होने के कारण है, वास्तव में ईएलएफ फ़ाइल में शून्य होने की आवश्यकता नहीं है)। ध्यान दें कि स्थानों निरपेक्ष स्थानों हो सकता है (आभासी पता 0x100000 या पाठ की समाप्ति के बाद 4096 बाइट्स की तरह रिश्तेदार स्थानों की तरह।)

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

3. प्रोग्रामिंग भाषा आप परिभाषित करता है का उपयोग कर रहे हैं जो अप्रारंभीकृत राज्य बीएसएस में चला जाता है, और जो स्पष्ट रूप से प्रारंभ हो जाता है। ध्यान दें कि बीएसएस में इन चरों में "संदर्भ" शामिल हैं, यह उन चर का समर्थन करने वाला संग्रहण है।

4. स्टैक चर को जेनरेट कोड से स्पष्ट रूप से संदर्भित किया जाता है। ईएलएफ फ़ाइल में उनके बारे में कुछ भी स्पष्ट नहीं है (या यहां तक ​​कि ढेर)।

5. स्टैक संदर्भों की तरह, ढेर संदर्भ ईएलएफ फ़ाइल में जेनरेट कोड में अंतर्निहित हैं। (वे सब sbrk या इसके समकक्ष के लिए एक कॉल के माध्यम से वर्चुअल ऐड्रेस स्पेस बदल रहा है के द्वारा बनाई गई स्मृति में संग्रहीत कर रहे हैं।)

ELF फ़ाइल एक OS को बताते हैं कि कैसे एक कार्यक्रम का एक उदाहरण के लिए सेटअप एक आभासी पता स्थान है। विभिन्न वर्ग अलग-अलग ज़रूरतों का वर्णन करते हैं। उदाहरण के लिए ".rodata" कहता है कि मैं केवल-पढ़ने के लिए डेटा संग्रहीत करना चाहता हूं (निष्पादन योग्य कोड के विपरीत)। ".text" खंड का अर्थ निष्पादन योग्य कोड है। "बीएसएस" एक ऐसा क्षेत्र है जो राज्य को स्टोर करने के लिए उपयोग किया जाता है जिसे ओएस द्वारा शून्य किया जाना चाहिए। आभासी पता स्थान का अर्थ है कि कार्यक्रम (वैकल्पिक रूप से) उन चीज़ों पर भरोसा कर सकता है जहां यह शुरू होने पर अपेक्षा करता है। (उदाहरण के लिए, यदि यह .bss को 0x4000 पते पर पूछता है, तो या तो ओएस इसे शुरू करने से इनकार कर देगा, या यह वहां होगा।)

ध्यान दें कि ये वर्चुअल पते भौतिक पते पर मैप किए गए हैं ओएस द्वारा प्रबंधित पेज टेबल। ईएलएफ फ़ाइल के उदाहरण में शामिल किसी भी विवरण को जानने की आवश्यकता नहीं है जिसमें भौतिक पृष्ठों का उपयोग किया जाता है।

2

यदि आप इन चीजों को जानना चाहते हैं, तो संभव हो तो स्रोत कोड (www.kernel.org) के साथ ओएस के बारे में जानें।
आपको यह एहसास होना चाहिए कि ओएस कर्नेल वास्तव में सीपीयू चला रहा है और मेमोरी संसाधन का प्रबंधन कर रहा है। और सी कोड ओएस ड्राइव करने और रजिस्टरों के साथ केवल सरल संचालन चलाने के लिए सिर्फ एक हल्के वजन स्क्रिप्ट है।

  1. वर्चुअल मेमोरी और शारीरिक स्मृति के बारे में CPU के TLB दे लगभग TLB की शक्ति के माध्यम से सटे स्मृति का उपयोग करने के लिए उपयोगकर्ता अंतरिक्ष प्रक्रिया (का उपयोग कर पृष्ठ तालिका) हार्डवेयर है। तो वास्तविक भौतिक स्मृति, जो कि वर्चुअल वर्चुअल मेमोरी में मैप की गई है, रैम पर कहीं भी बिखरी जा सकती है। संकलित प्रोग्राम इस टीएलबी सामग्री और भौतिक स्मृति पता सामान के बारे में नहीं जानता है। वे ओएस कर्नेल स्पेस में प्रबंधित होते हैं।

  2. बीएसएस एक ऐसा अनुभाग है जो ओएस शून्य भरे मेमोरी पते के रूप में तैयार करता है, क्योंकि उन्हें सी/सी ++ स्रोत कोड में प्रारंभ नहीं किया गया था, इस प्रकार संकलक/लिंकर द्वारा बीएसएस के रूप में चिह्नित किया गया था।

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

  4. कोई जादू नहीं। ऑब्जेक्ट कोड में, मॉलोक से लौटाए गए पॉइंटर से किए गए प्रत्येक ऑपरेशन को मैलोक फ़ंक्शन कॉल से लौटाए गए रजिस्टर मान पर ऑफ़सेट के रूप में संभाला जाता है।

असल में मॉलोक काफी जटिल चीजें कर रहा है। गतिशील आवंटन में सुधार के लिए विभिन्न कार्यान्वयन (जेमलोक/ptmalloc/dlmalloc/googlemalloc/...) हैं, लेकिन असल में वे सभी को एसआरबीके या एमएमएपी (/ dev/zero) का उपयोग कर ओएस से नया मेमोरी क्षेत्र मिल रहा है, जिसे अनाम स्मृति कहा जाता है ।

2

बस अपने कार्यक्रम के विभिन्न हिस्सों के शुरुआती पते को जानने के लिए स्वयं को कमांड पर एक आदमी करें।

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

रनटाइम बाध्यकारी के कारण रन-टाइम पर दूसरे प्रश्न पर आ रहा है। तीसरा सवाल सच है। सभी अनियमित वैश्विक चर और स्थिर चर बीएसएस में जाते हैं। विशेष मामले को भी ध्यान दें: वे बीएसएस में जाते हैं भले ही वे 0 से शुरू हो जाएं।

संबंधित मुद्दे