बेस पॉइंटर और स्टैक पॉइंटर क्या है? वे किस ओर इशारा करते हैं?


225

विकिपीडिया से आने वाले इस उदाहरण का उपयोग करते हुए , जिसमें DrawSquare () कॉललाइन () कहते हैं,

वैकल्पिक शब्द

(ध्यान दें कि इस आरेख में सबसे नीचे उच्च पते हैं और शीर्ष पर निम्न पते हैं।)

क्या कोई मुझे समझा सकता है कि इस संदर्भ में क्या हैं ebpऔर क्या espहैं?

मैं जो देखता हूं, उससे कहता हूं कि स्टैक पॉइंटर पॉइंट्स हमेशा स्टैक के शीर्ष पर होते हैं, और बेस पॉइंटर को वर्तमान फ़ंक्शन की शुरुआत में? और क्या?


संपादित करें: मेरा मतलब है कि विंडोज़ कार्यक्रमों के संदर्भ में

edit2: और कैसे eipकाम करता है?

edit3: मेरे पास MSVC ++ से निम्न कोड है:

var_C= dword ptr -0Ch
var_8= dword ptr -8
var_4= dword ptr -4
hInstance= dword ptr  8
hPrevInstance= dword ptr  0Ch
lpCmdLine= dword ptr  10h
nShowCmd= dword ptr  14h

यह सभी एक दूसरे के लिए 4 बाइट्स लेते हैं। इसलिए मैं देख सकता हूँ कि hInstance से 4 बाइट्स के var_4 में एक अंतर है। वे क्या हैं? मुझे लगता है कि यह वापसी का पता है, जैसा कि विकिपीडिया की तस्वीर में देखा जा सकता है?


(संपादक का नोट: माइकल के जवाब से एक लंबा उद्धरण हटा दिया गया, जो प्रश्न में नहीं है, लेकिन एक अनुवर्ती प्रश्न संपादित किया गया था):

ऐसा इसलिए है क्योंकि फ़ंक्शन कॉल का प्रवाह है:

* Push parameters (hInstance, etc.)
* Call function, which pushes return address
* Push ebp
* Allocate space for locals

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


23
एक महत्वपूर्ण बात यह है कि स्टैक स्मृति में "नीचे की ओर" बढ़ता है। इसका मतलब यह है कि स्टैक पॉइंटर को ऊपर की ओर ले जाने के लिए आप इसके मूल्य को कम करते हैं।
बीएस

4
ईबीपी / ईएसपी और ईआईपी क्या कर रहे हैं, यह बताने के लिए एक संकेत: ईबीपी और ईएसपी डेटा के साथ सौदा करते हैं, जबकि ईआईपी कोड से संबंधित है।
mmmmmmmm

2
आपके ग्राफ में, ebp (आमतौर पर) "फ्रेम पॉइंटर" है, जो "स्टैक पॉइंटर" है। यह [ebp-x] और स्टैक मापदंडों के माध्यम से [ebp + x] लगातार, स्टैक पॉइंटर से स्वतंत्र होने की अनुमति देता है (जो किसी फ़ंक्शन के भीतर अक्सर बदलता रहता है)। ईएसपी के माध्यम से किया जा सकता है, अन्य संचालन के लिए ईबीपी को मुक्त करना - लेकिन इस तरह, डिबगर्स कॉल स्टैक या स्थानीय लोगों के मूल्यों को नहीं बता सकते हैं।
पीटरचेन

4
@Ben। निस्सार नहीं। कुछ कंपाइलरों ने ढेर के ढेर को ढेर में डाल दिया। स्टैकिंग की अवधारणा नीचे बढ़ती जा रही है, एक अवधारणा जो इसे समझना आसान बनाती है। स्टैक का कार्यान्वयन कुछ भी हो सकता है (ढेर के यादृच्छिक विखंडू का उपयोग करके हैक बनाता है जो स्टैक के कुछ हिस्सों को बहुत मुश्किल से अधिलेखित करता है क्योंकि वे नियतात्मक नहीं हैं)।
मार्टिन यॉर्क

1
दो शब्दों में: स्टैक पॉइंटर काम करने के लिए पुश / पॉप ऑपरेशंस की अनुमति देता है (इसलिए पुश और पॉप जानता है कि डेटा कहाँ रखा / जाना है)। बेस पॉइंटर स्वतंत्र रूप से संदर्भ डेटा के लिए कोड की अनुमति देता है जिसे पहले स्टैक पर धकेल दिया गया है।
टाइगरॉ

