पहली चीज जो आपको चाहिए वह है कुछ इस फाइल की तरह । यह x86 प्रोसेसर के लिए निर्देश डेटाबेस है जैसा कि NASM असेंबलर द्वारा उपयोग किया जाता है (जो मैंने लिखने में मदद की, हालांकि वे भाग जो वास्तव में निर्देशों का अनुवाद नहीं करते हैं)। डेटाबेस से एक मनमानी लाइन लेने दें:
ADD rm32,imm8 [mi: hle o32 83 /0 ib,s] 386,LOCK
इसका मतलब यह है कि यह निर्देश का वर्णन करता है ADD
। इस निर्देश के कई प्रकार हैं, और जो विशिष्ट यहां वर्णित किया जा रहा है, वह संस्करण है जो या तो 32-बिट रजिस्टर या मेमोरी एड्रेस लेता है और तत्काल 8-बिट मान जोड़ता है (अर्थात एक अनुदेश में लगातार शामिल)। एक उदाहरण विधानसभा निर्देश जो इस संस्करण का उपयोग करेगा, वह यह है:
add eax, 42
अब, आपको अपने पाठ इनपुट को लेने और इसे व्यक्तिगत निर्देशों और ऑपरेंड में पार्स करने की आवश्यकता है। ऊपर दिए गए निर्देश के लिए, यह संभवतः एक संरचना में परिणाम होगा जिसमें अनुदेश ADD
, और एक सरणी ऑफ़ेंड (रजिस्टर EAX
और मूल्य का एक संदर्भ 42
) है। एक बार जब आपके पास यह संरचना होती है, तो आप निर्देश डेटाबेस के माध्यम से चलाते हैं और निर्देश नाम और ऑपरेंड्स के प्रकारों से मेल खाने वाली रेखा को ढूंढते हैं। यदि आपको कोई मेल नहीं मिलता है, तो यह एक त्रुटि है जिसे उपयोगकर्ता को प्रस्तुत करना होगा ("ओपकोड और ऑपरेंड्स का अवैध संयोजन" या समान सामान्य पाठ है)।
डेटाबेस से लाइन मिल जाने के बाद, हम तीसरे कॉलम को देखते हैं, जो इस निर्देश के लिए है:
[mi: hle o32 83 /0 ib,s]
यह निर्देशों का एक सेट है जो यह बताता है कि मशीन कोड निर्देश को उत्पन्न करने के लिए कैसे आवश्यक है:
mi
एक: ऑपरेंड के एक descriptiuon है modr/m
(रजिस्टर या स्मृति) संकार्य (जिसका अर्थ है हम एक संलग्न करने की आवश्यकता होगी modr/m
अनुदेश, जो हम बाद में करने के लिए आया हूँ के अंत तक बाइट) और एक एक तत्काल अनुदेश (जो होगा निर्देश के विवरण में इस्तेमाल किया जा सकता है)।
- अगला है
hle
। यह पहचानता है कि हम "लॉक" उपसर्ग को कैसे संभालते हैं। हमने "लॉक" का उपयोग नहीं किया है, इसलिए हम इसे अनदेखा करते हैं।
- अगला है
o32
। यह हमें बताता है कि अगर हम 16-बिट आउटपुट फॉर्मेट के लिए कोड असेंबल कर रहे हैं, तो इंस्ट्रक्शन को ऑपरेंड-साइज ओवरराइड प्रीफिक्स की जरूरत है। यदि हम 16-बिट आउटपुट का उत्पादन कर रहे थे, तो हम अब उपसर्ग का उत्पादन 0x66
करेंगे ( ), लेकिन मुझे लगता है कि हम नहीं हैं और इसे आगे बढ़ाएंगे।
- अगला है
83
। यह हेक्साडेसिमल में एक शाब्दिक बाइट है। हम इसका उत्पादन करते हैं।
अगला है /0
। यह कुछ अतिरिक्त बिट्स को निर्दिष्ट करता है जिनकी हमें modr / m bytem में आवश्यकता होगी, और हमें इसे उत्पन्न करने का कारण बनता है। modr/m
बाइट एनकोड रजिस्टर या अप्रत्यक्ष स्मृति संदर्भ किया जाता है। हमारे पास एक ऐसा ऑपरेंड, एक रजिस्टर है। रजिस्टर में एक नंबर है, जो किसी अन्य डेटा फ़ाइल में निर्दिष्ट है :
eax REG_EAX reg32 0
हम जाँचते हैं कि reg32
मूल डेटाबेस से निर्देश के आवश्यक आकार से सहमत हैं (यह करता है)। 0
रजिस्टर के नंबर है। एक modr/m
बाइट प्रोसेसर द्वारा निर्दिष्ट एक डेटा संरचना है, जो इस तरह दिखता है:
(most significant bit)
2 bits mod - 00 => indirect, e.g. [eax]
01 => indirect plus byte offset
10 => indirect plus word offset
11 => register
3 bits reg - identifies register
3 bits rm - identifies second register or additional data
(least significant bit)
क्योंकि हम एक रजिस्टर के साथ काम कर रहे हैं, mod
फील्ड है 0b11
।
reg
क्षेत्र, रजिस्टर हम प्रयोग कर रहे की संख्या है0b000
- क्योंकि इस निर्देश में केवल एक रजिस्टर है, हमें किसी
rm
चीज़ के साथ फ़ील्ड भरने की आवश्यकता है। क्या अतिरिक्त डेटा में निर्दिष्ट है कि के /0
तो हम में है कि शब्दों में कहें, के लिए था rm
, क्षेत्र 0b000
।
modr/m
बाइट इसलिए है 0b11000000
या 0xC0
। हम इसका उत्पादन करते हैं।
- अगला है
ib,s
। यह एक हस्ताक्षरित तत्काल बाइट निर्दिष्ट करता है। हम ऑपरेंड को देखते हैं और ध्यान दें कि हमारे पास तत्काल मूल्य उपलब्ध है। हम इसे एक हस्ताक्षरित बाइट में परिवर्तित करते हैं और इसे ( 42
=> 0x2A
) आउटपुट करते हैं ।
पूर्ण इकट्ठे निर्देश इसलिए है 0x83 0xC0 0x2A
:। इसे अपने आउटपुट मॉड्यूल पर भेजें, साथ ही ध्यान दें कि कोई भी बाइट मेमोरी रेफरेंस का गठन नहीं करता है (आउटपुट मॉड्यूल को यह जानने की आवश्यकता हो सकती है कि यह क्या है)।
हर निर्देश के लिए दोहराएँ। लेबल का ध्यान रखें ताकि आपको पता हो कि जब वे संदर्भित हों तो क्या डालें। मैक्रो और निर्देशों के लिए सुविधाएं जोड़ें जो आपके ऑब्जेक्ट फ़ाइल आउटपुट मॉड्यूल में पास हो जाते हैं। और यह मूल रूप से एक कोडांतरक कैसे काम करता है।