2008-09-05 19 views
19

वर्चुअल मशीन फ्लाई पर देशी मशीन कोड कैसे उत्पन्न करती है और इसे निष्पादित करती है?जेआईटी कोड जनरेशन तकनीक

मान लीजिए कि आप मूल मशीन ओप-कोड क्या हैं जिन्हें आप उत्सर्जित करना चाहते हैं, आप वास्तव में इसे चलाने के बारे में कैसे जाते हैं?

क्या यह बाइकरी कोडों के लिए निमोनिक निर्देशों को मैप करने के रूप में हैकी के रूप में कुछ है, इसे एक char * सूचक में भरना और इसे एक समारोह और निष्पादन के रूप में कास्टिंग करना है?

या आप एक अस्थायी साझा लाइब्रेरी (.dll या .so या जो कुछ भी) उत्पन्न करेंगे और LoadLibrary जैसे मानक कार्यों का उपयोग करके इसे स्मृति में लोड करेंगे?

उत्तर

8

आप केवल उस कोड को program counter बिंदु बना सकते हैं जिसे आप निष्पादित करना चाहते हैं। याद रखें कि डेटा डेटा या कोड हो सकता है। X86 पर प्रोग्राम काउंटर ईआईपी रजिस्टर है। ईआईपी का आईपी हिस्सा निर्देश सूचक के लिए है। जेएमपी निर्देश को एक पते पर कूदने के लिए बुलाया जाता है। कूदने के बाद ईआईपी में यह पता होगा।

क्या यह बाइकरी कोडों के लिए निमोनिक निर्देशों को मैप करने के रूप में हैकी के रूप में कुछ है, इसे एक char * सूचक में भरना और इसे एक समारोह और निष्पादन के रूप में कास्टिंग करना है?

हां। यह करने का यह एक तरीका है। परिणामस्वरूप कोड pointer to function में सी

1

जहां तक ​​मुझे पता है कि यह स्मृति में सबकुछ संकलित करता है क्योंकि इसे कोड को अनुकूलित करने के लिए कुछ हेरिस्टिक चलाते हैं (यानी: समय के साथ इनलाइनिंग) लेकिन आप Shared Source Common Language Infrastructure 2.0 रोटर रिलीज को देख सकते हैं। संपूर्ण कोडबेस जेटर और जीसी को छोड़कर .NET के समान है।

1

साथ ही रोटर 2.0 - आप ओपनजेडीके में HotSpot virtual machine पर भी देख सकते हैं।

6

क्या यह बाइकरी कोडों के लिए निमोनिक निर्देशों को मैप करने के रूप में हैकी के रूप में कुछ है, इसे एक char * सूचक में भरना और इसे एक समारोह और निष्पादन के रूप में कास्टिंग करना है?

हाँ, यदि आप इसे सी या सी ++ (या कुछ समान) में कर रहे थे, तो वही है जो आप करेंगे।

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

यदि आप वास्तव में ऐसा करने का प्रयास करते हैं, हालांकि, सुनिश्चित करें कि आप अपने सी प्रोग्राम पर वापस आने पर कॉलिंग सम्मेलन को सही तरीके से प्राप्त करें। मुझे लगता है कि अगर मैं कोड उत्पन्न करना चाहता हूं तो मैं अपने लिए उस पहलू की देखभाल करने के लिए एक पुस्तकालय की तलाश करूंगा। नैनोजीत हाल ही में खबरों में रहा है; आप इसे देख सकते हैं।

4

यूप। आप बस एक char * बनाते हैं और इसे निष्पादित करते हैं। हालांकि, आपको कुछ विवरणों को ध्यान में रखना होगा। Char * स्मृति के निष्पादन योग्य खंड में होना चाहिए और उचित संरेखण होना चाहिए।

नैनोजीत के अलावा आप एलएलवीएम भी देख सकते हैं जो एक और लाइब्रेरी है जो एक फ़ंक्शन पॉइंटर पर विभिन्न प्रोग्राम प्रस्तुतियों को संकलित करने में सक्षम है। यह इंटरफ़ेस साफ़ है और जेनरेट कोड प्रभावी होने लगता है।

1

डीएलएल उत्पन्न करने के बारे में: इसके लिए अतिरिक्त आवश्यक I/O, प्लस लिंकिंग, साथ ही डीएलएल प्रारूप उत्पन्न करने की जटिलता, इससे अधिक जटिल हो जाएगी, और इससे ऊपर वे प्रदर्शन को मार देंगे; इसके अतिरिक्त, अंत में आप अभी भी लोड कोड पर फ़ंक्शन पॉइंटर को कॉल करते हैं, इसलिए ... इसके अलावा, एक समय में जेआईटी संकलन एक विधि हो सकता है, और यदि आप ऐसा करना चाहते हैं तो आप बहुत सारे छोटे डीएलएल उत्पन्न करेंगे।

"निष्पादन योग्य अनुभाग" आवश्यकता के बारे में, POSIX सिस्टम पर mprotect() को कॉल करने से अनुमतियां ठीक हो सकती हैं (Win32 पर एक समान API है)। आपको इसे एक बड़े मेमोरी सेगमेंट के लिए करने की ज़रूरत है, इसके बजाय प्रति विधि एक बार यह बहुत धीमी होगी।

सादा x86 पर आप पीएई या 64 बिट एएमडी 64/इंटेल 64 बिट मशीनों के साथ x86 पर समस्या को नहीं देख पाएंगे, आपको एक सेगफॉल्ट मिलेगा।

1

यह मानचित्रण के रूप में के रूप में hacky स्मरक निर्देश कुछ द्विआधारी कोड के लिए है, यह एक चार * सूचक में भरने और एक समारोह और क्रियान्वित करने के रूप में यह कास्टिंग?

हाँ, यह काम करता है।

खिड़कियों में ऐसा करने के लिए आप आवंटित ब्लॉक करने के लिए PAGE_EXECUTE_READWRITE सेट करना होगा:

void (*MyFunc)() = (void (*)()) VirtualAlloc(NULL, sizeofblock, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 

//Now fill up the block with executable code and issue- 

MyFunc(); 
संबंधित मुद्दे