जवाबों:


228

esp जैसा कि आप कहते हैं, यह स्टैक के ऊपर है।

ebpआमतौर espपर फंक्शन की शुरुआत में सेट किया जाता है। फ़ंक्शन पैरामीटर और स्थानीय चर क्रमशः, एक निरंतर ऑफसेट से जोड़कर और घटाकर पहुँचा जाता है ebp। सभी x86 कॉलिंग कन्वेंशन ebpफ़ंक्शन कॉल में संरक्षित होने के रूप में परिभाषित करते हैं। ebpअपने आप में वास्तव में पिछले फ्रेम के बेस पॉइंटर को इंगित करता है, जो एक डिबगर में चलने और अन्य फ्रेम को काम करने के लिए स्थानीय चर देखने में सक्षम बनाता है।

अधिकांश समारोह प्रस्ताव कुछ इस तरह दिखते हैं:

push ebp      ; Preserve current frame pointer
mov ebp, esp  ; Create new frame pointer pointing to current stack top
sub esp, 20   ; allocate 20 bytes worth of locals on stack.

फिर बाद में फ़ंक्शन में आपके जैसे कोड हो सकते हैं (मान लें कि दोनों स्थानीय चर 4 बाइट्स हैं)

mov [ebp-4], eax    ; Store eax in first local
mov ebx, [ebp - 8]  ; Load ebx from second local

एफपीओ या फ्रेम पॉइंटर ऑप्रेशन ऑप्टिमाइज़ेशन जिसे आप सक्षम कर सकते हैं, वास्तव में इसे खत्म कर देगा और ebpसीधे दूसरे रजिस्टर और एक्सेस लोकल के रूप में उपयोग कर सकता है esp, लेकिन इससे डिबगिंग थोड़ी अधिक कठिन हो जाती है क्योंकि डीबगर अब सीधे फ़ंक्शन फ़ंक्शन के स्टैक फ़्रेम तक नहीं पहुंच सकता है।

संपादित करें:

आपके अद्यतन प्रश्न के लिए, स्टैक में गुम दो प्रविष्टियाँ हैं:

var_C = dword ptr -0Ch
var_8 = dword ptr -8
var_4 = dword ptr -4
*savedFramePointer = dword ptr 0*
*return address = dword ptr 4*
hInstance = dword ptr  8h
PrevInstance = dword ptr  0C
hlpCmdLine = dword ptr  10h
nShowCmd = dword ptr  14h

ऐसा इसलिए है क्योंकि फ़ंक्शन कॉल का प्रवाह है:

  • पुश पैरामीटर ( hInstance, आदि)
  • कॉल फ़ंक्शन, जो रिटर्न एड्रेस को पुश करता है
  • धक्का दें ebp
  • स्थानीय लोगों के लिए जगह आवंटित करें

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

3
EBP को जादुई रूप से नहीं बदला गया है, इसलिए जब तक आपने अपने फ़ंक्शन के लिए एक नया EBP स्थापित नहीं किया है तब तक आपके पास कॉलर्स का मूल्य होगा। और तर्कों के अलावा, स्टैक पुराने EIP (रिटर्न एड्रेस) को भी रखेगा
MSalters

3
अच्छा उत्तर। यद्यपि यह उल्लेख किए बिना पूरा नहीं हो सकता कि एपिलॉग में क्या है: "छुट्टी" और "रिट" निर्देश।
कैलमरीस

2
मुझे लगता है कि यह छवि कुछ चीजों को स्पष्ट करने में मदद करेगी कि प्रवाह क्या है। यह भी ध्यान रखें कि स्टैक नीचे की ओर बढ़ता है। ocw.cs.pub.ro/courses/_media/so/laboratoare/call_stack.png
आंद्रेई-निकुले पेट्रे

क्या यह मेरे, या सभी माइनस संकेत ऊपर दिए गए कोड स्निपेट से गायब हैं?
बारबरावार्क

96

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

आम तौर पर और यह संकलक से संकलक तक भिन्न हो सकता है), किसी फ़ंक्शन को दिए जा रहे सभी तर्कों को कॉलिंग फ़ंक्शन द्वारा स्टैक पर धकेल दिया जाता है (आमतौर पर रिवर्स ऑर्डर में वे फ़ंक्शन प्रोटोटाइप में घोषित होते हैं, लेकिन यह भिन्न होता है) । फिर फ़ंक्शन को कहा जाता है, जो स्टैक पर रिटर्न एड्रेस (ईआईपी) को धक्का देता है।

