2009-08-22 10 views
13
test.c: 

int main() 
{ 
    return 0; 
} 

मैंने किसी भी झंडे का उपयोग नहीं किया है (मैं gcc के लिए एक नया हूँ), बस आदेश:जीसीसी: खाली कार्यक्रम == 23202 बाइट्स?

gcc test.c 

मैंने win32 पर नवीनतम TDM build of GCC का उपयोग किया है। परिणामी निष्पादन योग्य लगभग 23 केबी है, एक खाली कार्यक्रम के लिए रास्ता बहुत बड़ा है।

मैं निष्पादन योग्य के आकार को कैसे कम कर सकता हूं?

+0

एक सुझाव: क्या आपको जीसीसी के मिनीजीडब्ल्यू बिल्डिंग का उपयोग करके एक ही परिणाम मिलते हैं? मुझे यकीन नहीं है कि वह आकार असामान्य है या नहीं, क्योंकि मुझे सी ++ का बहुत उपयोग नहीं किया जाता है। – Macha

+0

यूपीएक्स? http://upx.sourceforge.net/ – bobince

+0

हाँ, मुझे यूपीएक्स पता है, लेकिन यहां समस्या यह है: संकलक को एक खाली कार्यक्रम के लिए ~ 23 केबी जंक उत्पन्न नहीं करना चाहिए। – George

उत्तर

36

अपने सुझावों का पालन न करें, लेकिन मनोरंजन के लिए, this 'story' को सबसे छोटा संभव ईएलएफ बाइनरी बनाने के बारे में पढ़ें।

+6

+1 यह एक मजेदार पढ़ा है! –

+1

शित, यह गंभीरता से नहीं लिया जाना चाहिए था। अब यह सबसे ज्यादा वोट दिया गया जवाब मैंने दिया है! – Novelocrat

+1

http://stackoverflow.com/questions/553029/what-is-the-smallest-possible-windows-pe-executable में जुड़ा आलेख भी दिलचस्प है। – bk1e

10

डिफ़ॉल्ट रूप से कुछ मानक पुस्तकालय (उदा। सी रनटाइम) आपके निष्पादन योग्य से जुड़े हुए हैं। विवरण के लिए --nostdlib --nostartfiles --nodefaultlib देखें। लिंक विकल्प here वर्णित हैं।

वास्तविक कार्यक्रम के लिए दूसरा विकल्प optimization options, उदाहरण के लिए प्रयास करना है। -ओएस (आकार के लिए अनुकूलित करें)।

+0

यह सही है, लेकिन आमतौर पर आप उन पुस्तकालयों को _want_ करते हैं। –

+0

यह सही है। इन चाबियों का उपयोग मैंने केवल एम्बेडेड सिस्टम के लिए किया है। –

+0

आप किसके साथ शुरू करने की सलाह देते हैं?(मैं जीसीसी के लिए नया हूं, लेकिन मैंने पहले VisualCpp में सी का उपयोग किया है) – George

21

मैं इसका आकार कैसे कम कर सकता हूं?

  • ऐसा न करें। आप बस अपना समय बर्बाद कर रहे हैं।
  • उपयोग -s झंडा प्रतीक पट्टी (जीसीसी -s)
7

वास्तव में, यदि आपके कोड कुछ नहीं करता है, तो यह और भी उचित संकलक अभी भी एक निष्पादन योग्य बनाता है? ;-)

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

आपके कंपाइलर और उसके आकार को कम करने के लिए उपयोग की जाने वाली प्रत्येक विधि के आधार पर आजकल कुछ भी निष्पादन योग्य आकार में 4 और 8 किलोबाइट्स के बीच नहीं होगा। यह एक ऐसे आकार में होगा जहां यूपीएक्स वास्तव में बड़े निष्पादन योग्य परिणाम देगा! आपके निष्पादन योग्य में अतिरिक्त बाइट जोड़े जा सकते हैं क्योंकि आपने अपने कोड में कुछ लाइब्रेरी जोड़े हैं। प्रारंभिक डेटा या संसाधनों के साथ विशेष रूप से पुस्तकालयों में बाइट्स की काफी मात्रा में वृद्धि होगी। डीबग जानकारी जोड़ने से निष्पादन योग्य आकार भी बढ़ जाता है।

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


