2010-05-20 12 views
6

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

donot कृपया मुझे दे निम्न या किसी भी इसी तरह उत्तर:

"एक बहुत ही सूचक और एक विशाल सूचक के बीच फर्क सिर्फ इतना है कि एक बड़ा सूचक संकलक द्वारा सामान्यीकृत है एक सामान्यीकृत सूचक एक है कि। सेगमेंट में जितना संभव हो उतना पता है, जिसका अर्थ है कि ऑफ़सेट 15 से बड़ा नहीं होता है। एक बड़ा पॉइंटर सामान्य होता है जब पॉइंटर अंकगणित पर किया जाता है। असाइनमेंट होने पर सामान्यीकृत नहीं होता है। आप इसका कारण बन सकते हैं बढ़ते हुए मूल्य को बदलने के बिना सामान्यीकृत किया जाना चाहिए और फिर इसे कम करना। ऑफ़सेट 16 से कम होना चाहिए क्योंकि सेगमेंट 16 से अधिक या उसके बराबर किसी भी मान का प्रतिनिधित्व कर सकता है (उदाहरण के लिए पूर्ण पता 0x17 सामान्यीकृत रूप में 0001:0001 होगा। जबकि एक दूर सूचक 0x170000:0017 के साथ पूर्ण पते को संबोधित कर सकता है, यह वैध वैध (सामान्यीकृत) सूचक नहीं है क्योंकि ऑफ़सेट 0000F से अधिक है।)। विशाल संकेत भी बढ़ती जा सकता है और अंकगणितीय ऑपरेटर का उपयोग कर कम कर दिया है, लेकिन सामान्य कर रहे हैं वे अब तक संकेत की तरह लपेट नहीं होंगे। "

यहाँ सामान्य अवधारणा बहुत अच्छी तरह से समझाया नहीं है, या हो सकता है मैं करने में असमर्थ हूँ यह बहुत अच्छी तरह से समझते हैं।

किसी को भी देखने के एक शुरुआती बिंदु से इस अवधारणा को समझाने की कोशिश कर सकते हैं।

धन्यवाद, Rahamath

+0

यह कौन सा मंच है? 16-बिट एड्रेस स्पेस के साथ एम्बेडेड लक्ष्य का कुछ प्रकार? ऐसा लगता है कि सरल रैखिक पते होने के विपरीत, दूर/विशाल पॉइंटर्स में वास्तव में एक सेगमेंट और ऑफसेट होता है। – tomlogic

+5

1985 कहा जाता है, इसकी लंगड़ा प्रौद्योगिकी वापस चाहता है। – ergosys

+0

ergosys, आपको यह जानने के लिए surprized किया जाएगा कि अभी भी उपयोग में 80186 आर्किटेक्चर के आधार पर एम्बेडेड नियंत्रक हैं, और जब वे अब इंटेल और एएमडी द्वारा विज्ञापित नहीं हैं, तो भी आप उन्हें खरीद सकते हैं। –

उत्तर

13

शुरुआत में 8086 8 बिट प्रोसेसर 8085 का विस्तार था। 8085 केवल 16 बिट एड्रेस बस के साथ 65536 बाइट्स को संबोधित कर सकता था। जब इंटेल ने 8086 विकसित किया, तो वे चाहते थे कि सॉफ़्टवेयर पुराने 8 बिट प्रोसेसर के लिए जितना संभव हो उतना संगत हो, इसलिए उन्होंने सेगमेंट मेमोरी एड्रेसिंग की अवधारणा पेश की। इसने ध्यान देने के बिना बड़ी पता सीमा में रहने के लिए 8 बिट सॉफ़्टवेयर चलाने की अनुमति दी। 8086 में 20 बिट एड्रेस बस थी और इस प्रकार 1 एमबी मेमोरी (2^20) तक संभाल सकती है। दुर्भाग्य से यह इस स्मृति को सीधे संबोधित नहीं कर सका, इसे करने के लिए सेगमेंट रजिस्टरों का उपयोग करना पड़ा। असली पता 16 बिट ऑफसेट में जोड़ा गया 16 बिट सेगमेंट वैल्यू जोड़कर 16 बिट ऑफसेट में जोड़ा गया था।

Example: 
Segment 0x1234 Offset 0x5678 will give the real address 
    0x 1234 
    +0x 5678 
    --------- 
    =0x 179B8 

आपने गौर किया होगा के रूप में, इस आपरेशन द्विभाजित नहीं है, जिसका अर्थ है आप खंड और ऑफसेट के अन्य संयोजन के साथ वास्तविक पते उत्पन्न कर सकते हैं।

0x 1264    0x 1111 
    +0x 5378    +0x 68A8 
    ---------    ---------  etc. 
    =0x 179B8    =0x 179B8 

वहाँ क्योंकि 3 ओवरलैपिंग निबल (3*4 = 12 बिट्स, 2^12 = 4096) की, 4096 विभिन्न संयोजनों संभव वास्तव में कर रहे हैं। सामान्यीकृत संयोजन 4096 संभावित मूल्यों में से एकमात्र है जिसमें ऑफ़सेट के 3 उच्च निबल्स शून्य हो जाएंगे। हमारे उदाहरण में यह हो जाएगा:

0x 179B 
    +0x 0008 
    --------- 
    =0x 179B8 