फ़ंक्शन में प्रवेश करने पर, पुराने EBP मान को स्टैक पर धकेल दिया जाता है और EBP को ESP के मान पर सेट किया जाता है। फिर ईएसपी को कम किया जाता है (क्योंकि स्टैक मेमोरी में नीचे बढ़ता है) फ़ंक्शन के स्थानीय चर और अस्थायी के लिए जगह आवंटित करने के लिए। उस बिंदु से, फ़ंक्शन के निष्पादन के दौरान, फ़ंक्शन के तर्क ईबीपी से सकारात्मक ऑफसेट पर स्टैक पर स्थित हैं (क्योंकि उन्हें फ़ंक्शन कॉल से पहले धक्का दिया गया था), और स्थानीय वेरिएबल ईबीपी से नकारात्मक ऑफसेट पर स्थित हैं (क्योंकि उन्हें फ़ंक्शन प्रविष्टि के बाद स्टैक पर आवंटित किया गया था)। इसीलिए EBP को फ्रेम पॉइंटर कहा जाता है , क्योंकि यह फंक्शन कॉल फ्रेम के केंद्र की ओर इशारा करता है ।

बाहर निकलने पर, सभी फ़ंक्शन को ईएसपी को ईबीपी के मूल्य पर सेट करना होता है (जो स्टैक से स्थानीय चर को हटाता है, और स्टैक के शीर्ष पर प्रवेश ईबीपी को उजागर करता है), फिर स्टैक से पुराने ईबीपी मूल्य को पॉप करें। और फिर फ़ंक्शन रिटर्न (ईआईपी में रिटर्न एड्रेस को पॉप करना)।

कॉलिंग फ़ंक्शन पर वापस लौटने पर, यह फ़ंक्शन को हटाने के लिए ईएसपी को बढ़ा सकता है ताकि इसे दूसरे फ़ंक्शन को कॉल करने से पहले स्टैक पर धकेल दिया जाए। इस बिंदु पर, स्टैक वापस उसी स्थिति में होता है जिसे यह पहले से कहा जाता है।


15

आपके पास यह सही है। स्टैक पॉइंटर स्टैक पर शीर्ष आइटम को इंगित करता है और बेस पॉइंटर फ़ंक्शन को कॉल करने से पहले स्टैक के "पिछले" शीर्ष पर इंगित करता है।

जब आप किसी फ़ंक्शन को कॉल करते हैं, तो किसी भी स्थानीय चर को स्टैक पर संग्रहीत किया जाएगा और स्टैक पॉइंटर को बढ़ाया जाएगा। जब आप फ़ंक्शन से वापस आते हैं, तो स्टैक पर सभी स्थानीय चर दायरे से बाहर हो जाते हैं। आप स्टैक पॉइंटर को वापस बेस पॉइंटर पर सेट करके करते हैं (जो फ़ंक्शन कॉल से पहले "पिछले" शीर्ष था)।

स्मृति आवंटन करने से इस तरह से है बहुत , बहुत तेजी से और कुशल।


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

7

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

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

विंडोज कार्यक्रमों के बारे में बोलते हुए, आप शायद अपने C ++ कोड को संकलित करने के लिए Visual Studio का उपयोग कर सकते हैं। विदित हो कि Microsoft फ़्रेम पॉइंटर एडमिशन नामक एक अनुकूलन का उपयोग करता है, जो निष्पादन योग्य के लिए dbghlp लाइब्रेरी और PDB फ़ाइल का उपयोग किए बिना स्टैक को चलना लगभग असंभव बना देता है।

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

अपनी संकलन इकाइयों में एफपीओ से बचने के लिए, आपको अपनी परियोजनाओं में C ++ संकलन के झंडे को स्पष्ट रूप से / O2 का उपयोग करने से बचने की आवश्यकता है। आप संभवतः C या C ++ रनटाइम के खिलाफ लिंक करते हैं, जो रिलीज़ कॉन्फ़िगरेशन में FPO का उपयोग करता है, इसलिए आपके पास dbghlp.dll के बिना स्टैक वॉक करने के लिए कठिन समय होगा।


