2010-12-30 6 views
23

मैंने पाठ्य पुस्तकों में पढ़ा है कि ढेर स्मृति पते को कम करके बढ़ता है; वह है, उच्च पते से निम्न पते तक। यह एक बुरा सवाल हो सकता है, लेकिन मुझे अवधारणा सही नहीं मिली। क्या तुम समझा सकते हो?स्टैक पता स्मृति पते को कम करने की दिशा में क्यों बढ़ता है?

उत्तर

41

पहला, यह मंच निर्भर है। कुछ आर्किटेक्चर में, स्टैक को एड्रेस स्पेस के नीचे से आवंटित किया जाता है और ऊपर बढ़ता है।

86 कि नीचे की तरफ पता स्थान के ऊपर से बड़े हो गए ढेर की तरह एक वास्तुकला मानते हुए, विचार बहुत आसान है:

===============  Highest Address (e.g. 0xFFFF) 
|    | 
| STACK | 
|    | 
|.............| <- Old Stack Pointer (e.g. 0xEEEE) 
|    | 
| Newly  | 
| allocated | 
|-------------| <- New Stack Pointer (e.g. 0xAAAA) 
.  ...  . 
|    | 
|-------------| <- Heap Pointer  (e.g. 0x2222) 
|    | 
| HEAP  | 
|    | 
===============  Lowest Address (e.g. 0x0000) 
:

===============  Highest Address (e.g. 0xFFFF) 
|    | 
| STACK | 
|    | 
|-------------| <- Stack Pointer (e.g. 0xEEEE) 
|    | 
.  ...  . 
|    | 
|-------------| <- Heap Pointer (e.g. 0x2222) 
|    | 
| HEAP  | 
|    | 
===============  Lowest Address (e.g. 0x0000) 

ढेर बढ़ने के लिए, आपको ढेर सूचक कमी होगी

जैसा कि आप देख सकते हैं, ढेर बढ़ने के लिए, हमारे पास 0xEEEE से 0xAAAA तक स्टैक पॉइंटर घट गया है, जबकि ढेर बढ़ने के लिए, आपको ढेर पॉइंटर को बढ़ाना होगा।

जाहिर है, यह स्मृति लेआउट का सरलीकरण है। वास्तविक निष्पादन योग्य, डेटा खंड, ... स्मृति में भी लोड किया गया है। इसके अलावा, धागे की अपनी ढेर जगह होती है।

आप पूछ सकते हैं, क्यों नीचे ढेर होना चाहिए। खैर, जैसा कि मैंने पहले कहा था, कुछ आर्किटेक्चर रिवर्स करते हैं, जिससे ढेर नीचे बढ़ते हैं और ऊपर की ओर बढ़ते हैं। यह विपरीत पक्षों पर ढेर और ढेर लगाने के लिए समझ में आता है क्योंकि यह ओवरलैप को रोकता है और जब तक आपके पास पर्याप्त पता स्थान उपलब्ध हो, तब तक दोनों क्षेत्रों को स्वतंत्र रूप से बढ़ने की अनुमति मिलती है।

एक और वैध सवाल यह हो सकता है: क्या कार्यक्रम स्टैक पॉइंटर को कम/बढ़ाने के लिए नहीं है? प्रोग्रामर को एक आर्किटेक्चर एक दूसरे पर कैसे लगा सकता है? ऐसा क्यों नहीं है क्योंकि यह आर्किटेक्चर निर्भर है? जबकि आप आर्किटेक्चर से काफी ज्यादा लड़ सकते हैं और किसी भी तरह से विपरीत दिशा में अपना ढेर दूर कर सकते हैं, कुछ निर्देश, विशेष रूप से call और ret जो स्टैक पॉइंटर को संशोधित करते हैं, वे सीधे एक और दिशा मानते हैं, जिससे गड़बड़ हो जाती है।

+4

+0.5 अकेले ASCII कला के लिए। :) लेकिन, "कैसे" का जवाब देते हुए, यह "क्यों" बहुत अच्छा जवाब नहीं देता है। इस तरह से ढेर को परिभाषित करने के लिए यह इतना आम और/या उपयोगी बनाता है? – cHao

+2

@cHao: इस मुद्दे को हल करने के लिए कुछ अनुच्छेद जोड़े गए। –

+2

@ मेहरदद अफशारी कुछ ग्रंथों का कहना है क्योंकि हम ऑफसेट को नकारात्मक मानते हैं क्योंकि स्टैक नीचे बढ़ता है –

17

आजकल यह काफी हद तक है क्योंकि यह लंबे समय तक ऐसा किया गया है और बहुत से कार्यक्रम मानते हैं कि यह इस तरह से किया गया है, और इसे बदलने का कोई वास्तविक कारण नहीं है।

वापस जब डायनासोर पृथ्वी पर घूमते थे और कंप्यूटर में 8kb स्मृति थी, तो आप भाग्यशाली थे, हालांकि, यह एक महत्वपूर्ण स्थान अनुकूलन था। आप मेमोरी के शीर्ष पर ढेर के नीचे डालते हैं, बढ़ते हैं, और malloc क्षेत्र बढ़ने के साथ आप प्रोग्राम और उसके डेटा को बहुत नीचे रख देते हैं। इस तरह, ढेर के आकार पर एकमात्र सीमा कार्यक्रम + ढेर का आकार था, और इसके विपरीत। यदि स्टैक इसके बजाय 4kB (उदाहरण के लिए) पर शुरू हुआ और बड़ा हुआ, तो ढेर 4kB (प्रोग्राम के आकार से कम) से बड़ा कभी नहीं हो सकता है, भले ही प्रोग्राम को केवल कुछ सौ बाइट स्टैक की आवश्यकता हो।

1
int main() { 
    int a = 0x12345678; 
    int b = 0x34234232; 
    printf("%p\n", &a); 
    printf("%p\n", &b); 
    return 0; 
} 

इस कार्यक्रम पर इस उत्पादन पैदा करता है। पता नहीं होना चाहिए?

[email protected]:~/eclipse_workspace/Sample/Sample$ ./a.out 
0xbf8a5f98 
0xbf8a5f9c 
[email protected]:~/eclipse_workspace/Sample/Sample$ 
+4

जबकि स्थानीय चर ** ** स्टैक (सी में) पर संग्रहीत हैं, उन्हें स्टैक पर धक्का नहीं दिया जाता है, जैसे कॉल कॉल रिटर्न पते हैं। इसके बजाए, फंक्शन के कॉल के तुरंत बाद स्टैक का एक हिस्सा आवंटित किया जाता है। संकलक तब प्रत्येक घोषित स्थानीय चर के लिए इस खंड के भीतर एक स्थान निर्दिष्ट करता है। कंपाइलर उस चर के भीतर उन चरों को असाइन करने का विकल्प कैसे चुनता है संकलक द्वारा भिन्न होता है, हालांकि अक्सर वे घोषणा के क्रम के साथ स्मृति में चढ़ते हैं। यह भी देखें [यह प्रश्न] (http://stackoverflow.com/questions/1102049/order-of-local-variable-allocation-on-the-stack) –

+0

यह प्रश्न का उत्तर नहीं है। – problemofficer

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