स्टेटिक रीकंपिलेशन एक विदेशी वास्तुकला से दूसरे लक्ष्य आर्किटेक्चर में बाइनरी का अनुवाद करने का एक आशाजनक तरीका है। यह जस्ट-इन-टाइम (जेआईटी) से तेज़ होगा, क्योंकि इसे चलाने से पहले कोड को संकलित करने की आवश्यकता नहीं है, और क्योंकि अतिरिक्त संकलन समय यह उत्पन्न हो सकता है जेनरेट कोड को अनुकूलित करने के लिए उपयोगी है।
हालांकि जेआईटी संकलन गतिशील प्रोग्राम विश्लेषण का उपयोग करता है, जबकि स्थैतिक पुनर्मूल्यांकन स्थैतिक कार्यक्रम विश्लेषण (इसलिए नाम) पर निर्भर करता है।
स्थिर विश्लेषण में, आपके पास निष्पादन पर रनटाइम जानकारी नहीं है।
इसके साथ एक बड़ी समस्या अप्रत्यक्ष कूद से उत्पन्न होती है। शब्द कोड को कवर करता है जो फ़ंक्शन पॉइंटर्स के उपयोग से या रनटाइम पॉलीमोर्फिज्म (आभासी तालिका सोचने) से कुछ switch
कथन से उत्पन्न किया जा सकता है। यह सब फार्म की एक अनुदेश करने पर निर्भर करता:
JMP reg_A
मान लें कि अपने कार्यक्रम की शुरुआत का पता जानते हैं, और आप इस बिंदु से निर्देश पुन: संयोजित करने के लिए शुरू फैसला किया। जब आप सीधे कूदते हैं, तो आप अपने लक्षित पते पर जाते हैं, और आप वहां से पुनर्मूल्यांकन जारी रखते हैं। जब आप अप्रत्यक्ष कूद का सामना करते हैं, तो आप अटक जाते हैं। इस असेंबली निर्देश में, reg_A
की सामग्री स्थैतिक रूप से ज्ञात नहीं है। इसलिए, हम अगले निर्देश का पता नहीं जानते हैं। ध्यान दें कि गतिशील पुनर्मूल्यांकन में, हमारे पास यह समस्या नहीं है, क्योंकि हम रजिस्टरों की आभासी स्थिति का अनुकरण करते हैं, और हम reg_A
की वर्तमान सामग्री को जानते हैं। इसके अलावा, स्थैतिक पुनर्मूल्यांकन में, आप सभी इस बिंदु पर reg_A
के संभावित मानों को खोजने में रुचि रखते हैं, क्योंकि आप संकलित सभी संभावित पथ चाहते हैं। गतिशील विश्लेषण में, आपको वर्तमान में निष्पादित करने वाले पथ को उत्पन्न करने के लिए केवल वर्तमान मान की आवश्यकता है, reg_A
अपना मान बदलना चाहिए, फिर भी आप अन्य पथ उत्पन्न कर पाएंगे। कुछ मामलों में, स्थिर विश्लेषण उम्मीदवारों की एक सूची पा सकता है (यदि यह switch
है तो कहीं भी संभावित ऑफसेट की एक तालिका होनी चाहिए), लेकिन सामान्य मामले में हम बस नहीं जानते हैं।
ठीक, आप कहते हैं, चलिए बाइनरी में सभी निर्देशों को फिर से सम्मिलित करते हैं!
समस्या यह है कि अधिकांश बाइनरी में कोड और डेटा दोनों होते हैं। आर्किटेक्चर के आधार पर, आप यह बताने में सक्षम नहीं होंगे कि कौन सा है।
बदतर, कुछ आर्किटेक्चर में कोई संरेखण बाधाएं और परिवर्तनीय चौड़ाई निर्देश नहीं हैं, और आप किसी बिंदु पर अलग-अलग हो सकते हैं, केवल यह पता लगाने के लिए कि आपने ऑफसेट के साथ पुनः संकलन शुरू कर दिया है।
के एक सरल अनुदेश दो निर्देश शामिल सेट और एक एकल रजिस्टर A
लेते हैं:
41 42
मान लीजिए कि प्रारंभ बिंदु पहली बाइट 41
है दो:
41 xx (size 2): Add xx to `A`.
42 (size 1): Increment `A` by one.
के निम्नलिखित द्विआधारी कार्यक्रम लेते हैं । आप कार्य करें:
41 42 (size 2): Add 42 to `A`.
लेकिन क्या 41 यदि डेटा का एक टुकड़ा है? फिर अपने कार्यक्रम हो जाता है:
42 (size 1): Increment `A` by one.
यह समस्या पुराने खेल है, जो अक्सर विधानसभा में सीधे अनुकूलित किया गया में बढ़ाया जाए, और जहां प्रोग्रामर हो सकता है जानबूझकर expect some byte to be interpreted as both code and data, depending on the context!
भी बदतर, फिर कंपाइल कार्यक्रम हो सकता है कोड स्वयं! एक जेआईटी कंपाइलर recompiling कल्पना कीजिए। नतीजा अभी भी स्रोत आर्किटेक्चर के लिए आउटपुट कोड होगा और इस पर कूदने की कोशिश करेगा, संभवतः कार्यक्रम को जल्द ही मरने का कारण बन जाएगा। स्थिर रूप से पुन: संकलित कोड जो केवल रनटाइम पर उपलब्ध है, अनंत ट्रिकरी की आवश्यकता है!
स्टेटिक बाइनरी विश्लेषण अनुसंधान का एक बहुत ही जीवंत क्षेत्र है (मुख्य रूप से सुरक्षा के क्षेत्र में, उन प्रणालियों में भेद्यता की तलाश करने के लिए जिनके स्रोत उपलब्ध नहीं हैं), और वास्तव में मुझे NES emulator that tries to statically recompile programs बनाने का प्रयास पता है। लेख बहुत दिलचस्प है।
जेआईटी और स्थैतिक पुनर्मूल्यांकन के बीच एक समझौता यथासंभव अधिक से अधिक कोड को पुन: संकलित करना होगा, केवल बिट्स को स्थिर रूप से अनुवादित नहीं किया जा सकता है।
यह कुछ बार किया गया है। उदाहरण के लिए, डीईसी का एफएक्स! 32 डीईसी अल्फा पर चलाने के लिए x86 बाइनरी का पुन: संकलित किया गया, जो कि समय के किसी भी x86 से अधिक तेज़ हो सकता था। हालांकि डीईसी (गलत) प्रबंधन के लिए तैयार नहीं था, और कॉम्पैक/एचपी ने इसके बारे में ज्यादा परवाह नहीं की थी। –
यदि मामला है तो अनुकरणकर्ता भी क्यों मौजूद हैं? क्या यह वास्तव में * है * एक एमुलेटर लिखने से ज्यादा कठिन है? – user1483857