2009-05-10 9 views
37

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

एक उदाहरण के रूप जीसीसी ले रहा है, यह सीधे करने के लिए मशीन कोड एक छोटी सी में लिखे प्रोग्राम संकलित करता है, या यह पहली बार मानव पठनीय विधानसभा में अनुवाद करता है, और उसके बाद ही एक (में निर्मित?) कोडांतरक का उपयोग करता है असेंबली कार्यक्रम का अनुवाद बाइनरी में करने के लिए, मशीन कोड - सीपीयू के लिए निर्देशों की एक श्रृंखला?

बाइनरी निष्पादन योग्य एक महत्वपूर्ण महंगी ऑपरेशन बनाने के लिए असेंबली कोड का उपयोग कर रहा है? या यह एक अपेक्षाकृत सरल और त्वरित चीज है?

(मान लेते हैं हम प्रोसेसर की केवल 86 परिवार के साथ काम कर रहे हैं, और सभी कार्यक्रमों लिनक्स के लिए लिखा जाता है।)

मैं किसी भी मदद के लिए बहुत आभारी होगा और इस मामले पर सोचा। धन्यवाद!

उत्तर

40

जीसीसी वास्तव में असेंबलर उत्पन्न करता है और इसे असेंबलर के रूप में उपयोग करके इकट्ठा करता है। सभी कंपाइलर ऐसा नहीं करते हैं - एमएस कंपाइलर्स सीधे ऑब्जेक्ट कोड उत्पन्न करते हैं, हालांकि आप उन्हें असेंबलर आउटपुट उत्पन्न कर सकते हैं। ऑब्जेक्ट कोड पर असेंबलर का अनुवाद करना कम से कम संकलन के साथ तुलना में एक बहुत ही सरल प्रक्रिया है। उदाहरण के लिए, cfront, पहले सी ++ संकलक सी इसके उत्पादन के रूप में निर्मित है जो फिर एक सी संकलक द्वारा संकलित किया गया -

कुछ compilers उनके उत्पादन के रूप में अन्य उच्च स्तरीय भाषा कोड का उत्पादन।

ध्यान दें कि न तो प्रत्यक्ष संकलन या असेंबली वास्तव में निष्पादन योग्य उत्पन्न करती है। यह लिंकर द्वारा किया जाता है, जो संकलन/असेंबली द्वारा उत्पादित विभिन्न ऑब्जेक्ट कोड फ़ाइलों को लेता है, वे सभी नामों को हल करता है और अंतिम निष्पादन योग्य बाइनरी उत्पन्न करता है।

+3

कुछ ऐतिहासिक कंपाइलर सीधे एक्जिक्यूटिव का उत्पादन करते थे। कुछ संकलन के दौरान एक ही पास में निष्पादन योग्य .COM फ़ाइल भी लिख सकते हैं [प्रत्येक प्रक्रिया के लिए कोड के बाद, संकलक पिछली प्रक्रिया की पैच-पॉइंट सूची के पते के साथ उस प्रक्रिया के भीतर पैच-पॉइंट की एक सूची आउटपुट कर सकता है; कोड लोड होने पर स्टार्टअप कोड सभी आवश्यक पैच बना सकता है]। फ्लॉपी डिस्क का उपयोग करते समय भी, यह बहुत ही कम स्मृति पदचिह्न में तेजी से संकलन संभव बनाता है। – supercat

6

सामान्य रूप से कंपाइलर्स, स्रोत कोड को एक सार सिंटेक्स ट्री (एएसटी) में पार्स करते हैं, फिर कुछ मध्यवर्ती भाषा में। केवल तभी, आमतौर पर कुछ अनुकूलन के बाद, वे लक्षित भाषा को छोड़ देते हैं।

जीसीसी के बारे में, यह विभिन्न प्रकार के लक्ष्यों को संकलित कर सकता है। मुझे नहीं पता कि x86 के लिए यह पहले असेंबली में संकलित है, लेकिन मैंने आपको कंपेलरों पर कुछ अंतर्दृष्टि दी - और आपने इसके लिए भी पूछा।

1

विजुअल सी ++ में आउटपुट असेंबली कोड के लिए switch है, इसलिए मुझे लगता है कि यह मशीन कोड आउटपुट करने से पहले असेंबली कोड उत्पन्न करता है।

6

