क्या संकलक-लेखकों को वास्तव में मशीन कोड को 'समझने' की आवश्यकता है? [बन्द है]


10

एक अजीब तरह का सवाल हो सकता है।

C ++ कंपाइलर (या जो भी गैर-वीएम भाषा है) लिखने वाला लड़का: क्या उसे कच्ची मशीन की भाषा पढ़ने / लिखने में सक्षम होना चाहिए? वह कैसे काम करता है?

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



1
नहीं, आपको इसे जानने की भी आवश्यकता नहीं है, आप बस आँख बंद करके, अपने लक्ष्य आईएसए विनिर्देशन की नकल कर सकते हैं: dl.acm.org/citation.cfm?id=1706346
SK-logic

1
कॉफी जावास्क्रिप्ट के लिए संकलित करता है।
कार्तिक

@Kartik क्या जावास्क्रिप्ट को संकलित करने वाले कॉफीस्क्रिप्ट संकलक में एक जावास्क्रिप्ट संकलक भी शामिल है जो जावास्क्रिप्ट को संकलित करने के लिए संकलित करता है? या यह केवल जावास्क्रिप्ट स्रोत कोड को संकलित करता है और अधिक कुछ नहीं?
अवीव कोहन

कॉफ़िशस्क्रिप्ट संकलक बस कॉफ़ीस्क्रिप्ट को जावास्क्रिप्ट में परिवर्तित करता है। जावास्क्रिप्ट संकलित नहीं है, यह ब्राउज़र द्वारा नियंत्रित किया जाता है। मैं यह कहना चाहता था कि आप एक संकलक लिख सकते हैं जो एक भाषा को दूसरी भाषा में संकलित करता है, आपको उसके लिए मशीनी भाषा नहीं जाननी चाहिए। एक अन्य उदाहरण 'एसपीएल' संकलक है जो शेक्सपियर के नाटकों को C ++ में संकलित करता है। shakespearelang.sourceforge.net
कार्तिक

जवाबों:


15

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

वैसे, गैर-वीएम कार्यान्वयन बनाम वीएम कार्यान्वयन का आपका भेद उपयोगी नहीं है।

  • शुरुआत के लिए, मशीन कोड के लिए वीएम या प्रीकंप्लिमेंटेशन का उपयोग करना एक भाषा को लागू करने के लिए सिर्फ अलग-अलग तरीके हैं; ज्यादातर मामलों में एक भाषा को रणनीति का उपयोग करके लागू किया जा सकता है। मुझे वास्तव में एक बार C ++ इंटरप्रेटर का उपयोग करना पड़ा ।

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

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

LLVM के बारे में अच्छी बात यह है कि इसका VM केवल एक अमूर्त है, और यह कि बाइट कोड की आमतौर पर व्याख्या नहीं की जाती है, लेकिन पारदर्शी रूप से इसके बजाय JITted किया जाता है। तो यह पूरी तरह से एक भाषा लिखने के लिए संभव है जो प्रभावी रूप से संकलित हो, बिना आपके सीपीयू के निर्देश सेट के बारे में कभी भी पता चले।


और एलएलवीएम की एक और अच्छी संपत्ति यह है कि एक कुशल बैकएंड को लागू करने के लिए लक्ष्य आईएसए को गहराई से समझने की आवश्यकता नहीं है। यह बहुत ही घोषणात्मक है, इसलिए कोई ISA विनिर्देश को कॉपी-एंड-पेस्ट कर सकता है। इसे समझने की कोशिश किए बिना भी .td फ़ाइलों में।
एसके-लॉजिक

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

5
@ प्रोग हाँ। यदि आप अमूर्त की एक परत बनाते हैं, तो आपको केवल अपने नीचे की परत को समझना होगा। हालांकि सभी परतों की बुनियादी समझ होना उपयोगी है, यह वास्तव में आवश्यक नहीं है। एक ट्रांजिस्टर का उपयोग करने के लिए आपको क्वांटम भौतिकी को समझने की आवश्यकता नहीं है। सीपीयू का उपयोग करने के लिए आपको चिप डिजाइन को समझने की आवश्यकता नहीं है। विधानसभा लिखने के लिए आपको मशीन कोड जानने की आवश्यकता नहीं है। आपको VM, आदि का उपयोग करते समय प्लेटफ़ॉर्म के इंस्ट्रक्शन सेट को जानने की आवश्यकता नहीं है .. लेकिन किसी को आपके नीचे उन अमूर्त स्तरों का निर्माण करना था।
आमोन

1
@ एसके-लॉजिक सही नहीं है (कम से कम अगर आपको अच्छा कोड चाहिए) तो मैंने जो सुना है। जिन लोगों ने llvm के लिए Aarch64 बैकएंड को लागू किया, उनमें कुछ चुनौतियां थीं (एक, लोड-स्टोर पैटर्न भयानक, ..) के लिए स्थानांतरण। और वह कमरे के सबसे बड़े हाथी की अनदेखी कर रहा है : आईएसए का मेमोरी मॉडल और जिस भाषा में आपकी रुचि है उसका मेमोरी मॉडल। आप एक कंपाइलर पर काम कर सकते हैं, लेकिन आप आर्किटेक्चर को समझे बिना बैकएंड पर काम नहीं कर सकते हैं ..
वू

