जवाबों:
कंपाइलरों के उचित मशीन कोड के बजाय असेंबली का उत्पादन करने के अन्य कारण हैं:
add eax,2
किया जा सकता है । 83 c0 02
66 83 c0 02
use16
एक कंपाइलर आमतौर पर उच्च-स्तरीय कोड को सीधे मशीन भाषा में परिवर्तित करता है, लेकिन इसे एक मॉड्यूलर तरीके से बनाया जा सकता है ताकि एक बैक-एंड मशीन कोड और दूसरा असेंबली कोड (जैसे GCC) का उत्सर्जन करे। कोड जनरेशन चरण "कोड" का उत्पादन करता है जो मशीन कोड का कुछ आंतरिक प्रतिनिधित्व है, जिसे फिर मशीन भाषा या असेंबली कोड जैसे प्रयोग करने योग्य प्रारूप में बदलना होगा।
ऐतिहासिक रूप से कई उल्लेखनीय संकलक सीधे मशीन कोड का उत्पादन करते थे। हालाँकि ऐसा करने में कुछ कठिनाइयाँ हैं। आम तौर पर कोई है जो यह पुष्टि करने की कोशिश कर रहा है कि एक कंपाइलर सही तरीके से काम कर रहा है, मशीन कोड की तुलना में असेंबली-कोड आउटपुट की जांच करना आसान होगा। इसके अलावा, यह संभव है (और ऐतिहासिक रूप से आम था) एक असेंबली-भाषा फ़ाइल का उत्पादन करने के लिए एक-पास सी या पास्कल संकलक का उपयोग करने के लिए जिसे तब दो-पास कोडांतरक का उपयोग करके संसाधित किया जा सकता है। कोड बनाने के लिए सीधे या तो दो-पास सी या पास्कल कंपाइलर का उपयोग करना होगा या फिर सिंगल-पास कंपाइलर का उपयोग करके आगे-पीछे के पतों के कुछ साधनों का उपयोग करना होगा [अगर एक रनटाइम वातावरण लॉन्च किए गए प्रोग्राम का आकार उपलब्ध कराता है निश्चित स्थान, एक कंपाइलर कोड के अंत में पैच की एक सूची लिख सकता है और स्टार्टअप कोड को उन पैच को रनटाइम पर लागू करता है; इस तरह के दृष्टिकोण से निष्पादन योग्य आकार में लगभग चार बाइट्स प्रति पैच-पॉइंट बढ़ जाएगा, लेकिन कार्यक्रम-पीढ़ी की गति में सुधार होगा]।
यदि लक्ष्य एक कंपाइलर है जो जल्दी से चलता है, तो डायरेक्ट कोड जेनरेशन अच्छा काम कर सकती है। अधिकांश परियोजनाओं के लिए, हालांकि, असेंबली-लैंग्वेज कोड तैयार करने और इसे असेंबल करने की लागत आजकल एक बड़ी समस्या नहीं है। संकलक एक ऐसे रूप में कोड का उत्पादन करते हैं जो अन्य संकलक द्वारा उत्पादित कोड के साथ अच्छी तरह से बातचीत कर सकते हैं, आमतौर पर संकलन समय में वृद्धि को सही ठहराने के लिए एक बड़ा पर्याप्त लाभ है।
यहां तक कि एक ही निर्देश सेट का उपयोग करने वाले प्लेटफार्मों में अलग-अलग स्थानांतरित वस्तु फ़ाइल प्रारूप हो सकते हैं। मैं "a.out" (शुरुआती UNIX), OMF, MZ (MS-DOS EXE), NE (16-बिट विंडोज), COFF (UNIX सिस्टम V), मच-ओ (OS X और iOS), और के बारे में सोच सकता हूं। ELF (लिनक्स और अन्य), साथ ही 32-बिट विंडोज पर XCOFF (AIX), ECOFF (SGI), और COFF- आधारित पोर्टेबल एक्सेसेबल (PE) जैसे वेरिएंट। असेंबली भाषा का निर्माण करने वाले एक कंपाइलर को ऑब्जेक्ट फ़ाइल स्वरूपों के बारे में अधिक जानकारी की आवश्यकता नहीं होती है, जिससे कोडांतरक और लिंकर को एक अलग प्रक्रिया में उस ज्ञान को इनकैप्सुलेट करने की अनुमति मिलती है।
स्टैक ओवरफ्लो पर OMF और COFF के बीच अंतर भी देखें ।
आमतौर पर कंपाइलर आंतरिक रूप से निर्देशों के अनुक्रम के साथ काम करते हैं। प्रत्येक निर्देश को एक डेटा संरचना द्वारा दर्शाया जाएगा, जो ऑपरेशन नाम, ऑपरेंड और इतने पर है। जब ऑपरेंड संबोधित करते हैं तो वे पते आमतौर पर प्रतीकात्मक संदर्भ होंगे, न कि ठोस मूल्य।
आउटपुट कोडांतरक अपेक्षाकृत सरल है। यह कंपाइलर्स आंतरिक डेटा संरचना को लेने और इसे एक विशिष्ट प्रारूप में एक पाठ फ़ाइल में डंप करने की बात है। असेंबलर आउटपुट को पढ़ना भी अपेक्षाकृत आसान होता है जो तब उपयोगी होता है जब आपको यह जांचने की आवश्यकता होती है कि कंपाइलर क्या कर रहा है।
बाइनरी ऑब्जेक्ट फ़ाइलों को आउटपुट करना काफी अधिक काम है। संकलक लेखक को यह जानने की जरूरत है कि सभी निर्देश कैसे एन्कोड किए गए हैं (जो कुछ सीपीयूएस पर तुच्छ से दूर हो सकते हैं), उन्हें द्विआधारी ऑब्जेक्ट फ़ाइल में मेटा डेटा के किसी भी रूप में प्रोग्राम रिलेटिव एड्रेस और अन्य को कुछ प्रतीकात्मक संदर्भ बदलने की आवश्यकता है। । उन्हें एक प्रारूप में सब कुछ लिखने की ज़रूरत है जो कि अत्यधिक सिस्टम विशिष्ट है।
हाँ, आप पूरी तरह से एक संकलक बना सकते हैं जो बाइनरी ऑब्जेक्ट्स को सीधे मध्यवर्ती कोड के रूप में कोडांतरक के बिना लिख सकते हैं। सॉफ्टवेयर विकास में बहुत सी चीजें जैसे सवाल यह है कि क्या संकलन समय में कमी अतिरिक्त विकास और रखरखाव के काम के लायक है।
संकलक के साथ मैं सबसे अधिक परिचित (फ्रीस्पेसल) सभी प्लेटफार्मों पर कोडांतरक आउटपुट कर सकता हूं, लेकिन केवल प्लेटफार्मों के एक सबसेट पर सीधे बाइनरी ऑब्जेक्ट्स का उत्पादन कर सकता हूं।
एक कंपाइलर प्रोग्रामर के लाभ के लिए सामान्य रिलोसेबल कोड के अतिरिक्त एक कोडांतरक आउटपुट का उत्पादन करने में सक्षम होना चाहिए।
एक बार मुझे सिर्फ LSI-11 मशीन पर यूनिक्स सिस्टम V पर चल रहे C प्रोग्राम में बग नहीं मिला। कुछ भी काम नहीं लग रहा था। अंत में हताशा में मेरे पास प्रोटेबल सी कंपाइलर था जो इसके अनुवाद के एक असेंबलर संस्करण का उत्सर्जन करता है। मैं अंत में बग मिल गया था! संकलक मशीन में मौजूद की तुलना में अधिक रजिस्टरों को आवंटित कर रहा था! (कंपाइलर ने R8 को R8 के माध्यम से एक मशीन पर आवंटित किया है जिसमें R7 के माध्यम से केवल R0 रजिस्टर होता है।) मैं कंपाइलर में बग के आसपास काम करने में कामयाब रहा और मेरे कार्यक्रम ने काम किया।
कोडांतरक आउटपुट होने का एक और लाभ "मानक" पुस्तकालयों का उपयोग करने की कोशिश कर रहा है जो एक अलग पैरामीटर पासिंग प्रोटोकॉल का उपयोग करते हैं। बाद में सी कंपाइलर मुझे एक पैरामीटर के साथ प्रोटोकॉल सेट करने की अनुमति देते हैं ("पास्कल" कंपाइलर को ऑर्डर के सी मानक के विपरीत दिए गए क्रम में पैरामीटर जोड़ देगा)।
फिर भी एक और लाभ प्रोग्रामर को यह देखने की अनुमति देता है कि उसका कंपाइलर क्या काम कर रहा है। एक साधारण सी स्टेटमेंट में लगभग 44 मशीन निर्देश होते हैं। मान को स्मृति से लोड किया जाता है और फिर जल्दी से हटा दिया जाता है। आदि, आदि ...
मेरा व्यक्तिगत रूप से मानना है कि किसी रीकॉन्सेबल ऑब्जेक्ट मॉड्यूल के बजाय एक कंपाइलर होना वास्तव में बेवकूफी है। आपके प्रोग्राम को संकलित करते समय, कंपाइलर आपके प्रोग्राम के बारे में बहुत जानकारी इकट्ठा करता है। यह आमतौर पर एक प्रतीक तालिका नामक किसी चीज में इस सारी जानकारी को संग्रहीत करता है। कोडांतरक कोड को एक्सेप्ट करने के बाद यह सारी सूचना तालिका को फेंक देता है। असेम्बलर तब उत्सर्जित कोड की जांच करता है और संकलक के पास पहले से मौजूद कुछ सूचनाओं को फिर से एकत्र करता है। हालाँकि असेंबलर के बारे में कुछ भी नहीं पता है कि क्या स्टेटमेंट्स फॉर स्टेटमेंट्स या जबकि स्टेटमेंट्स हैं। इसलिए यह सारी जानकारी गायब है। फिर असेंबलर रीकॉन्सेबल ऑब्जेक्ट मॉड्यूल का उत्पादन करता है जो कंपाइलर ने नहीं किया था।
क्यों???