2013-04-13 8 views
9

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

कागज पर, यह काफी आसान लगता है। असेंबली कोड आता है, मशीन कोड आता है।

लेकिन जैसे ही मैं सभी विवरणों के बारे में सोचता हूं, यह अचानक बहुत चुनौतीपूर्ण हो जाता है। ऑपरेटिंग सिस्टम की मांग क्या है? मैं डेटा को संरेखित कैसे करूं और कूदता हूं? निष्पादन योग्य के अंदर भी क्या दिखता है?

मुझे खो रहा है। इस पर कोई ट्यूटोरियल नहीं है कि मैं लोकप्रिय असेंबलरों के स्रोत कोड को ढूंढ और देख सकता था प्रेरणादायक नहीं था (हालांकि, मैं फिर कोशिश करने के लिए तैयार हूं)।

मैं यहां से कहां से जाऊं? आप इसे कैसे करेंगे? क्या इस विषय पर कोई अच्छा ट्यूटोरियल या साहित्य है?

+1

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

+1

शायद आपको [NASM] (http://www.nasm.us/) जैसे पैकेज का अध्ययन करना चाहिए। –

+0

8086 संसाधनों के लिए [कोडक गोल्फ पर यह चुनौती] देखें (http://codegolf.stackexchange.com/questions/4732/emulate-an-intel-8086-cpu) और सबसेट का उपयोग करके बहुत कम नमूना प्रोग्राम स्रोत और बाइनरी दोनों रूपों में 8086 का। आईएमओ 1 9 7 9 मैनुअल शुरू करने का स्थान है। ... [मेरे असेंबली संसाधन विकी प्रश्न] (http://stackoverflow.com/a/7203667/) पर विशेष रूप से फ़ाइल देखें, विशेष रूप से फ़ाइल "पीडीपी -1_Macro.pdf" जो एक बहुत ही प्राचीन असेंबलर का विस्तृत विवरण देती है । –

उत्तर

3

जो आप खोज रहे हैं वह एक ट्यूटोरियल या स्रोत कोड नहीं है, यह विनिर्देश है। देखें http://msdn.microsoft.com/en-us/library/windows/hardware/gg463119.aspx

एक बार जब आप निष्पादन योग्य के विनिर्देश को समझ लेते हैं, तो एक उत्पन्न करने के लिए एक प्रोग्राम लिखें। आपके द्वारा निर्मित निष्पादन योग्य जितना संभव हो उतना सरल होना चाहिए। एक बार जब आप इसे महारत हासिल कर लेते हैं, तो फिर आप एक साधारण रेखा उन्मुख पार्सर लिख सकते हैं जो exe में प्लग करने के लिए कोड के ब्लॉक उत्पन्न करने के लिए निर्देश नाम और संख्यात्मक तर्क पढ़ता है। बाद में आप जो भी चाहें प्रतीक, शाखाएं, अनुभाग जोड़ सकते हैं, और यही वह जगह है जहां http://www.davidsalomon.name/assem.advertis/asl.pdf कुछ ऐसा होगा।

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

4

आपको एलएलवीएम देखना चाहिए, llvm एक मॉड्यूलर कंपाइलर बैक एंड है, सबसे लोकप्रिय फ्रंट एंड सी/सी ++/ऑब्जेक्टिव-सी संकलन के लिए क्लैंग है। एलएलवीएम के बारे में अच्छी बात यह है कि आप उस कंपाइलर श्रृंखला का हिस्सा चुन सकते हैं जिसमें आप रुचि रखते हैं और बस उस पर ध्यान केंद्रित करते हैं, अन्य सभी को अनदेखा करते हैं। आप अपनी खुद की भाषा बनाना चाहते हैं, एक पार्सर लिखें जो एलएलवीएम आंतरिक प्रतिनिधित्व कोड उत्पन्न करता है, और मुफ्त में आप सभी मध्य परत लक्ष्य स्वतंत्र अनुकूलन प्राप्त करते हैं और कई अलग-अलग लक्ष्यों को संकलित करते हैं। कुछ विदेशी सीपीयू के लिए एक कंपाइलर में रूचि रखते हुए, एक कंपाइलर बैकएंड लिखें जो एलएलवीएम इंटरमीडिएटेड कोड लेता है और आपके इकट्ठा करता है। ऑप्टिमाइज़ेशन टेक्निक्स, स्वचालित थ्रेडिंग के बारे में कुछ विचार हैं, शायद एक मध्यम परत लिखें जो एलएलवीएम इंटरमीडिएट कोड को संसाधित करता है। एलएलवीएम पुस्तकालयों का संग्रह है जो जीसीसी की तरह एक स्टैंडअलोन बाइनरी नहीं है, और इसलिए अपनी परियोजनाओं में इसका उपयोग करना बहुत आसान है।

11

मैंने कुछ खुद को लिखा है (असेंबलर और डिस्सेबलर) और मैं x86 से शुरू नहीं करूंगा। यदि आप x86 या किसी अन्य निर्देश सेट को जानते हैं तो आप कम से कम शेरों के हिस्से को कम क्रम में एक अन्य निर्देश सेट (एक शाम/दोपहर) में सिंटैक्स चुन सकते हैं और सीख सकते हैं।एक असेंबलर (या डिस्सेबलर) लिखने का कार्य निश्चित रूप से आपको एक निर्देश सेट, तेज़ सिखाएगा, और आपको पता चलेगा कि निर्देश उस निर्देश सेट के लिए कई अनुभवी असेंबली प्रोग्रामर से बेहतर है, जिसने उस स्तर पर माइक्रोक्रोड की जांच नहीं की है। msp430, pdp11, और अंगूठे (thumb2 एक्सटेंशन नहीं) (या मिप्स या ओपन्रिस्क) शुरू करने के लिए सभी अच्छी जगहें हैं, बहुत सारे निर्देश नहीं, अत्यधिक जटिल नहीं हैं, आदि

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

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

असेंबलर स्वयं सीधे आगे है, बस ascii पढ़ें और मशीन कोड में बिट्स सेट करें। शाखाएं और अन्य पीसी सापेक्ष निर्देश थोड़ा अधिक दर्दनाक होते हैं क्योंकि वे पूरी तरह हल करने के लिए स्रोत/तालिकाओं के माध्यम से एकाधिक पास ले सकते हैं।

mov r0,r1 
    mov r2 ,#1 

कोडांतरक एक लाइन (बाइट्स कि एक गाड़ी वापसी 0xD या लाइन फ़ीड 0xA का पालन के रूप में परिभाषित किया जा रहा) के लिए पाठ पार्स करने, सफेद स्थान (स्पेस और टैब) त्यागने जब तक आप कुछ गैर सफेद करने के लिए मिल शुरू होता है अंतरिक्ष, फिर ज्ञात निमोनिक्स के साथ strncmp। यदि आप एक को दबाते हैं तो उस निर्देश के संभावित संयोजनों को पार्स करें, सफेद स्थान पर गैर-सफेद स्थान पर mov skip के बाद ऊपर दिए गए साधारण मामले में, शायद आपको जो पहली चीज़ मिलती है वह एक रजिस्टर होना चाहिए, फिर वैकल्पिक सफेद स्थान, फिर एक अल्पविराम। व्हाइटस्पेस और कॉमा को हटा दें और तारों की एक तालिका के खिलाफ इसकी तुलना करें या इसके माध्यम से बस पार्स करें। एक बार यह रजिस्टर हो जाने के बाद, जहां अल्पविराम मिल जाए, वहां जाएं और कहें कि यह एक और रजिस्टर है या तत्काल है। अगर तत्काल कहें तो इसका नाम # हस्ताक्षर होना चाहिए, अगर रजिस्टर कहता है कि इसे कम या ऊपरी मामले 'आर' से शुरू करना है। उस रजिस्टर या तत्काल पार्सिंग के बाद, सुनिश्चित करें कि रेखा पर कुछ भी नहीं है जो लाइन पर नहीं होना चाहिए। इस इंस्ट्रुसिटन के लिए मशीन कोड बनाएं या कम से कम जितना आप कर सकते हैं, और अगली पंक्ति पर जाएं। यह थकाऊ हो सकता है लेकिन एएससीआई को पार्स करना मुश्किल नहीं है ...

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

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

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

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

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