EXE header में रूचि है? यह "मार्क ज़बिकोव्स्की" के लिए एमजेड अक्षरों से शुरू होता है।पहला भाग एक्जिक्यूटिव के लिए पुरानी शैली के एमएस-डॉस हेडर है और एमएस-डॉस के स्टब के रूप में प्रयोग किया जाता है कि यह प्रोग्राम एक एमएस-डॉस निष्पादन योग्य नहीं है। (बाइनरी में, आप टेक्स्ट 'यह प्रोग्राम डॉस मोड में नहीं चलाया जा सकता है।' मूल रूप से यह सब करता है: उस संदेश को प्रदर्शित करना। अगला पीई हेडर है, जो विंडोज एमएस-डॉस के बजाय पहचान और उपयोग करेगा हेडर। यह PE for Portable Executable अक्षरों से शुरू होता है। इस दूसरे हेडर के बाद निष्पादन योग्य स्वयं होगा, कोड और डेटा के कई ब्लॉक में विभाजित होगा। हेडर में विशेष पुनर्विक्रय सारणी होती है जो ओएस को एक विशिष्ट ब्लॉक लोड करने के लिए कहती है। और यदि आप कर सकते हैं एक सीमा तक इस रखने के लिए, अंतिम निष्पादन योग्य 4 KB से कम हो सकता है लेकिन 90% तो हेडर सूचना और कोई कार्यक्षमता होगा।

+3

एक डॉस एप्लिकेशन के लिए, एक साधारण रीट करेगा। वह है, 1 बाइट। –

+0

एक रिट करेगा, लेकिन आधिकारिक नियम यह था कि आपको "बाहर निकलें" बाधा डालना पड़ा। –

+0

मैंने वास्तविक विंडोज एक्जिक्यूटिव (पीई प्रारूप) बनाया है जो VS2005 का उपयोग करके <4KB में उपयोगी चीजें करता है। तो निष्पादन योग्य कुछ भी निश्चित रूप से 8 केबी नहीं होना चाहिए। (क्यों? एक सीडी के लिए Autorun चेकर, यदि एक ऐप पहले से स्थापित है तो एक बड़ा इंस्टॉलर EXE शुरू नहीं करें) – MSalters

2

इस अभ्यास का उद्देश्य क्या है?

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

खाली कार्यक्रम के बाइनरी आकार की जांच करना एक बेकार अभ्यास है। यह आपको कुछ भी नहीं बताता है। यदि आप कोड आकार के बारे में कुछ सीखना चाहते हैं, तो गैर-खाली (और अधिमानतः गैर-तुच्छ) प्रोग्राम लिखने का प्रयास करें। उन कार्यक्रमों की तुलना करें जो मानक पुस्तकालयों का उपयोग उन कार्यक्रमों के साथ करते हैं जो सब कुछ स्वयं करते हैं।

यदि आप वास्तव में जानना चाहते हैं कि उस बाइनरी में क्या चल रहा है (और यह इतना बड़ा क्यों है), तो निष्पादन योग्य प्रारूप को बाइनरी डंप टूल प्राप्त करें और चीज़ को अलग करें।

+0

यह देखते हुए कि आप ओपी की प्रेरणा नहीं जानते हैं, यह सच नहीं है। उन्हें एम्बेडेड विकास में दिलचस्पी हो सकती है, उदाहरण के लिए कोड आकार बहुत मायने रखता है। – Novelocrat

+3

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

+0

रिक्त प्रोग्राम का कोड आकार अप्रासंगिक नहीं है। 1. आप कोड डेमो, 2. आप रुचि रखते हैं कि संकलन कैसे काम करता है, अंतिम निष्पादन योग्य में क्या होता है, 3. और आखिर में जब आप जानते हैं कि एक खाली प्रोग्राम नहीं होना चाहिए ~ 23kb। इस तरह के कुछ का कोई स्पष्ट उपयोग नहीं हो सकता है, लेकिन यह संकलक झंडे के बारे में सीखने को अप्रासंगिक नहीं बनाता है। – George

3

मैं जिस तरह से पसंद DJGPP पूछे जाने वाले प्रश्न addressed this कई कई साल पहले:

सामान्य में, "हैलो" कार्यक्रमों के आकार को देखकर कोड आकारों को पहचानने, व्यर्थ है क्योंकि ऐसे कार्यक्रमों स्टार्टअप के ज्यादातर मिलकर बनता है कोड। ... इन सभी सुविधाओं की अधिकांश शक्ति "हैलो" कार्यक्रमों में बर्बाद हो जाती है। 15-बाइट स्ट्रिंग और बाहर निकलने के लिए बस उस कोड को चलाने में कोई बात नहीं है।

+1

खाली कार्यक्रम का पूरा बिंदु ओवरहेड देखना है। मैं बस दिलचस्पी लेता हूं कि संकलन कैसे काम करता है, जो मैंने वहां दिए गए कोड से अलग संकलित बाइनरी में समाप्त होता है। – George

+2

रिचर्ड, यह आपके प्रश्न में जो कुछ भी आपने पूछा है वह बिल्कुल नहीं है। आपने पूछा कि ओवरहेड से कैसे छुटकारा पाएं। आपने नहीं पूछा कि ओवरहेड में क्या शामिल है। –

0

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

कुछ लिंकर झंडे भी हो सकते हैं जो अंतिम बाइनरी से अप्रयुक्त कोड छोड़ने के लिए कह रहे हैं।

+0

-Os इस कोड में कोई फर्क नहीं पड़ता। इस मामले में –

+1

असुरक्षित। जीसीसी वास्तव में यहां छू रहा है कि इतना कोड नहीं है। – Novelocrat

11

छोड़ दें। x86 लिनक्स पर, जीसीसी 4.3.2 5 के बाइनरी का उत्पादन करता है। लेकिन रुकें! यह गतिशील लिंकिंग के साथ है! सांख्यिकीय रूप से जुड़ा हुआ बाइनरी आधे मेग्राम से अधिक है: 516K। आराम करो और ब्लोट के साथ जीना सीखो।

और उन्होंने कहा कि 200K हैलो वर्ल्ड बाइनरी के कारण मॉडुला -3 कभी भी कहीं नहीं जाएगी!


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

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

1

प्रतीकों से छुटकारा पाने के लिए बाइनरी पर रन स्ट्रिप। जीसीसी संस्करण 3.4.4 (साइगिंग स्पेशल) के साथ मैं 10k से 4k तक ड्रॉप करता हूं।

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

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

2

'size a.out' कोड, डेटा और बीएसएस सेगमेंट के आकार के बारे में आपको क्या बताता है? कोड का बहुमत प्रारंभिक कोड (क्लासिकल crt0.o यूनिक्स मशीनों पर) होने की संभावना है, जिसे ओ/एस द्वारा बुलाया जाता है और main() का आह्वान करने से पहले कार्य सेट अप करता है (जैसे कि कमांड लाइन तर्कों को argc, argv में सॉर्ट करना)।

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