2013-02-12 30 views
5

मैं निष्पादन योग्य के "सामान्य" खंड के बारे में अधिक समझने की कोशिश कर रहा हूं और मैंने देखा है कि संकलित कोड पर objdump करने पर, मैं सामान्य कोड में केवल ऑब्जेक्ट फ़ाइलों (*.o) पर सामान्य कोड में रखे गए चर देख सकता हूं।सामान्य अनुभाग चर केवल ऑब्जेक्ट फ़ाइल में निष्पादन योग्य क्यों नहीं दिखाते हैं?

वह क्यों है?

//test.c 

int i[1000]; 
int main(){return 0;} 

निर्माण आदेश:

> gcc -g0 -fcommon -c test.c 
> gcc -g0 -fcommon test.c 

objdump प्रतीक तालिका में आम खंड में i पता चलता है:

> objdump -x test.o 
    ... 
    SYMBOL TABLE: 
    ... 
    00000fa0 O *COM* 00000020 i 

जब तक मैं निष्पादन पर चला:

> objdump -x a.out 
    ... 
    SYMBOL TABLE: 
    ... 
    0804a040 g O .bss 00000fa0 i 

यदि मैं ऑब्जेक्ट फ़ाइल को -fno-common ध्वज के साथ पुनर्निर्माण करता हूं, तो यह .bss सेगमेंट में दिखाई देता है जैसे कि यह निष्पादन योग्य पर होता है। क्या अंतिम निष्पादन योग्य के पास यह "COMMON" अनुभाग नहीं है?

उत्तर

6

आम अनुभाग कुछ ऐसा है जो लिंकर के बारे में जानता है। यह मूल रूप से सभी common सामग्री को तीन या चार वास्तविक खंडों में से एक में डालता है [एक विशिष्ट] निष्पादन योग्य (कोड या टेक्स्ट, डेटा, बीएसएस - कभी-कभी एक रॉडाटा भी होता है)।

तो, इस मामले में आपका चर .bss में समाप्त होता है, क्योंकि उन्हें प्रारंभ नहीं किया जाता है।

-fcommon/ -fno-common

सी कोड में पर

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

तो, -fno-common या -fcommon केवल सकारात्मक प्रभाव पड़ेगा अगर वहाँ एक से अधिक वैश्विक चर कहा i [और वे एक ही आकार का होना चाहिए है, या अपने कार्यक्रम अमान्य हो जाता है, जो अपरिभाषित व्यवहार एक से ग्रेड बदतर है !]

+0

ठीक है ... तो आम अनुभाग का बिंदु क्या है?'fcommon' और' fno-common 'दोनों के साथ अंतिम परिणाम निष्पादन योग्य के .bs सेगमेंट में अनियमित चर समाप्त होता है; या यह उसी कारण से अस्तित्व में है जिसे आपने लिखा था "[एक ठेठ]" '? जिसका अर्थ है कि – Mike

+2

@ माइक हैं लेकिन कंपाइलर को इसके बारे में पता नहीं है- यह पता लगाने के लिए लिंकर्स नौकरी है। लक्ष्य (और निष्पादन योग्य प्रारूप) जो एक .bss अनुभाग प्रदान करते हैं, बीएसएस अनुभाग सामान्य रूप से आवंटित किया जाता है और रनटाइम पर प्रारंभ किया जाता है। उन लक्ष्यों पर जिनके पास क्षमता नहीं है, आम अनुभाग निष्पादन योग्य में समाप्त होते हैं, और यदि आपके पास 10 एमबी की वैश्विक सरणी है, तो आपका निष्पादन योग्य 10 एमबी बड़ा होता है। यह आपको अपनी खुद की लिंकर स्क्रिप्ट लिखने की अनुमति देता है, और उन सामान्य वर्गों को स्थान देता है जहां आप उन्हें चाहते हैं। -फनो-आम के पास अन्य उपयोग हैं, जो कि जीसीसी मैन पेज हालांकि बताते हैं। – nos

+0

मैंने कहा "एक ठेठ" क्योंकि कुछ आर्किटेक्चर में अतिरिक्त अनुभाग जोड़ना संभव है, और इन वर्गों को सभी प्रकार के विशेषताओं को भी असाइन किया जा सकता है। सभी कंपाइलर्स, लिंकर्स इत्यादि इसका समर्थन नहीं करेंगे, और बड़ी संख्या में ओएस आर्किटेक्चर के साथ 'जीसीसी' बड़ी संख्या में सिस्टम चलाने में सक्षम है। मैं नहीं चाहता था कि किसी को यह इंगित करने के लिए कि ओएस ग्लूर्फ पर, लिंकर एक्स के साथ, आपके पास अनुभाग हैं ..., आदि –

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

  • कोई संबंधित समस्या नहीं^_^