1
मुझे लगता है कि विधानसभा और मशीन कोड के बीच वास्तव में कोई महत्वपूर्ण अंतर नहीं है, वैचारिक रूप से। आपको वास्तव में बहुत अधिक लाभ होने वाला नहीं है, एक बार यह जानने के बाद कि किसी विशेष निर्देश का उपयोग कैसे करना है, उस अनुदेश का ओपकोड क्या है। यदि आप जानते हैं कि MOV का उपयोग कैसे किया जाता है, तो यह वास्तव में मायने नहीं रखता है यदि आप नहीं जानते कि यह निर्देश 27 है, जो मुझे लगता है कि @ SK- तर्क के समान है।
whatsisname

9

नहीं। आपके प्रश्न का मुख्य बिंदु यह है कि संकलन अत्यंत व्यापक शब्द है। संकलन किसी भी भाषा से किसी भी भाषा में हो सकता है। और असेंबली / मशीन कोड संकलन लक्ष्य के लिए कई भाषाओं में से केवल एक है। उदाहरण के लिए, C #, F # और VB.NET जैसी जावा और .NET भाषाएँ सभी मशीन-विशिष्ट कोड के बजाय किसी प्रकार के मध्यवर्ती कोड के लिए संकलित हैं। इससे कोई फर्क नहीं पड़ता कि यह तब VM पर चलता है, भाषा अभी भी संकलित है। कुछ अन्य भाषा को संकलित करने का विकल्प भी है, जैसे सी। सी वास्तव में काफी लोकप्रिय संकलन लक्ष्य है और कई उपकरण इसे करते हैं। और अंत में, आप अपने लिए मशीन कोड के निर्माण की कड़ी मेहनत करने के लिए कुछ टूल या लाइब्रेरी का उपयोग कर सकते हैं। उदाहरण के लिए एलएलवीएम है जो स्टैंडअलोन कंपाइलर बनाने के लिए आवश्यक प्रयास को कम कर सकता है।

साथ ही, आपके संपादन का कोई मतलब नहीं है। यह पूछने जैसा है कि "क्या हर इंजीनियर को यह समझने की ज़रूरत है कि इंजन कैसे काम करता है? और मैं इंजनों पर काम करने वाले इंजीनियरों के बारे में पूछ रहा हूँ।" यदि आप एक प्रोग्राम या लाइब्रेरी पर काम कर रहे हैं जो मशीन कोड का उत्सर्जन करता है, तो आपको इसे समझना होगा। बात यह है, संकलक लिखते समय आपको ऐसा करने की ज़रूरत नहीं है। कई लोगों ने इसे आपके सामने किया, इसलिए आपको इसे फिर से करने के लिए गंभीर कारण की आवश्यकता है।


और उपकरण या पुस्तकालय लिखने वाला व्यक्ति जो मशीन भाषा के लिए वास्तविक रूपांतरण करता है, उसे मशीन की भाषा को पूरी तरह से समझना होगा, है ना?
अवीव कोहन

3
@ प्रोग क्या आपको प्रोग्राम करने के लिए प्रोग्रामिंग भाषा को पूरी तरह से समझने की आवश्यकता है? नहीं, लेकिन आप संभवतः उप-इष्टतम कोड लिखेंगे, और आप कुछ ऐसी चीजें नहीं कर सकते हैं जो दूसरे करने में सक्षम हो सकते हैं। क्या आपको मशीन भाषा को पूरी तरह से समझने की ज़रूरत है यदि आप एक कंपाइलर लिखते हैं जो उस पर अनुवाद करता है। नहीं, लेकिन आपका कंपाइलर सबऑप्टिमल होगा, और कुछ चीजें करने में असमर्थ होगा।
सुमुरै 8

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

@SteveJessop यदि आप प्रत्येक ओपोड को एक बिंदु पर समझते हैं, तो आप एक मशीन सीख सकते हैं कि एक उच्च स्तर की अवधारणा को व्यक्त करने के लिए अन्य ओपकोड के साथ मिलकर ओपकोड कैसे करें, आप मशीन भाषा को पूरी तरह से समझते हैं। फिर आप हर समस्या के लिए इष्टतम समाधान खोजने के लिए बहुत आलसी हैं
;;

