.Bss खंड की आवश्यकता क्यों है?


120

मुझे पता है कि वैश्विक और स्थिर चर .dataखंड में संग्रहीत किए गए हैं , और खंड में अनइंस्टॉल किए गए डेटा हैं .bss। मुझे समझ में नहीं आता है कि हमारे पास असिंचित चर के लिए समर्पित खंड क्यों है? यदि रन के समय में एक अनइंस्टाल्यूटेड वैरिएबल का मान दिया गया है, तो क्या वैरिएबल अभी भी .bssसेगमेंट में मौजूद है ?

निम्नलिखित कार्यक्रम में, aमें है .dataखंड, और bमें है .bssखंड; क्या वो सही है? अगर मेरी समझ गलत है तो कृपया मुझे सही करें।

#include <stdio.h>
#include <stdlib.h>

int a[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9};
int b[20]; /* Uninitialized, so in the .bss and will not occupy space for 20 * sizeof (int) */

int main ()
{
   ;
}  

इसके अलावा, निम्नलिखित कार्यक्रम पर विचार करें,

#include <stdio.h>
#include <stdlib.h>
int var[10];  /* Uninitialized so in .bss */
int main ()
{
   var[0] = 20  /* **Initialized, where this 'var' will be ?** */
}

3
आप बीएसएस को बेटर सेव स्पेस के रूप में पढ़ सकते हैं ।
smwikipedia

जवाबों:


89

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

for(i=0; i<all_explicitly_initialized_objects; i++)
{
  .data[i] = init_value[i];
}

memset(.bss, 
       0, 
       all_implicitly_initialized_objects);

जहाँ .data और .bs को रैम में संग्रहीत किया जाता है, लेकिन init_value को रोम में संग्रहीत किया जाता है। यदि यह एक खंड था, तो ROM को बहुत सारे शून्य से भरा जाना था, जिससे ROM का आकार काफी बढ़ गया।

रैम-आधारित निष्पादन योग्य समान रूप से काम करते हैं, हालांकि निश्चित रूप से उनके पास कोई सच्चा ROM नहीं है।

इसके अलावा, मेमसेट की संभावना बहुत कुशल इनलाइन कोडांतरक है, जिसका अर्थ है कि स्टार्टअप कॉपी-डाउन को तेजी से निष्पादित किया जा सकता है।


7
स्पष्ट करने के लिए: .data और .bs के बीच एकमात्र अंतर यह है कि स्टार्ट-अप पर, "कॉपी-डाउन" को क्रमिक रूप से चलाया जा सकता है, इसलिए तेजी से। यदि इसे दो खंडों में विभाजित नहीं किया गया, तो आरंभीकरण को असिंचित चर से संबंधित रैम स्पॉट को छोड़ना होगा, ताकि समय बर्बाद हो।
CL22

80

.bssखंड एक अनुकूलन है। पूरे .bssखंड को एक एकल संख्या, शायद 4 बाइट्स या 8 बाइट्स द्वारा वर्णित किया गया है, जो कि चलने की प्रक्रिया में अपना आकार देता है, जबकि .dataखंड आरंभिक चर के आकार के योग जितना बड़ा है। इस प्रकार, .bssनिष्पादन योग्य को लोड करने के लिए छोटा और तेज बनाता है। अन्यथा, चर .dataशून्य के लिए स्पष्ट प्रारंभ के साथ खंड में हो सकते हैं ; कार्यक्रम को अंतर बताने के लिए कड़ी मेहनत की जाएगी। (विस्तार में, वस्तुओं का पता .bssसम्भवत: उस .dataखंड के पते से भिन्न होगा ।)

पहले कार्यक्रम aमें, .dataखंड में bहोगा और .bssनिष्पादन योग्य क्षेत्र में होगा। एक बार कार्यक्रम लोड होने के बाद, अंतर स्थिर हो जाता है। रन समय में, बाइट्स पर bकब्जा कर लेता है 20 * sizeof(int)

दूसरे कार्यक्रम में, varस्थान आवंटित किया जाता है और main()उस स्थान को संशोधित करता है। ऐसा होता है कि सेगमेंट के बजाय सेगमेंट के लिए स्थान varका वर्णन किया गया था , लेकिन यह उस तरीके को प्रभावित नहीं करता है जिस तरह से प्रोग्राम चलने पर व्यवहार करता है।.bss.data


16
उदाहरण के लिए, कई बिन बुर्ज वाले 4096 बाइट्स की लंबाई पर विचार करें। क्या आप उन सभी 4k बफ़र्स को बाइनरी के आकार में योगदान देना चाहेंगे? यह काफी जगह बर्बाद होगी।
जेफ मर्काडो

1
@ जोनाथन हत्यारा: एकल नंबर द्वारा वर्णित पूरे बीएसएस खंड क्यों है ??
सूरज जैन

@JonathanLeffler मेरा मतलब है कि सभी शून्य प्रारंभिक स्थिर वैरिएबल bss में जाते हैं। तो क्या इसका मूल्य सिर्फ शून्य नहीं होना चाहिए? और यह भी कि उन्हें स्थान पर जगह क्यों नहीं दी गई है। डेटा अनुभाग इतना धीमा कैसे कर सकता है?
सूरज जैन

2
@ सुरजजैन: संग्रहित संख्या शून्य से भरे जाने वाले बाइट्स की संख्या है। जब तक कि इस तरह के कोई असिंचित चर नहीं हैं, तब तक bss अनुभाग की लंबाई शून्य नहीं होगी, भले ही सभी बाइट्स I bss अनुभाग शून्य हो जाएगा, जब प्रोग्राम लोड हो जाएगा।
जोनाथन लेफ्लर