मुझे नहीं लगता कि ईआईपी स्टैक पर कैसे संग्रहीत किया जाता है। क्या यह एक रजिस्टर नहीं होना चाहिए? स्टाॅक पर रजिस्टर कैसे हो सकता है? धन्यवाद!
खगोलीय एलीसियम

कॉल करने वाले ईआईपी को कॉल निर्देश द्वारा स्वयं स्टैक पर धकेल दिया जाता है। आरईटी निर्देश सिर्फ स्टैक के शीर्ष को प्राप्त करता है और इसे ईआईपी में डालता है। यदि आपके पास बफर ओवररन हैं, तो इस तथ्य का उपयोग विशेषाधिकार प्राप्त धागे से उपयोगकर्ता कोड में कूदने के लिए किया जा सकता है।
आकर्षक

@devouredelysium ईआईपी रजिस्टर की सामग्री (या मूल्य ) स्टैक पर (या कॉपी की गई) पर डाल दी जाती है, न कि रजिस्टर में ही।
बारबरावार्क

@BarbaraKwarc मूल्य-योग्य इनपुट के लिए धन्यवाद । मैं देख नहीं पाया कि मेरे जवाब से ओपी क्या गायब था। वास्तव में, रजिस्टर वहीं रहते हैं जहां वे होते हैं, केवल उनका मूल्य सीपीयू से रैम में भेजा जाता है। Amd64 मोड में, यह थोड़ा अधिक जटिल हो जाता है, लेकिन इसे दूसरे प्रश्न पर छोड़ दें।
व्यंग्य

उस am64 के बारे में क्या? मैं उत्सुक हूँ।
बारबराकर्क

6

सबसे पहले, स्टैक पॉइंटर पॉइंटर के निचले हिस्से की ओर इशारा करता है क्योंकि x86 स्टैक उच्च एड्रेस वैल्यू से निचले एड्रेस वैल्यू तक बनता है। स्टैक पॉइंटर वह बिंदु होता है जहां अगली कॉल पुश (या कॉल) करने के लिए अगला मान होगा। यह ऑपरेशन C / C ++ स्टेटमेंट के बराबर है:

 // push eax
 --*esp = eax
 // pop eax
 eax = *esp++;

 // a function call, in this case, the caller must clean up the function parameters
 move eax,some value
 push eax
 call some address  // this pushes the next value of the instruction pointer onto the
                    // stack and changes the instruction pointer to "some address"
 add esp,4 // remove eax from the stack

 // a function
 push ebp // save the old stack frame
 move ebp, esp
 ... // do stuff
 pop ebp  // restore the old stack frame
 ret

बेस पॉइंटर वर्तमान फ्रेम के ऊपर है। ईबे आमतौर पर आपके रिटर्न पते की ओर इशारा करता है। ebp + 4 आपके फ़ंक्शन के पहले पैरामीटर (या किसी वर्ग विधि का मान) को इंगित करता है। ebp-4 आपके फ़ंक्शन के पहले स्थानीय चर को इंगित करता है, आमतौर पर ईबीपी का पुराना मूल्य ताकि आप पूर्व फ्रेम पॉइंटर को पुनर्स्थापित कर सकें।


2
नहीं, ESP स्टैक के नीचे की ओर इशारा नहीं करता है । मेमोरी एड्रेसिंग स्कीम का इससे कोई लेना-देना नहीं है। इससे कोई फर्क नहीं पड़ता कि स्टैक कम या उच्च पते पर बढ़ता है या नहीं। स्टैक का "शीर्ष" हमेशा ऐसा होता है जहां अगला मान धकेल दिया जाएगा (स्टैक के शीर्ष पर रखा जाएगा), या, अन्य आर्किटेक्चर पर, जहां अंतिम धक्का मूल्य डाल दिया गया है और जहां यह वर्तमान में देता है। इसलिए, ईएसपी हमेशा स्टैक के शीर्ष पर इंगित करता है ।
बारबराकर्क

1
नीचे या आधार ढेर के, दूसरे हाथ पर, जहां पहले (या सबसे पुराना ) मूल्य डाल दिया गया है, और फिर और अधिक हाल के मूल्यों से कवर किया। यहीं से EBP के लिए "बेस पॉइंटर" नाम आया: यह एक सबरूटीन के वर्तमान स्थानीय स्टैक के आधार (या नीचे) को इंगित करने वाला था।
बारबराकर्क

