जवाबों:
=====> COMPILATION PROCESS <======
|
|----> Input is Source file(.c)
|
V
+=================+
| |
| C Preprocessor |
| |
+=================+
|
| ---> Pure C file ( comd:cc -E <file.name> )
|
V
+=================+
| |
| Lexical Analyzer|
| |
+-----------------+
| |
| Syntax Analyzer |
| |
+-----------------+
| |
| Semantic Analyze|
| |
+-----------------+
| |
| Pre Optimization|
| |
+-----------------+
| |
| Code generation |
| |
+-----------------+
| |
| Post Optimize |
| |
+=================+
|
|---> Assembly code (comd: cc -S <file.name> )
|
V
+=================+
| |
| Assembler |
| |
+=================+
|
|---> Object file (.obj) (comd: cc -c <file.name>)
|
V
+=================+
| Linker |
| and |
| loader |
+=================+
|
|---> Executable (.Exe/a.out) (com:cc <file.name> )
|
V
Executable file(a.out)
C प्रीप्रोसेसिंग संकलन में पहला कदम है। यह संभालता है:
#define
बयान।#include
बयान।यूनिट का उद्देश्य सी सोर्स फाइल को प्योर सी कोड फाइल में बदलना है।
यूनिट में छह चरण हैं:
यह "TOKEN" बनाने के लिए स्रोत फ़ाइल में वर्णों को जोड़ती है। एक टोकन वर्णों का एक समूह है जिसमें 'स्पेस', 'टैब' और 'नई लाइन' नहीं होती है। इसलिए संकलन की इस इकाई को "TOKENIZER" भी कहा जाता है। यह टिप्पणियों को भी हटाता है, प्रतीक तालिका और स्थानांतरण तालिका प्रविष्टियां उत्पन्न करता है।
यह इकाई कोड में वाक्य रचना के लिए जाँच करती है। पूर्व के लिए:
{
int a;
int b;
int c;
int d;
d = a + b - c * ;
}
उपरोक्त कोड पार्स त्रुटि उत्पन्न करेगा क्योंकि समीकरण संतुलित नहीं है। यह इकाई इस प्रकार से पार्सर के पेड़ को उत्पन्न करके आंतरिक रूप से जांचती है:
=
/ \
d -
/ \
+ *
/ \ / \
a b c ?
इसलिए इस इकाई को PARSER भी कहा जाता है।
यह इकाई कथनों में अर्थ की जाँच करती है। पूर्व के लिए:
{
int i;
int *p;
p = i;
-----
-----
-----
}
उपरोक्त कोड "असंगत प्रकार का असाइनमेंट" त्रुटि उत्पन्न करता है।
यह इकाई सीपीयू से स्वतंत्र है, अर्थात, दो प्रकार के अनुकूलन हैं
यह इकाई निम्नलिखित रूपों में कोड का अनुकूलन करती है:
पूर्व के लिए:
{
int a = 10;
if ( a > 5 ) {
/*
...
*/
} else {
/*
...
*/
}
}
यहाँ, संकलनकर्ता संकलन समय पर 'a' का मूल्य जानता है, इसलिए यह भी जानता है कि यदि शर्त हमेशा सही होती है। इसलिए यह कोड में अन्य भाग को समाप्त कर देता है।
पूर्व के लिए:
{
int a, b, c;
int x, y;
/*
...
*/
x = a + b;
y = a + b + c;
/*
...
*/
}
निम्नानुसार अनुकूलित किया जा सकता है:
{
int a, b, c;
int x, y;
/*
...
*/
x = a + b;
y = x + c; // a + b is replaced by x
/*
...
*/
}
पूर्व के लिए:
{
int a;
for (i = 0; i < 1000; i++ ) {
/*
...
*/
a = 10;
/*
...
*/
}
}
उपरोक्त कोड में, यदि 'क' स्थानीय है और लूप में उपयोग नहीं किया जाता है, तो इसे निम्नानुसार अनुकूलित किया जा सकता है:
{
int a;
a = 10;
for (i = 0; i < 1000; i++ ) {
/*
...
*/
}
}
यहाँ, कंपाइलर असेंबली कोड जनरेट करता है ताकि रजिस्टरों में अधिक बार उपयोग किए जाने वाले वेरिएबल को स्टोर किया जा सके।
यहाँ अनुकूलन CPU पर निर्भर है। मान लीजिए कि यदि कोड में एक से अधिक छलांग हैं तो वे एक के रूप में परिवर्तित हो जाते हैं:
-----
jmp:<addr1>
<addr1> jmp:<addr2>
-----
-----
नियंत्रण सीधे कूदता है।
फिर अंतिम चरण लिंकिंग है (जो निष्पादन योग्य या पुस्तकालय बनाता है)। जब निष्पादन योग्य चलाया जाता है, तो इसके लिए आवश्यक पुस्तकालयों को लोड किया जाता है।
ASCII प्रतिनिधित्व:
[Source Code] ---> Compiler ---> [Object code] --*
|
[Source Code] ---> Compiler ---> [Object code] --*--> Linker --> [Executable] ---> Loader
| |
[Source Code] ---> Compiler ---> [Object code] --* |
| |
[Library file]--* V
[Running Executable in Memory]
आशा है कि यह आपको थोड़ा और मदद करेगा।
सबसे पहले, इस आरेख पर जाएं:
(img source->internet)
आप कोड का एक टुकड़ा बनाते हैं और फ़ाइल (स्रोत कोड) को सहेजते हैं, फिर
preprocessing : - जैसा कि नाम से पता चलता है, यह संकलन का हिस्सा नहीं है। वे संकलक को वास्तविक संकलन से पहले आवश्यक पूर्व-प्रसंस्करण करने का निर्देश देते हैं। आप इस चरण को पाठ प्रतिस्थापन कह सकते हैं या # द्वारा निरूपित विशेष पूर्वप्रक्रमक निर्देशों की व्याख्या कर सकते हैं।
संकलन : - संकलन एक ऐसी प्रक्रिया है जिसमें एक भाषा में लिखे गए कार्यक्रम को दूसरी लक्षित भाषा में अनुवादित किया जाता है। यदि कुछ त्रुटियां हैं, तो संकलक उन्हें पता लगाएगा और रिपोर्ट करेगा।
असेंबल : - असेंबल कोड का अनुवाद मशीन कोड में हो जाता है। आप असेम्बलर को एक विशेष प्रकार का कंप्लेंट कह सकते हैं।
लिंकिंग : - अगर कोड के इन टुकड़े को लिंक करने के लिए किसी अन्य स्रोत फ़ाइल की आवश्यकता होती है, तो लिंकर इसे एक निष्पादन योग्य फ़ाइल बनाने के लिए लिंक करता है।
इसके बाद कई प्रक्रियाएं होती हैं। हां, आपने अनुमान लगाया कि यहीं लोडर की भूमिका आती है:
लोडर : - यह निष्पादन योग्य कोड को मेमोरी में लोड करता है; प्रोग्राम और डेटा स्टैक बनाया जाता है, रजिस्टर इनिशियलाइज़ हो जाता है।
थोड़ी अतिरिक्त जानकारी: - http://www.geeksforgeeks.org/memory-layout-of-c-program/ , आप वहां पर मेमोरी लेआउट देख सकते हैं।
कंपाइलर: यह एक प्रोग्राम है जो उच्च स्तरीय भाषा प्रोग्राम को मशीन लैंग्वेज प्रोग्राम में तब्दील करता है। एक संकलक एक कोडांतरक की तुलना में अधिक बुद्धिमान है। यह सभी प्रकार की सीमाओं, सीमाओं, त्रुटियों आदि की जांच करता है, लेकिन इसका प्रोग्राम रन टाइम अधिक है और मेमोरी के एक बड़े हिस्से पर कब्जा कर लेता है। इसकी गति धीमी है। क्योंकि एक कंपाइलर पूरे प्रोग्राम से गुजरता है और फिर पूरे प्रोग्राम को मशीन कोड में ट्रांसलेट करता है। यदि कंपाइलर कंप्यूटर पर चलता है और उसी कंप्यूटर के लिए मशीन कोड का निर्माण करता है तो इसे सेल्फ कंपाइलर या रेजिडेंट कंपाइलर के रूप में जाना जाता है। दूसरी ओर, यदि एक कंपाइलर कंप्यूटर पर चलता है और दूसरे कंप्यूटर के लिए मशीन कोड का उत्पादन करता है तो इसे क्रॉस कंपाइलर के रूप में जाना जाता है।
लिंकर: उच्च स्तरीय भाषाओं में, कुछ हेडर फ़ाइलों या पुस्तकालयों में संग्रहीत किए जाते हैं। इन पुस्तकालयों को पूर्वनिर्धारित किया जाता है और इनमें बुनियादी कार्य होते हैं जो कार्यक्रम को निष्पादित करने के लिए आवश्यक होते हैं। ये फ़ंक्शंस लिंकर नामक एक कार्यक्रम द्वारा पुस्तकालयों से जुड़े हुए हैं। यदि लिंकर को किसी फ़ंक्शन का पुस्तकालय नहीं मिलता है, तो यह संकलक को सूचित करता है और फिर संकलक एक त्रुटि उत्पन्न करता है। कंपाइलर स्वचालित रूप से लिंकर को एक प्रोग्राम को संकलित करने के अंतिम चरण के रूप में आमंत्रित करता है। पुस्तकालयों में नहीं बनाया गया है, यह उपयोगकर्ता परिभाषित कार्यों को उपयोगकर्ता परिभाषित पुस्तकालयों से भी जोड़ता है। आमतौर पर एक लंबे कार्यक्रम को छोटे उपप्रोग्राम में विभाजित किया जाता है जिसे मॉड्यूल कहा जाता है। और इन मॉड्यूल को प्रोग्राम को निष्पादित करने के लिए संयोजित किया जाना चाहिए। मॉड्यूल के संयोजन की प्रक्रिया लिंकर द्वारा की जाती है।
लोडर: लोडर एक ऐसा प्रोग्राम है जो किसी प्रोग्राम के मशीन कोड को सिस्टम मेमोरी में लोड करता है। कम्प्यूटिंग में, एक लोडर एक ऑपरेटिंग सिस्टम का हिस्सा है जो लोडिंग प्रोग्राम के लिए जिम्मेदार है। यह एक कार्यक्रम शुरू करने की प्रक्रिया में आवश्यक चरणों में से एक है। क्योंकि यह कार्यक्रमों को स्मृति में रखता है और उन्हें निष्पादन के लिए तैयार करता है। प्रोग्राम लोड करने से मेमोरी में निष्पादन योग्य फ़ाइल की सामग्री को पढ़ना शामिल है। एक बार लोडिंग पूरी हो जाने के बाद, ऑपरेटिंग सिस्टम लोड प्रोग्राम कोड पर नियंत्रण पारित करके कार्यक्रम शुरू करता है। सभी ऑपरेटिंग सिस्टम जो प्रोग्राम लोडिंग का समर्थन करते हैं उनमें लोडर हैं। कई ऑपरेटिंग सिस्टमों में लोडर स्थायी रूप से मेमोरी में रहता है।
विकिपीडिया के पास एक अच्छा जवाब होना चाहिए, यहाँ मेरे विचार हैं:
*
*
लिंकर्स और लोडरLinuxJournal के लिंकर्स इस अवधारणा को स्पष्टता के साथ बताते हैं। यह भी बताता है कि क्लासिक नाम a.out कैसे आया। (कोडांतरक आउटपुट)
एक त्वरित सारांश,
c program --> [compiler] --> objectFile --> [linker] --> executable file (say, a.out)
हमें निष्पादन योग्य मिल गया है, अब इस फ़ाइल को अपने मित्र या अपने ग्राहक को दें, जिसे इस सॉफ़्टवेयर की आवश्यकता है :)
जब वे इस सॉफ़्टवेयर को चलाते हैं, तो इसे कमांड लाइन में टाइप करके कहें ।/a.out
execute in command line ./a.out --> [Loader] --> [execve] --> program is loaded in memory
एक बार जब प्रोग्राम को मेमोरी में लोड कर दिया जाता है, तो इस प्रोग्राम को पीसी (प्रोग्राम काउंटर) बनाकर ट्रांसफर कर दिया जाता है। a.out
यह सोर्स फाइल पढ़ेगा जो कि .c या .cpp आदि का हो सकता है और इसे .o फाइल को ऑब्जेक्ट फाइल के रूप में ट्रांसलेट करता है।
यह कई .o फ़ाइलों को जोड़ती है जो एक निष्पादन योग्य फ़ाइल (जीसीसी में ईएलएफ प्रारूप) में कई स्रोत फ़ाइलों के लिए उत्पन्न हो सकती हैं। जोड़ने के दो प्रकार हैं:
एक प्रोग्राम जो निष्पादन योग्य फ़ाइल को मशीन की प्राथमिक मेमोरी में लोड करता है।
लिनक्स में प्रोग्राम निष्पादन के इन तीन चरणों के बारे में विस्तार से अध्ययन के लिए, कृपया इसे पढ़ें ।
संकलक परिवर्तन त्रुटियों के लिए आपके स्रोत कोड की जाँच करता है और इसे ऑब्जेक्ट कोड में बदलता है। यह वह कोड है जो ऑपरेटिंग सिस्टम चलाता है।
आप अक्सर एकल फ़ाइल में एक पूरा कार्यक्रम नहीं लिखते हैं इसलिए लिंकर आपके सभी ऑब्जेक्ट कोड फ़ाइलों को लिंक करता है।
जब तक यह मुख्य मेमोरी में नहीं है तब तक आपका प्रोग्राम निष्पादित नहीं होगा
लिंकर और दुभाषिया परस्पर अनन्य दुभाषिया हैं जो लाइन द्वारा कोड लाइन प्राप्त कर रहे हैं और लाइन द्वारा लाइन निष्पादित करते हैं।
कंपाइलर यह सोर्स कोड को ऑब्जेक्ट कोड में परिवर्तित करता है।
लिंकर यह एक निष्पादन योग्य प्रोग्राम फ़ाइल में कई ऑब्जेक्ट फ़ाइलों को जोड़ती है।
लोडर यह निष्पादन योग्य फ़ाइल को मुख्य मेमोरी में लोड करता है।
एक कंपाइलर एक विशेष कार्यक्रम है जो एक विशेष प्रोग्रामिंग भाषा में लिखे गए बयानों को संसाधित करता है और उन्हें मशीन भाषा या "कोड" में बदल देता है जो कंप्यूटर का प्रोसेसर उपयोग करता है
एक संकलक प्रोग्रामिंग भाषा से मशीन भाषा में कोड की पंक्तियों का अनुवाद करता है।
एक लिंकर दो कार्यक्रमों के बीच एक लिंक बनाता है।
एक लोडर मुख्य डेटाबेस, प्रोग्राम आदि में प्रोग्राम को मेमोरी में लोड करता है।
कंपाइलर: यह एक सिस्टम सॉफ्टवेयर है जो प्रोग्राम्स, ऑब्जेक्ट फाइल, मैसेज आदि की त्रुटि को ठीक करता है
लिंकर: यह एक सिस्टम सॉफ्टवेयर है जो एक या एक से अधिक ऑब्जेक्टफाइल्स को मिलाता है और कुछ लाइब्रेरी कोड को संभवत: कुछ अतिशेष कुछ लाइब्रेरी या त्रुटि की सूची में शामिल करता है।
लोडर: एक प्रोग्राम जो निष्पादन योग्य फ़ाइल को मशीन की प्राथमिक मेमोरी में लोड करता है