1
निष्पादन योग्य में .bs अनुभाग केवल एक संख्या है। स्मृति प्रक्रिया छवि में .bss अनुभाग आम तौर पर .data अनुभाग से सटे स्मृति है और अक्सर रनटाइम .data अनुभाग .bs के साथ संयुक्त होता है; रनटाइम मेमोरी में कोई भेद नहीं किया गया है। कभी-कभी, आप पा सकते हैं कि bss की शुरुआत कहाँ से हुई ( edata)। व्यावहारिक रूप में, .bss स्मृति में मौजूद नहीं है, जब प्रक्रिया की छवि पूरी हो जाती है; शून्य डेटा .data अनुभाग का सरल हिस्सा है। लेकिन विवरण ओ / एस आदि के आधार पर भिन्न होता है
जोनाथन लेफ़लर

15

से विधानसभा भाषा चरण-दर-चरण: लिनक्स के साथ प्रोग्रामिंग के बारे में जेफ Duntemann द्वारा, .data अनुभाग:

.Data अनुभाग initialized डेटा वस्तुओं के डेटा परिभाषाओं में शामिल है। आरंभिक डेटा वह डेटा है जिसका प्रोग्राम चलने से पहले एक मान होता है। ये मान निष्पादन योग्य फ़ाइल का हिस्सा हैं। जब निष्पादन योग्य फ़ाइल को निष्पादन के लिए मेमोरी में लोड किया जाता है तो उन्हें मेमोरी में लोड किया जाता है।

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

और .bs वर्ग:

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

.Data अनुभाग में परिभाषित डेटा आइटम और .bs अनुभाग में डेटा आइटम के बीच एक महत्वपूर्ण अंतर है: .data अनुभाग में डेटा आइटम आपकी निष्पादन योग्य फ़ाइल के आकार में जोड़ते हैं। .Bs अनुभाग में डेटा आइटम नहीं है। एक बफ़र जो 16,000 बाइट्स (या कभी-कभी अधिक, कभी-कभी अधिक) लेता है, उसे .bs में परिभाषित किया जा सकता है और निष्पादन योग्य फ़ाइल आकार में लगभग कुछ भी नहीं (विवरण के लिए लगभग 50 बाइट्स) जोड़ सकता है।


9

ठीक है, सबसे पहले, आपके उदाहरण में जो चर हैं, वे असंगठित नहीं हैं; C निर्दिष्ट करता है कि स्थिर वैरिएबल अन्यथा इनिशियलाइज़ नहीं किए गए हैं 0 के लिए इनिशियलाइज़ किए गए हैं।

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

प्रोग्राम चलाते समय, प्रोग्राम लोडर .data और .bss को मेमोरी में लोड करेगा। .Data या .bs में रहने वाली वस्तुओं में इस प्रकार केवल स्मृति में जाते हैं, वे किसी भी बिंदु पर बाइनरी डिस्क पर फ्लश नहीं होते हैं।


5

सिस्टम वी ABI 4.1 (1997) (उर्फ ELF विनिर्देश) भी जवाब शामिल हैं:

.bssयह खंड अनइंस्टाल्यूटेड डेटा रखता है जो प्रोग्राम की मेमोरी इमेज में योगदान देता है। परिभाषा के अनुसार, प्रोग्राम शुरू होने पर सिस्टम शून्य के साथ डेटा को इनिशियलाइज़ करता है। अनुभाग में कोई फ़ाइल स्थान नहीं है, जैसा कि अनुभाग प्रकार द्वारा इंगित किया गया है SHT_NOBITS

का कहना है कि अनुभाग नाम .bssआरक्षित है और इसके विशेष प्रभाव हैं, विशेष रूप से यह कोई फ़ाइल स्थान नहीं रखता है , इस प्रकार लाभ खत्म हो गया है .data

नकारात्मक पक्ष यह है कि सभी बाइट्स को 0तब सेट किया जाना चाहिए जब ओएस उन्हें मेमोरी पर रखता है, जो अधिक प्रतिबंधात्मक है, लेकिन एक सामान्य उपयोग का मामला है, और अनइंस्टॉल किए गए चर के लिए ठीक काम करता है।

SHT_NOBITSअनुभाग इस प्रकार के दस्तावेज़ को दोहराता है कि प्रतिज्ञान:

sh_sizeयह सदस्य बाइट में अनुभाग का आकार देता है। जब तक अनुभाग प्रकार नहीं होता है SHT_NOBITS, तब तक अनुभाग sh_size फ़ाइल में बाइट्स रखता है । प्रकार के एक खंड में SHT_NOBITSएक गैर-शून्य आकार हो सकता है, लेकिन यह फ़ाइल में कोई स्थान नहीं रखता है।

सी मानक वर्गों के बारे में कुछ नहीं कहता है, लेकिन हम आसानी से सत्यापित कर सकते हैं कि लिनक्स में कहां चर संग्रहित है objdumpऔर इसके साथ ही readelfनिष्कर्ष निकाला जाता है कि असिंचित ग्लोबल्स वास्तव में संग्रहित हैं .bss। उदाहरण के लिए इस उत्तर को देखें: C में घोषित, गैर-पंजीकृत चर का क्या होता है?


3

विकिपीडिया लेख .bs एक अच्छा ऐतिहासिक विवरण प्रदान करता है, यह देखते हुए कि यह शब्द 1950 के मध्य से है (मेरे जन्मदिन की बधाई;;

दिन में वापस, हर बिट कीमती था, इसलिए आरक्षित खाली स्थान को संकेत देने के लिए कोई भी तरीका उपयोगी था। यह ( .bs ) वह है जो अटक गया है।

.data सेक्शन अंतरिक्ष के लिए है जो खाली नहीं है, बल्कि इसमें (आपके) परिभाषित मूल्य होंगे।

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