एक far और एक huge सूचक के बीच अंतर सामान्य में नहीं है, आप गैर सामान्यीकृत huge सूचक हो सकता है, यह absolutly अनुमति दी गई है। पॉइंटर अंकगणित करते समय उत्पन्न कोड में अंतर होता है। पॉइंटर्स में मूल्यों को बढ़ाने या जोड़ने पर दूर पॉइंटर्स के साथ कोई ओवरफ़्लो हैंडलिंग नहीं होगी और आप केवल 64K मेमोरी को संभालने में सक्षम होंगे।

char far *p = (char far *)0x1000FFFF; 
p++; 
printf("p=%p\n"); 

प्रिंट 1000:0000 विशाल सूचकों के लिए संकलक कोड को संभालने के लिए आगे ले जाना आवश्यक उत्पन्न होगा होगा।

char huge *p = (char huge *)0x1000FFFF; 
p++; 
printf("p=%p\n"); 

प्रिंट होगा 2000:0000

इसका मतलब है आप जब दूर का उपयोग कर या बड़ा संकेत के रूप में उन लोगों के साथ गणित की लागत अलग है सावधान रहना होगा।

किसी को यह भी नहीं भूलना चाहिए कि अधिकांश 16 बिट कंपाइलर्स में पुस्तकालय थे जो इन मामलों को सही ढंग से कभी-कभी छोटी गाड़ी सॉफ्टवेयर नहीं देते थे। माइक्रोस्कोफ्ट वास्तविक मोड कंपाइलर ने अपने सभी स्ट्रिंग फ़ंक्शंस पर विशाल पॉइंटर्स को संभाल नहीं लिया। बोरलैंड भी मेम फ़ंक्शंस के रूप में भी बदतर था (memcpy, memset, आदि) ऑफ़सेट ओवरफ़्लो को संभाल नहीं पाए। यही वजह है कि इन पुस्तकालय कार्यों के साथ सामान्यीकृत पॉइंटर्स का उपयोग करना एक अच्छा विचार था, ऑफसेट ओवरफ्लो की संभावना उनके साथ कम थी।

+0

इस अद्भुत व्याख्या के लिए धन्यवाद !! – wrapperm

10

को समझने के लिए है कि कैसे एक खंडित सूचक एक रेखीय में बदल जाता है पहली बात पता। उदाहरण के लिए आप के लिए, रूपांतरण है:

linear = segment * 16 + offset; 
इस कारण से

, यह वहाँ एक ही रैखिक पता व्यक्त किया जा सकता पता चला है अलग सेगमेंट का उपयोग करें/ऑफसेट संयोजन। उदाहरण के लिए, निम्नलिखित खंड/ऑफसेट संयोजन सभी एक ही रैखिक पते का संदर्भ लें:

0004:0000 
0003:0010 
0002:0020 
0001:0030 
0000:0040 

इस के साथ समस्या यह है कि आप 0010:0020, एक की एक खंडित पते के साथ 0100:0000 के हिस्सों में बंटा हुआ पता और ptr2 साथ ptr1 किया है सरल तुलना निर्धारित करेगा कि ptr1 != ptr2 भले ही वे वास्तव में एक ही पते पर इंगित करें।

सामान्यीकरण वह प्रक्रिया है जिसके द्वारा आप एक पते को एक रूप में रूपांतरित करते हैं, जैसे कि यदि दो गैर-सामान्यीकृत पॉइंटर्स एक ही रैखिक पते का संदर्भ लेते हैं, तो वे दोनों एक ही सामान्यीकृत रूप में परिवर्तित हो जाएंगे।

+0

+1, मैं अपने जवाब में भूल गया। –

+0

संख्याएं गलत हैं, 0100: 0000 == 00FF: 0010 == 00FE: 0020, आदि –

+0

@ हंसपैसेंट - डांग, किसी कारण से मैंने इंडेक्स पर सेगमेंट और हेक्स के लिए बाइनरी का उपयोग किया। इसे ठीक कर देगा .. –

1

मुझे याद है के रूप में, यह कुछ इस तरह है:

  • पास संकेत दिए गए एक ही खंड में याद करने के लिए बिंदु (सूचक के रूप में)।
  • सुदूर पॉइंटर्स अन्य खंड में स्मृति को इंगित करते हैं।
  • विशाल पॉइंटर्स आपको स्मृति से इंगित करते हैं जो एक सेगमेंट से बड़ा है (इसलिए आपके पास ब्लॉक> 64k हो सकता है और आपके पॉइंटर पर अंकगणित हो सकता है, और सैमुअल ने क्या कहा)।

यदि आप एक नौसिखिया हैं, तो शायद यह भूलना सबसे अच्छा है कि आपने लगभग/दूर/विशाल के बारे में सुना है। उनके पास केवल पुराने 16-बिट खंडित मेमोरी मॉडल में अर्थ है जो आमतौर पर इंटेल 80x86 के प्रारंभ में देखा जाता है। 32- और 64-बिट भूमि (यानी, 1 99 4 से सबकुछ) में, स्मृति सिर्फ एक बड़ा संगत ब्लॉक है, इसलिए एक सूचक केवल एक सूचक (जहां तक ​​एक ही आवेदन संबंधित है)।

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