2009-02-13 29 views
7

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

सभी की


     /* this code immediately follows the setting of the PE flag in CR0 */

.byte 0x66, 0xEA 
.long TARGET_ADDRESS 
.word 0x0010   /* descriptor #2, GDT, RPL=0 */ 

सबसे पहले, क्यों एक (अनुदेश स्मरक के बजाय) ऐसा करना चाहते हैं?

मैं इंटेल मैनुअल देख रहा हूं, लेकिन अभी भी कोड द्वारा थोड़ा उलझन में हूं। विशेष रूप से वॉल्यूम 2 ​​ए, पेज 3-549 में, ऑपकोड की एक तालिका है। प्रासंगिक प्रविष्टि:

 
EA *cp* JMP ptr16:32 Inv. Valid Jump far, absolute, address given in 
operand 

वास्तविक ओपोड स्पष्ट है, लेकिन पहला बाइट, 0x66, मुझे उलझन में डाल दिया है। इंटेल मैनुअल में टेबल का जिक्र करते हुए, सीपी का स्पष्ट रूप से मतलब है कि एक 6 बाइट ऑपरेंड का पालन करेगा। और स्पष्ट रूप से अगले दो पंक्तियों में 6 बाइट्स का पालन करें। 0x66 एन्कोड करता है 'ऑपरेंड-साइज ओवरराइड उपसर्ग'। तालिका में सीपी के साथ इसका क्या संबंध है? मैं उम्मीद कर रहा था कि सीपी के लिए कुछ हेक्स वैल्यू हो, लेकिन इसके बजाय यह ओवरराइड उपसर्ग है। क्या कोई इसे मेरे लिए साफ़ कर सकता है?

यहाँ आयुध डिपो से एक डंप है:

 
c022 **ea66 0000 0001 0010** ba52 03f2 c030 

TARGET_ADDRESS 0x00010000 के रूप में परिभाषित किया गया था।

मैं पिछले दो बाइट्स के महत्व से थोड़ा उलझन में हूं। हालांकि, यह एक और सवाल पूरी तरह से प्रतीत होता है। यह काफी देर हो रही है, और मैं घंटों के लिए कोड और इंटेल मैनुअल पर घूर रहा हूं, इसलिए मुझे उम्मीद है कि मुझे अपना अंक मिल जाएगा।

देखने के लिए धन्यवाद!

+0

लोग 2 कारणों से ऑपकोड (निर्देशों के बजाए) का उपयोग करते हैं।पहला कारण यह है कि जब असेंबलर "पर्याप्त से कम" होता है और उसे आवश्यक निर्देश के लिए समर्थन प्रदान नहीं करता है (यह तब होता है जब नए निर्देश जोड़े जाते हैं और पुराने असेंबलर अभी तक उनका समर्थन नहीं करते हैं)। दूसरा कारण यह है कि जब असेंबलर निर्देश की सहायता करता है तो उन्हें आवश्यकता होती है लेकिन प्रोग्रामर यह नहीं जानता कि इसे उत्पन्न करने के लिए असेंबलर को कैसे मनाने के लिए। असल में, यह या तो खराब उपकरण है (पुराने उपकरण, भ्रमित वाक्यविन्यास और/या खराब दस्तावेज सहित) या खराब प्रोग्रामर। – Brendan

+0

नोट: ऊपर मेरी टिप्पणी "सामान्य रूप से" है और सभी असेंबलरों पर लागू होती है। मैं जीएएस का उपयोग नहीं करता, और मुझे कोई जानकारी नहीं है कि यह "16-बिट कोड में 32-बिट दूर कूद" निर्देश का समर्थन करता है या नहीं (या दस्तावेज कितना अच्छा/बुरा है)। – Brendan

उत्तर

12

0x66 इंगित करता है कि जेएमपी (0xEA) छह बाइट्स को संदर्भित करता है। डिफ़ॉल्ट वास्तविक मोड में 64K (16 बिट्स) या संरक्षित मोड में 32 बिट्स (यदि मुझे अच्छी तरह से याद है) में प्रतिबिंबित किया जा रहा है। इसे बढ़ाने के बाद, इसमें सेगमेंट डिस्क्रिप्टर, या तो जीडीटी या एलडीटी में सेगमेंट की अनुक्रमणिका भी शामिल है, जिसका अर्थ यह है कि यह कोड परंपरागत रूप से "लंबी कूद" कहलाता है: एक कूद जो सेगमेंट से परे पार हो जाती है x86 वास्तुकला। इस मामले में सेगमेंट जीडीटी पर दूसरी प्रविष्टि को इंगित करता है। यदि आप उस कार्यक्रम में पहले देखते हैं, तो आप देखेंगे कि जीडीटी को सेगमेंट और लम्बाई शुरू करने वाले सेगमेंट के संदर्भ में कैसे परिभाषित किया गया है (जीडीटी और एलडीटी टेबल का अध्ययन करने के लिए इंटेल मैनुअल में देखें, प्रत्येक सेगमेंट का वर्णन करने वाली 32 बिट एंट्री)।

+0

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

+0

फिर फिर, मैं अभी भी उत्सुक हूं कि लेखक ने निमोनिक्स का उपयोग करने के बजाय ऐसा क्यों करना चुना। –

+0

यह ऑपरेंड-आकार उपसर्ग है, लेकिन यह इसे 'jmp ptr16: 16' से' jmp ptr16: 32'] में बदलता है (http://felixcloutier.com/x86/JMP.html)। इस उत्तर का दावा है कि नो-प्रीफिक्स संस्करण 'jmp rel16' या' jmp rel32' होगा, लेकिन यह एक अलग ऑपोड है, 'E9' 'EA' नहीं है। 'ईए 'हमेशा ऑफसेट और सेगमेंट के साथ एक दूर-जेएम है। –

2

मैं इसे थोड़ा सा चलाता हूं। कुछ असेंबलर केवल एक लेबल में कूदेंगे। इस मामले में व्यक्ति एक विशिष्ट हार्ड कोडित ऑफ़सेट पर पूर्ण कूद बनाना चाहता है। jmp TARGET_ADDRESS काम नहीं करेगा मैं अनुमान लगा रहा हूं, इसलिए उन्होंने इसे इस मुद्दे को हल करने के लिए बस बाइट्स के रूप में रखा है।

0

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