बारबरा, इंटेल x86 में, स्टैक UPSIDE DOWN है। स्टैक के शीर्ष में स्टैक पर धकेल दिया गया पहला आइटम होता है और प्रत्येक आइटम को पुश करने के बाद शीर्ष आइटम को धक्का दिया जाता है। ढेर के नीचे वह जगह है जहां नए आइटम रखे जाते हैं। कार्यक्रम 1k से शुरू होने वाले स्मृति में रखे जाते हैं और अनंत तक बढ़ते हैं। स्टैक अनंत से शुरू होता है, वास्तविक रूप से अधिकतम मेम न्यूनतम रॉम, और एक पते पर 0. ईएसपी अंक की ओर बढ़ता है जिसका मूल्य उस पहले पते से कम है जिसे धक्का दिया गया है।
19uc में jmucchiello

1

लंबे समय से मैंने विधानसभा प्रोग्रामिंग की है, लेकिन यह लिंक उपयोगी हो सकता है ...

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

स्टैक पॉइंटर का उपयोग ज्यादातर तब किया जाता है जब आप अन्य प्रक्रियाओं को कॉल कर रहे होते हैं। आधुनिक संकलक के साथ, डेटा का एक गुच्छा पहले स्टैक पर डंप किया जाएगा, इसके बाद रिटर्न एड्रेस होगा ताकि सिस्टम को पता चल जाएगा कि लौटने के लिए एक बार कहां जाना है। स्टैक पॉइंटर अगले स्थान पर इंगित करेगा जहां नए डेटा को स्टैक पर धकेला जा सकता है, जहां यह तब तक रहेगा जब तक यह फिर से पॉपअप नहीं हो जाता।

बेस रजिस्टर या सेगमेंट रजिस्टर बड़ी मात्रा में डेटा के पता स्थान को इंगित करता है। दूसरे रजिस्टर के साथ संयुक्त, बेस पॉइंटर मेमोरी को विशाल ब्लॉकों में विभाजित करेगा जबकि दूसरा रजिस्टर इस ब्लॉक के भीतर एक आइटम पर इंगित करेगा। आधार बिंदु डेटा के ब्लॉक के आधार को इंगित करते हैं।

ध्यान रखें कि असेंबली बहुत सीपीयू विशिष्ट है। सीपीयू के विभिन्न प्रकारों के बारे में जानकारी प्रदान करने के लिए मैंने जो पेज लिंक किया है।


खंड पंजीयन x86 पर अलग-अलग हैं - वे gs, cs, ss हैं, और जब तक आप स्मृति प्रबंधन सॉफ़्टवेयर नहीं लिख रहे हैं, तब तक आप उन्हें स्पर्श नहीं करते हैं।
माइकल

ds भी एक सेगमेंट रजिस्टर है और MS-DOS और 16-बिट कोड के दिनों में, आपको निश्चित रूप से इन सेगमेंट रजिस्टर को कभी-कभी बदलने की आवश्यकता होती है, क्योंकि वे कभी भी 64 KB से अधिक रैम की ओर इशारा नहीं कर सकते हैं। फिर भी डॉस 1 एमबी तक मेमोरी एक्सेस कर सकता है क्योंकि इसमें 20-बिट एड्रेस पॉइंट का इस्तेमाल किया गया है। बाद में हमें 32-बिट्स सिस्टम मिला, जिसमें कुछ 36-बिट्स एड्रेस रजिस्टर और अब 64-बिट्स रजिस्टर हैं। इसलिए आजकल आपको वास्तव में इन सेगमेंट रजिस्टर को बदलने की आवश्यकता नहीं होगी।
दस ब्रिंक

कोई भी आधुनिक OS 386 खंडों का उपयोग नहीं करता है
Ana Betts

@Paul: गलत! गलत! गलत! 16-बिट सेगमेंट को 32-बिट सेगमेंट द्वारा प्रतिस्थापित किया जाता है। संरक्षित मोड में, यह मेमोरी के वर्चुअलाइजेशन की अनुमति देता है, मूल रूप से प्रोसेसर को तार्किक लोगों को भौतिक पते मैप करने की अनुमति देता है। हालाँकि, आपके आवेदन में, चीजें अभी भी सपाट लगती हैं, क्योंकि ओएस ने आपके लिए मेमोरी को वर्चुअलाइज किया है। कर्नेल संरक्षित मोड में काम करता है, जिससे एप्लिकेशन एक फ्लैट मेमोरी मॉडल में चल सकते हैं। En.wikipedia.org/wiki/Protected_mode
Wim ten Brink