@ Sumurai8: हम्म, लेकिन कम से कम सिद्धांत रूप में मैं पांच मिनट के लिए प्रत्येक ओपेक को संक्षेप में "समझ" सकता हूं जो मुझे इसे कॉन्फ़िगर करने के लिए लेता है, और फिर जब तक मैं अगले के बाद ओपकोड को "समझ" नहीं लेता। शायद ऐसा नहीं है कि प्रश्नकर्ता का अर्थ "कच्ची मशीन की भाषा पढ़ने / लिखने में सक्षम होना" है। बेशक, मैं यहाँ एक बहुत अच्छी रूपरेखा तैयार कर रहा हूँ, जो कि निर्देश सेट के प्रत्येक ओपकोड के बारे में सभी उपयोगी जानकारी को परिभाषित करने और उपयोग करने के लिए पर्याप्त है। LLVM इसके लिए कुछ उद्देश्य रखता है लेकिन "वू" के अनुसार (नीचे टिप्पणी में) इसे हिट नहीं किया है।
स्टीव जेसोप

3

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

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

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


2

बहुत समय पहले मैंने एक संकलक लिखा था जो दो अलग-अलग शैल लिपियों के बीच परिवर्तित हो गया। यह मशीन कोड के पास कोई रास्ता नहीं था।

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

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

YACC एक ऐसा कंपाइलर है जो मशीन कोड को आउटपुट नहीं करता है।


0

आपको अपने इनपुट और आउटपुट भाषाओं के शब्दार्थों के विस्तृत ज्ञान के साथ शुरुआत करने की आवश्यकता नहीं है , लेकिन आप बेहतर ढंग से दोनों के एक्सक्लूसिव विस्तृत ज्ञान के साथ समाप्त होते हैं, अन्यथा आपका कंपाइलर असामान्य रूप से छोटा हो जाएगा। इसलिए यदि आपका इनपुट C ++ है और आपका आउटपुट कुछ विशिष्ट मशीन भाषा है, तो आपको अंततः दोनों के शब्दार्थों को जानना होगा।

यहाँ C ++ को मशीन कोड के संकलन में कुछ सूक्ष्मताएँ दी गई हैं: (बस मेरे सिर के ऊपर से, मुझे यकीन है कि और भी बहुत कुछ मैं भूल रहा हूँ।)

  1. आकार क्या होगा int? यहां "सही" विकल्प एक कला है, जो मशीन के प्राकृतिक सूचक आकार, अंकगणितीय संचालन के विभिन्न आकारों के लिए ALU के प्रदर्शन और मशीन के लिए मौजूदा संकलक द्वारा किए गए विकल्पों पर आधारित है। क्या मशीन में 64-बिट अंकगणित भी है? यदि नहीं तो 32-बिट पूर्णांक के अलावा एक अनुदेश में अनुवाद करना चाहिए जबकि 64-बिट पूर्णांक के अलावा 64-बिट जोड़ने के लिए फ़ंक्शन कॉल में अनुवाद करना चाहिए। क्या मशीन में 8-बिट और 16-बिट ऑपरेशन हैं या क्या आपको 32-बिट ऑप्स और मास्किंग के साथ अनुकरण करना है (जैसे कि डीईसी अल्फा 21064)?

  2. मशीन पर अन्य संकलक, पुस्तकालयों और भाषाओं द्वारा उपयोग किए जाने वाले कॉलिंग सम्मेलन क्या है? क्या मापदंडों को स्टैक पर दाएं-बाएं या बाएं-से-दाएं पर धक्का दिया जाता है? क्या कुछ पैरामीटर रजिस्टरों में जाते हैं जबकि अन्य स्टैक पर जाते हैं? क्या अलग-अलग रजिस्टर स्पेस में इन्टस और फ्लोट्स हैं? क्या पंजीकृत आवंटित मापदंडों को विशेष रूप से वैरगस कॉल पर इलाज करने की आवश्यकता है? कौन से रजिस्टर कॉलर-सेव हैं और कौन से कैली-सेव हैं? क्या आप लीफ-कॉल ऑप्टिमाइज़ेशन कर सकते हैं?

  3. मशीन की प्रत्येक शिफ्ट निर्देश क्या करता है? यदि आप 65 बिट्स को 64 बिट्स द्वारा शिफ्ट करने के लिए कहते हैं तो परिणाम क्या है? (कई मशीनों पर परिणाम 1 बिट द्वारा स्थानांतरित करने के समान है, दूसरों पर परिणाम "0" है।)

  4. मशीन की मेमोरी संगति शब्द क्या हैं? C ++ 11 में बहुत अच्छी तरह से परिभाषित स्मृति शब्दार्थ है जो कुछ मामलों में कुछ अनुकूलन पर प्रतिबंध लगाता है, लेकिन अन्य मामलों में अनुकूलन की अनुमति देता है। आपको लगता है कि है एक भाषा संकलन रहे हैं, तो नहीं अच्छी तरह से (सी से पहले C / C ++ ++ 11, और कई अन्य जरूरी भाषाओं के हर संस्करण की तरह) स्मृति अर्थ विज्ञान को परिभाषित किया है तो आप स्मृति अर्थ विज्ञान का आविष्कार करने के रूप में आप साथ जाने होगा, और आम तौर पर आप स्मृति शब्दार्थों का आविष्कार करना चाहेंगे जो आपके मशीन शब्दार्थों से सर्वोत्तम रूप से मेल खाते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.