2010-08-12 8 views
47

सी प्रोग्राम कैसे शुरू होता है?सी में, मुख्य() विधि को प्रारंभ में कैसे कहा जाता है?

+14

आप करते हैं! आप मुख्य() कहते हैं! हाँ य़ह सही हैं! हाँ आप कीजिए! – recursive

+8

दर्शक कौन देखता है? – Cascabel

+8

विषय एक बयान है लेकिन शरीर एक प्रश्न है। –

उत्तर

23

आखिरकार यह ऑपरेटिंग सिस्टम है। आमतौर पर असली प्रविष्टि बिंदु और मुख्य कार्य के बीच कुछ माध्यम होता है, यह कंपाइलर लिंकर द्वारा डाला जाता है।

कुछ विवरण (विंडोज से संबंधित): पीई फ़ाइल में शीर्षलेख है जिसे IMAGE_OPTIONAL_HEADER कहा जाता है जिसमें फ़ील्ड AddressOfEntryPoint है, जो फ़ाइल में पहले कोड बाइट के बदले पते पर है जिसे निष्पादित किया जाएगा।

+1

यह कंपाइलर द्वारा डाला नहीं गया है, यह लिंकर द्वारा डाला गया है, आमतौर पर 'crt.a (crt) जैसे कुछ को जोड़कर .o) 'या' crt.lib (crt.obj) ', जो आमतौर पर 'libc.a' या' c.lib' जैसी चीज़ का हिस्सा होता है। –

+0

@ क्रिस्टियन हूजर आप सही हैं, कंपाइलर द्वारा मेरा मतलब टूलचैन था। – Andrey

+0

आप __linker__ के बारे में निश्चित हैं, मुझे लगता है कि __loader__ तब क्या करता है? – roottraveller

38

ऑपरेटिंग सिस्टम main() फ़ंक्शन को कॉल करता है। असल में, यह आमतौर पर _init जैसी अजीब चीज नामक कुछ और कहता है। सी कंपाइलर प्रत्येक एप्लिकेशन को एक मानक लाइब्रेरी लिंक करता है जो इस ऑपरेटिंग सिस्टम को एंट्री पॉइंट परिभाषित करता है और फिर main() पर कॉल करता है।

संपादित करें: जाहिर है कि कुछ लोगों के लिए पर्याप्त विस्तृत और सही नहीं था।

Executable and Linkable Format (ELF) जो कई यूनिक्स ओएस का उपयोग एक प्रविष्टि बिंदु पता परिभाषित करता है। ओएस के बाद exec() कॉल समाप्त होने के बाद प्रोग्राम चलाना शुरू होता है। एक लिनक्स सिस्टम पर यह _init है।

objdump -d से:

Disassembly of section .init: 

08049f08 <_init>: 
8049f08:  55      push %ebp 
8049f09:  89 e5     mov %esp,%ebp 
8049f0b:  83 ec 08    sub $0x8,%esp 
8049f0e:  e8 a1 05 00 00   call 804a4b4 <call_gmon_start> 
8049f13:  e8 f8 05 00 00   call 804a510 <frame_dummy> 
8049f18:  e8 d3 50 00 00   call 804eff0 <__do_global_ctors_aux> 
8049f1d:  c9      leave 
8049f1e:  c3      ret  

readelf -d से:

0x00000001 (NEEDED)      Shared library: [libstdc++.so.6] 
0x00000001 (NEEDED)      Shared library: [libm.so.6] 
0x00000001 (NEEDED)      Shared library: [libgcc_s.so.1] 
0x00000001 (NEEDED)      Shared library: [libpthread.so.0] 
0x00000001 (NEEDED)      Shared library: [libc.so.6] 
0x0000000c (INIT)      0x8049f08 
0x0000000d (FINI)      0x804f018 
0x00000004 (HASH)      0x8048168 
0x00000005 (STRTAB)      0x8048d8c 
0x00000006 (SYMTAB)      0x804867c 
0x0000000a (STRSZ)      3313 (bytes) 
0x0000000b (SYMENT)      16 (bytes) 
0x00000015 (DEBUG)      0x0 
0x00000003 (PLTGOT)      0x8059114 
0x00000002 (PLTRELSZ)     688 (bytes) 
0x00000014 (PLTREL)      REL 
0x00000017 (JMPREL)      0x8049c58 
0x00000011 (REL)      0x8049be0 
0x00000012 (RELSZ)      120 (bytes) 
0x00000013 (RELENT)      8 (bytes) 
0x6ffffffe (VERNEED)     0x8049b60 
0x6fffffff (VERNEEDNUM)     3 
0x6ffffff0 (VERSYM)      0x8049a7e 
0x00000000 (NULL)      0x0 

