2012-06-24 2 views
6

क्या कोई विशेष वैश्विक सरणी शून्य पर प्रारंभ करने के लिए जीसीसी को बताने का कोई तरीका नहीं है?फोर्स जीसीसी को कुछ ग्लोबल्स शून्य करने के लिए मजबूर करना

मैं एक बड़ी डेटा संरचना है कि मेरे कोड का प्रबंधन करता है भंडारण के लिए स्मृति का एक बड़ा हिस्सा आरक्षित करना चाहते हैं, तो मैं कहना:

#define SIZE_16_MB 0x01000000 
BYTE mChunkSpace[SIZE_16_MB]; 

समस्या यह है कि crtinit() इस स्थान प्रारंभ करने में एक लाख साल लेता है शून्य करने के लिए, और यह बिल्कुल जरूरी नहीं है।

क्या कोई तरीका है कि मैं इसे उस स्थान को शुरू करने के लिए मजबूर नहीं कर सकता हूं?

वर्तमान में मैं एक स्मृति पता हार्ड कोडिंग कर रहा हूं जो लिंकर के बारे में जानता है, लेकिन यह चीजों को करने का एक विशेष रूप से मजबूत तरीका नहीं है।

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

उत्तर

6

आप gcc विशेषताओं का उपयोग किसी अन्य नए मेमोरी सेक्शन में संग्रहीत करने के लिए कर सकते हैं, उदाहरण के लिए .noinit मेमोरी सेक्शन में।

BYTE mChunkSpace[SIZE_16_MB] __attribute__ ((section (".noinit"))); 
+0

मैंने इस पर खुद को ठोकर खाई, लेकिन मुझे यह पता लगाना मुश्किल था कि यह कैसे कार्यान्वित किया जाता है और यदि यह अपने लक्षित मंच पर ओपी के लिए उपलब्ध होगा। मैं '.noinit' सेक्शन को '.bss' सेक्शन में बता सकता हूं। क्या इसका मतलब यह शून्य प्रारंभ नहीं हुआ है * और * निष्पादन योग्य में ~ 16 एमबी स्पेस नहीं लेता है? –

+0

@EdS। 'आकार-ए-एक्स' मुझे दिखाता है कि स्मृति खंड का पता '.bsssection के पते से अलग है। – ouah

+0

मैं जो कुछ पढ़ता हूं उसे दोहरा रहा हूं: http://www.nongnu.org/avr-libc/user-manual/mem_sections.html –

-2

मानक कहता है कि स्थैतिक डेटा जो घोषणा के बिंदु पर स्पष्ट रूप से प्रारंभ नहीं किया गया है, शून्य-प्रारंभिक होगा। आप एक गैर शून्य मान अपने आप को पहला तत्व आरंभ द्वारा क्रम प्रारंभ से बच सकते हैं:

#define SIZE_16_MB 0x01000000 
BYTE mChunkSpace[SIZE_16_MB] = {1}; 

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

बेशक, यह परिणामस्वरूप निष्पादन योग्य (~ 16 एमबी बड़ा सटीक होना) होगा, लेकिन स्मृति को रनटाइम पर प्रारंभ नहीं किया जाएगा। तो सवाल यह है कि आप के लिए क्या maters; उस स्मृति को शून्य करने के लिए आवश्यक समय, या परिणामी निष्पादन योग्य आकार?

BYTE* mChunkSpace = (BYTE*)malloc(SIZE_16_MB * sizeof(BYTE)); 

फिर इस डेटा अप्रारंभीकृत और आप इसे प्रारंभ करने के लिए इंतज़ार कर रहा है:

+0

इस गैर-रचनात्मक टिप्पणी के लिए खेद है- मेरे पास कोई अच्छा समाधान नहीं है, मैंने लगभग 'mChunkSpace' को मजाक के रूप में 'मुख्य()' के स्थानीय स्थान बनाने का सुझाव दिया है, लेकिन अभ्यास में काम करने की संभावना नहीं है। वैसे भी, जब आप कहते हैं "लेकिन स्मृति को रनटाइम पर प्रारंभ नहीं किया जाएगा": इसे इसके बजाय स्थायी संग्रहण से लोड किया जाएगा। यह तेजी से होने की संभावना नहीं है। –

+1