@Workshop ALex: यह एक तकनीकी है। सभी आधुनिक OS सभी खंडों को [0, FFFFFFFF] पर सेट करते हैं। यह वास्तव में गिनती नहीं है। और यदि आप लिंक किए गए पृष्ठ को पढ़ेंगे, तो आप देखेंगे कि सभी फैंसी सामान पृष्ठों के साथ किए गए हैं, जो कि तब बहुत अधिक बारीक-बारीक होते हैं।
MSALters

-4

संपादित करें हाँ, यह ज्यादातर गलत है। यह किसी के हित में होने पर पूरी तरह से अलग कुछ का वर्णन करता है :)

हाँ, स्टैक पॉइंटर स्टैक के शीर्ष पर इंगित करता है (चाहे वह पहला खाली स्टैक स्थान हो या अंतिम पूर्ण मैं अनिश्चित हूं)। आधार पॉइंटर उस अनुदेश के मेमोरी लोकेशन को इंगित करता है जिसे निष्पादित किया जा रहा है। यह opcodes के स्तर पर है - सबसे बुनियादी निर्देश जो आप कंप्यूटर पर प्राप्त कर सकते हैं। प्रत्येक ओपकोड और उसके मापदंडों को एक मेमोरी स्थान में संग्रहीत किया जाता है। एक ओ या सी ++ या सी # लाइन का एक ओपकोड में अनुवाद किया जा सकता है, या यह कितना जटिल है, इसके आधार पर दो या अधिक का एक क्रम। इन्हें प्रोग्राम मेमोरी में क्रमिक रूप से लिखा और निष्पादित किया जाता है। सामान्य परिस्थितियों में बेस पॉइंटर को एक निर्देश दिया जाता है। कार्यक्रम नियंत्रण (गोटो, आईएफ, आदि) के लिए इसे कई बार बढ़ाया जा सकता है या बस अगले मेमोरी पते से बदला जा सकता है।

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


मुझे समझने में थोड़ी परेशानी हो रही है कि ईबप क्या है। अगर हमारे पास MASM कोड की 10 लाइनें हैं, तो इसका मतलब है कि जैसे-जैसे हम उन लाइनों को चलाते जा रहे हैं, ईबीपी हमेशा बढ़ता जाएगा?
dev:

1
@Douroured - नहीं। यह सच नहीं है। ईप बढ़ रहा होगा।
माइकल

आपका मतलब है कि मैंने जो कहा वह सही है लेकिन ईबीपी के लिए नहीं, बल्कि आईईपी के लिए, क्या यह है?
ईविलियम

2
हाँ। EIP निर्देश सूचक है और प्रत्येक निर्देश के निष्पादित होने के बाद इसे संशोधित किया जाता है।
माइकल

2
ऊह मेरी बुर। मैं एक अलग पॉइंटर के बारे में सोच रहा हूं। मुझे लगता है कि मैं अपने दिमाग को धो दूंगा।
स्टीफन फ्राइडरिच्स

-8

esp "विस्तारित स्टैक पॉइंटर" के लिए खड़ा है ..... "समथिंग बेस पॉइंटर" के लिए ईबप .... और "समथिंग इंस्ट्रक्शन पॉइंटर" के लिए ईप ... स्टैक पॉइंटर स्टैक सेगमेंट के ऑफसेट पते पर इंगित करता है । बेस पॉइंटर अतिरिक्त खंड के ऑफसेट पते की ओर इशारा करता है। निर्देश सूचक कोड खंड के ऑफसेट पते को इंगित करता है। अब, खंडों के बारे में ... वे प्रोसेसर मेमोरी क्षेत्र के छोटे 64KB विभाजन हैं ..... इस प्रक्रिया को मेमोरी सेगमेंटेशन के रूप में जाना जाता है। मुझे उम्मीद है कि यह पोस्ट सहायक थी।


3
यह एक पुराना प्रश्न है, हालांकि, एसपी स्टैक पॉइंटर के लिए खड़ा है, बीपी का मतलब बेस पॉइंटर के लिए है और इंस्ट्रक्शन पॉइंटर के लिए आईपी है। हर किसी की शुरुआत में ई यह कह रहा है कि यह 32 बिट पॉइंटर है।
हाइड डेन्स

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