आपको लगता है कि INIT देख सकते हैं _init का पता करने के लिए बराबर है।

frame_dummy और __do_global_ctors_aux के लिए कोड crtbegin.o और crtend.o (और उन नामों के रूपों) नामक फ़ाइलों के एक सेट में है। ये जीसीसी का हिस्सा हैं। वह कोड सी प्रोग्राम के लिए आवश्यक विभिन्न चीजें करता है जैसे स्टडीन, स्टडआउट, ग्लोबल और स्टेटिक वैरिएबल और अन्य चीजें सेट करना।

निम्न आलेख काफी अच्छी तरह से क्या यह लिनक्स में करता है (एक जवाब से नीचे कम वोटों के साथ लिया गया) का वर्णन: http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html

मेरा मानना ​​है कि किसी और के जवाब पहले से ही वर्णित क्या विंडोज करता है।

+2

'__start', वू। – strager

+4

यह '_init' या किसी अन्य को कॉल नहीं करता है। यह प्रवेश बिंदु पता कॉल करता है। यह कहीं भी हो सकता है। – Andrey

+0

libstdC++ की आवश्यकता है। तो.6? यह एक सी कार्यक्रम से नहीं है! – Jens

8
+0

मैं क्यों इस downvoted था पता नहीं है, लिंक अच्छी जानकारी – zwol

+5

@Zack आम तौर पर सारांश यहाँ –

+1

जानना अच्छा है पर सिकोड़ी है किसी प्रकार का बिना एक लिंक पोस्ट, धन्यवाद – zwol

4

ध्यान दें कि जवाब के अलावा पहले से ही तैनात है, यह भी संभव है कि आप अपने आप को main कॉल करने के लिए। आम तौर पर यह एक बुरा विचार है जो obfuscated कोड के लिए आरक्षित है।

+4

यह सी में कानूनी नहीं है ++ है, वैसे - एक और तरीका जिसमें सी ++ सख्त सुपरसेट नहीं है। –

6

ऑपरेटिंग सिस्टम मुख्य कहता है। स्थानांतरित करने योग्य निष्पादन योग्य में एक पता होगा जो मुख्य स्थान पर इंगित करता है (अधिक जानकारी के लिए यूनिक्स एबीआई देखें)।

लेकिन, जो ऑपरेटिंग सिस्टम को कॉल करते हैं?

केंद्रीय संसाधन प्रसंस्करण इकाई, "रीसेट" सिग्नल पर (जिसे बिजली पर भी लगाया जाता है) पर, कुछ निर्देशों को किसी दिए गए पते (कहें, 0xffff) पर अपने निर्देशों के लिए देखना शुरू कर देगा।

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

सभी कड़ी मेहनत के बाद, कर्नेल हमारे सॉफ़्टवेयर को लोड करने के लिए आगे बढ़ सकता है।

5

ऑपरेटिंग सिस्टम सी रनटाइम (सीआरटी) में शामिल एक फ़ंक्शन को कॉल करता है और आपके निष्पादन योग्य में लिंक किया जाता है। इसे "सीआरटी मुख्य" कहते हैं।

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

दृश्य सी ++ सीआरटी मुख्य कुछ और चीजें करता है, अगर स्मृति सेवा करता है। यह मेमोरी लीक या खराब पहुंच खोजने में मदद के लिए डीबग सीआरटी का उपयोग करते हुए मेमोरी आवंटक को कॉन्फ़िगर करता है। यह structured exception हैंडलर के भीतर भी मुख्य कॉल करता है जो खराब मेमोरी एक्सेस और अन्य क्रैश को पकड़ता है और उन्हें प्रदर्शित करता है।

+0

भले ही आप सी ++ नहीं सी के बारे में बात कर रहे हों, आपकी पोस्ट रोशनी हो रही है! –

3

शायद आपके प्रश्न के लिए सबसे अच्छी जानकारी नीचे उल्लिखित लिंक http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html, में मिल सकती है जो आज तक का सबसे अच्छा है।

+0

यह बढ़िया है! आपका बहुत बहुत धन्यवाद! –

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