आप यह नियंत्रित कर सकते हैं कि जीसीसी शून्य-प्रारंभिक चर को -b [no-] शून्य-प्रारंभिक-इन-बीएसएस ध्वज के साथ .bss में रखता है या नहीं। डिफ़ॉल्ट है -फेजो-प्रारंभिक-इन-बीएसएस –

+0

@ पास्कल क्यूक: शायद ही गैर-रचनात्मक! मुझे लगता है कि यह बहुत रचनात्मक है क्योंकि मैंने इसे बिल्कुल नहीं माना था। –

4

गतिशील प्रारंभ की कोशिश करो।

+0

यह एक अच्छा समाधान है, लेकिन इसका मतलब यह होगा कि मेरा ढेर खंड बहुत बड़ा हो जाएगा। यह ठीक हो सकता है अगर यह अन्य संदर्भों में ढेर के प्रदर्शन को प्रभावित नहीं करता है। – NXT

0

मुझे वास्तव में लगता है कि गैर स्थैतिक स्मृति डिफ़ॉल्ट रूप से शून्य से शुरू नहीं होती है?

+1

फ़ाइल स्कोप पर परिभाषित ऑब्जेक्ट्स में स्थिर संग्रहण अवधि है, इसलिए शून्य पर प्रारंभ किया गया है। – ouah

+0

यह बिल्कुल सही नहीं है (क्या यह एक प्रश्न या कथन है?)। क्या आप मानते हैं कि 'i' को निम्नलिखित कोड में '0' में प्रारंभ किया गया है?'int मुख्य() {int i; वापसी 0; } ' –

+0

मुझे लगता है कि मैं इसे * स्टैक पर रख सकता हूं और इसे वैश्विक में एक पॉइंटर स्टोर कर सकता हूं, लेकिन यह वास्तव में ढेर के दुरुपयोग की तरह लगता है। :-) – NXT

2

सामान्य उत्तर प्लेटफार्मों (यानी पीसी, चाहे विंडोज या लिनक्स) दोनों पर विजुअल स्टूडियो या जीसीसी की तरफ से अधिकतर उत्तर मिलेगा, और "मानक कहता है" पर भारी होगा। "उद्धरण, जिनमें से कोई भी छोटे एम्बेडेड सिस्टम के लिए इतना कुछ लागू नहीं करता है, जब तक कि आप एम्बेडेड लिनक्स या विंडोज सीई नहीं चलाते।

कहां का उत्तर शायद आपको जो चाहिए उसे सबसे नज़दीक है ... शायद आप वास्तव में जीसीसी का उपयोग कर रहे हैं, तो आपको वास्तव में क्या चाहिए। चूंकि आप जो स्मृति खंड चाहते हैं वह बहुत बड़ा है, शायद आपके सिस्टम की स्मृति के शेर के हिस्से को खपत कर रहा है, आपकी सबसे अच्छी शर्त है कि आप अपने निर्माण की लिंकर कमांड फ़ाइल में एक विशेष अनुभाग को परिभाषित करें, या सी, सी ++ या असेंबली फ़ाइल में लिंकर निर्देशों द्वारा । ऐसा करने के लिए वाक्यविन्यास कंपाइलर द्वारा अलग-अलग होगा। यदि आप किसी स्रोत/असेंबली फ़ाइल में लिंकर निर्देशों का उपयोग करते हैं, तो संभवतः ऐसे गुण हैं जिन्हें आपको स्मृति क्षेत्र की पढ़ने/लिखने की क्षमता आदि के बारे में निर्दिष्ट करने की आवश्यकता होगी ...या शायद नहीं, अगर माइक्रोब्लैज में कोई एमएमयू/मेमोरी-नियंत्रक नहीं है। आपको अनुभाग की शुरुआत में एक लिंकर प्रतीक डालना होगा, और अपने सी कोड में, "बाहरी चार symName []" निर्देश का उपयोग करें ताकि आपका सी कोड रिलेक्स में संकलित हो सके कि लिंकर वास्तविक पते के साथ ओवरराइट करेगा अनुभाग। कंपाइलर और आर्किटेक्चर के आधार पर, आपको किसी भी प्रकार की "दूर" विशेषता के साथ symName [] बाहरी घोषित करने की आवश्यकता हो सकती है; मुझे माइक्रोब्लैज के बारे में कुछ भी कहना नहीं है।

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