Introduction to Reverse Engineering Software की chapter 2, दोनों जीसीसी और cl.exe (MSVC के लिए ++ वापस अंत संकलक) (माइक पेरी और Nasko Oskov द्वारा) के अनुसार एस स्विच आप उत्पादन के लिए विधानसभा कि प्रत्येक संकलक का उत्पादन उपयोग कर सकते हैं ।

आप वर्बोज़ मोड (gcc -v) में जीसीसी भी चला सकते हैं ताकि यह देखने के लिए निष्पादित किया जा सके कि यह दृश्यों के पीछे क्या कर रहा है।

1

आप शायद इस फली डाली को सुनने के लिए दिलचस्पी होगी: Internals of GCC

+1

अपडेटेड लिंक: http://www.se-radio.net/2007/07/episode-61-internals-of-gcc/ –

1

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

बस हर कंपाइलर के पास इस मक्खन का कुछ रूप है, यह एक निहित या स्पष्टता कदम है।

5

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

0

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

हालांकि यह धीमा प्रतीत हो सकता है - यह तेज़ हो सकता है क्योंकि JVM बाद के CPU निर्देशों और नए अनुकूलन का लाभ उठा सकता है। एक सी ++ कंपाइलर ऐसा नहीं करेगा - आपको संकलन समय पर निर्देश सेट को लक्षित करना होगा।

14

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

  • Standard ML of New Jersey, जो सहभागी चलाता है और मक्खी पर हर अभिव्यक्ति संकलित शामिल हैं।

  • tinycc compiler, जो कोडांतरक और लिंकर बुलाने की भूमि के ऊपर नहीं चाहता है काफी तेजी से संकलित करने के लिए, लोड हो, और अच्छी तरह के तहत 100 मिलीसेकेंड में एक सी स्क्रिप्ट चलाने के लिए डिज़ाइन किया गया है, और इसलिए।

इन मामलों में आम बात क्या है "तत्काल" प्रतिक्रिया की इच्छा है। असेंबलर और लिंकर्स बहुत तेज़ हैं, लेकिन इंटरैक्टिव प्रतिक्रिया के लिए पर्याप्त नहीं हैं। फिर भी।

स्मॉलटॉक, जावा, और Lua जैसे भाषाओं का एक बड़ा परिवार भी है, जो बाइटकोड को संकलित करता है, असेंबली कोड नहीं, लेकिन जिसका कार्यान्वयन बाद में बाइटकोड को सीधे असेंबलर के लाभ के बिना मशीन कोड में अनुवाद कर सकता है।

(पाद-टिप्पणी:। 1990 के दशक में, मरियम फर्नांडीज और मैं New Jersey Machine Code Toolkit, जिसके लिए code ऑनलाइन है, जो सी   पुस्तकालयों कि संकलक लेखकों मैरी मोटे तौर पर करने के लिए यह प्रयोग किया जाता मानक कोडांतरक और लिंकर बायपास करने के लिए उपयोग कर सकते हैं उत्पन्न लिखा था a.out उत्पन्न करते समय उसके अनुकूल लिंकर की गति को दोगुना करें। यदि आप डिस्क पर नहीं लिखते हैं, तो स्पीडअप भी अधिक होते हैं ...)

1

संकलन के कई चरण हैं। संक्षेप में, सामने वाला अंत होता है जो स्रोत कोड को पढ़ता है, इसे टोकन में और अंत में एक पार्स पेड़ में तोड़ देता है।यह अनुकूलन के

reg1 = y + z 
x = reg1 + w 

फिर, यह में अनुवाद:

कोड:

में
x = y + z + w 

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

0

हालांकि सभी कंपाइलर स्रोत कोड को मध्यवर्ती स्तर कोड में परिवर्तित नहीं करते हैं, लेकिन कई संकलकों में स्रोत कोड को मशीन स्तर कोड में ले जाने का एक पुल है

2

कोई भी जवाब इस तथ्य को स्पष्ट नहीं करता है कि एक एस्सेबलर बिनरी कोड और मशीन डिप्लेन्ट सिंबल कोड के बीच अमूर्तता की पहली परत है। एक कंपाइलर मशीन डिप्लेन्ट सिंबल कोड और मशीन इंडेक्सेंट सिंबल कोड के बीच अमूर्तता की दूसरी परत है।

यदि कोई संकलक सीधे परिभाषा के अनुसार कोड को बाइनरी कोड में परिवर्तित करता है, तो इसे असेंबलर कहा जाएगा और संकलक नहीं।

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

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

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