एनओपी निर्देश का उद्देश्य और x86 विधानसभा में संरेखित कथन


15

एक या दो साल हो गए हैं क्योंकि मैंने आखिरी बार असेंबली क्लास ली थी। उस कक्षा में, हम इरविन पुस्तकालयों के साथ MASM का उपयोग कर रहे थे ताकि इसमें प्रोग्राम करना आसान हो सके।

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

किसी को पता है?


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

11
एनओपी वास्तव में कुछ करता है। यह इंस्ट्रक्शन पॉइंटर को बढ़ाता है।
१०:१२ बजे एरिकसोफर

जवाबों:


37

अक्सर समय NOPका उपयोग निर्देश पते संरेखित करने के लिए किया जाता है। यह आमतौर पर उदाहरण के लिए सामना किया जाता है जब शेलकोड को बफर ओवरफ्लो या प्रारूप स्ट्रिंग भेद्यता का फायदा उठाने के लिए लिखते हैं ।

कहते हैं कि आपके पास 100 बाइट्स के लिए एक सापेक्ष छलांग है, और कोड में कुछ संशोधन करें। संभावना यह है कि आपके संशोधन कूद लक्ष्य के पते को गड़बड़ कर देते हैं और जैसे कि आपको पूर्वोक्त सापेक्ष कूद को भी बदलना होगा। यहां, आप NOPलक्ष्य पते को आगे बढ़ाने के लिए s जोड़ सकते हैं । यदि आपके पास NOPलक्ष्य पते और कूदने के निर्देश के बीच कई s हैं, तो आप NOPलक्ष्य पते को पीछे की ओर खींचने के लिए s हटा सकते हैं।

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

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

फिर भी NOPनिर्देश के लिए एक और विशेष उपयोग तब होता है जब कोई किसी प्रोग्राम के कोड को संशोधित करता है। उदाहरण के लिए, आप सशर्त छलांग के कुछ हिस्सों को NOPएस के साथ बदल सकते हैं और इस तरह की स्थिति को कम कर सकते हैं। यह एक अक्सर इस्तेमाल किया जाने वाला तरीका है जब सॉफ्टवेयर को " क्रैकिंग " कॉपी प्रोटेक्शन। सरलतम रूप से यह कोड की if(genuineCopy) ...लाइन के लिए विधानसभा कोड निर्माण को हटाने और NOPs और .. के साथ निर्देशों की जगह लेने के बारे में है! कोई जांच नहीं की जाती है और गैर-वास्तविक प्रतिलिपि काम करती है!

ध्यान दें कि संक्षेप में शेलकोड और क्रैकिंग दोनों उदाहरण समान हैं; संचालन के सापेक्ष पते को अपडेट किए बिना मौजूदा कोड को संशोधित करें जो सापेक्ष पते पर निर्भर करते हैं।


2
यह एक अद्भुत जवाब था, यह समझाने के लिए समय निकालने के लिए धन्यवाद! मैं अंत में समझ गया!
अल्वानेलोस

कुछ रियल-टाइम सिस्टम (पीएलसी दिमाग में आते हैं) आपको मौजूदा प्रोग्राम में नए लॉजिक को "पैच" करने की अनुमति देते हैं। ये सिस्टम हर छोटे से छोटे तर्क से पहले NOP को छोड़ देते हैं ताकि आप NOP को एक नए जंप के साथ ओवरराइट कर सकें जो आप डाल रहे हैं। नए तर्क के अंत में यह आपके द्वारा प्रतिस्थापित किए जा रहे मूल तर्क के अंत में कूद जाएगा। नए लॉजिक के सामने एक NOP भी होगा जिससे आप नए लॉजिक को भी बदल सकते हैं।
स्कॉट व्हिटलॉक 19

10

जब कोई अन्य निर्देश वहां रखा जा सकता है, तो एक एनओपी को एक देरी स्लॉट में इस्तेमाल किया जा सकता है।

lw   v0,4(v1)
jr   v0

MIPS में, यह एक बग होगा क्योंकि उस समय jr रजिस्टर v0 को पढ़ रहा था रजिस्टर v0 को पिछले निर्देश से अभी तक मूल्य के साथ लोड नहीं किया गया है।

इसे ठीक करने का तरीका होगा:

lw   v0,4(v1)
nop
jr   v0
nop

यह लोड वर्ड के बाद घातक स्लॉट्स को भरता है और जप रजिस्टर निर्देशों को एक एनओपी के साथ भरता है ताकि जम्प रजिस्टर कमांड निष्पादित होने से पहले लोड वर्ड इंस्ट्रक्शन पूरा हो जाए।

आगे पढ़ने - देरी स्लॉट्स के स्पार्क भरने पर थोड़ा । उस दस्तावेज़ से:

देरी स्लॉट में क्या डाला जा सकता है?

  • कुछ उपयोगी निर्देश जिसे निष्पादित किया जाना चाहिए चाहे आप शाखा करें या नहीं।
  • कुछ निर्देश जो केवल तब काम करते हैं जब आप शाखा करते हैं (या जब आप शाखा नहीं करते हैं), लेकिन दूसरे मामले में निष्पादित होने पर कोई नुकसान नहीं करता है।
  • जब बाकी सब विफल हो जाता है, तो एक एनओपी निर्देश

देरी स्लॉट में क्या नहीं डाला जाना चाहिए?

  • कुछ भी जो सीसी को निर्धारित करता है कि शाखा का निर्णय निर्भर करता है। ब्रांच इंस्ट्रक्शन इस बात का निर्णय करता है कि ब्रांच को सही है या नहीं, लेकिन यह वास्तव में ब्रांच को देरी के निर्देश के बाद तक नहीं करता है। (केवल शाखा में देरी हुई है, निर्णय नहीं।)
  • एक और शाखा निर्देश। (यदि आप ऐसा करते हैं तो क्या होता है यह भी परिभाषित नहीं किया गया है! परिणाम अप्रत्याशित है!)
  • एक "सेट" निर्देश। यह वास्तव में दो निर्देश हैं, एक नहीं, और इसका केवल आधा विलंब स्लॉट में होगा। (असेंबलर आपको इस बारे में चेतावनी देगा।)

देरी स्लॉट में डालने के लिए तीसरे विकल्प पर ध्यान दें। बग जो आपने देखा था, संभवत: कोई व्यक्ति उन चीजों में से एक को भर रहा है जो देरी स्लॉट में नहीं डालनी चाहिए। उस स्थान पर एक झपकी लगाना तो बग को ठीक कर देगा।

नोट: प्रश्न को फिर से पढ़ने के बाद, यह x86 के लिए था, जिसमें देरी स्लॉट्स नहीं हैं (इसके बजाय पाइपलाइन स्टाल करते हैं)। तो यह बग का कारण / समाधान नहीं होगा। RISC सिस्टम पर, इसका उत्तर हो सकता है।


4
ध्यान दें कि प्रश्न x86 को टैग किया गया है, और x86 में विलंब स्लॉट नहीं है। कभी नहीं, या तो, क्योंकि यह एक टूटने वाला बदलाव है।
MSalters

6

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


यह बिल्कुल नहीं है कि ब्लॉक को संरेखित करने की आवश्यकता है, यह है कि आप पिछले ब्लॉक के अंतिम युगल बाइट प्राप्त नहीं करना चाहते हैं। इसलिए कूदना ठीक है 0x1002, क्योंकि 16B के संरेखित ब्लॉक में अभी भी 14 बाइट्स निर्देश हैं जिनमें लक्ष्य पता शामिल है, लेकिन कूदने के लिए ठीक नहीं है 0x099D
पीटर कॉर्डेस

3

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


1
आमतौर पर लंबे समय तक फ्रेम, जैसे 1 सेकंड, टाइमर का उपयोग किया जाता है। NOPS का उपयोग घड़ी की परिमाण के एक क्रम के भीतर-नैनो और माइक्रो सेकंड के लिए किया जाता है।
मटनज़

यह केवल एक माइक्रोकंट्रोलर पर समझ में आता है, न कि आधुनिक x86। अधिकांश x86 कोड आधुनिक सुपरस्लेकर आउट-ऑफ-ऑर्डर सीपीयू की पाइपलाइन चौड़ाई को संतृप्त नहीं करता है, इसलिए अधिकांश कोड में प्रत्येक निर्देश के बीच एक एनओपी जोड़ने से केवल एक छोटा प्रभाव पड़ेगा (मुझे लगता है कि "औसत" कोड के लिए संख्या हो सकती है) निर्देशों की संख्या को दोगुना करने के लिए 5 से 20%, कुछ कोड के साथ कोई मंदी नहीं, लेकिन कुछ तंग छोरों को लगभग 2x मंदी दिखा रहा है।) वैसे भी, क्रस्टी पुराने x86 कोड परंपरागत रूप से loopदेरी छोरों के लिए निर्देश का उपयोग करते थे , एनओपी नहीं।
पीटर कॉर्ड्स

3

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

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


3

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


    STI
    CLI

यह लंबित व्यवधान को संसाधित नहीं करेगा, क्योंकि इंटेल का हवाला देते हुए:

आईएफ फ्लैग सेट होने के बाद, प्रोसेसर अगले निर्देश के निष्पादित होने के बाद बाहरी, मुखौटा करने योग्य व्यवधान का जवाब देना शुरू कर देता है।

तो यह कम से कम के रूप में फिर से लिखा जाएगा:


    STI
    NOP
    CLI

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


-2

एनओपी का मतलब है नो ऑपरेशन

इसका उपयोग आमतौर पर मशीन कोड डालने या हटाने या किसी विशेष कोड के निष्पादन में देरी के लिए किया जाता है।

ब्रेकपॉइंट सेट करने के लिए पटाखे और डिबगर्स द्वारा भी उपयोग किया जाता है।

तो शायद कुछ ऐसा कर रहे हैं: XCHG BX, BX भी उसी में परिणाम देगा।

मुझे लगता है जैसे कि कुछ ऑपरेशन थे जो अभी भी प्रक्रिया में थे और इसलिए इसमें त्रुटि हुई।

यदि आप VB से परिचित हैं, तो मैं आपको एक उदाहरण दे सकता हूं:

यदि आप vb में एक लॉगिन सिस्टम बनाते हैं, और 3 पेजों को एक साथ लोड करते हैं - facebook, youtube और twitter 3 अलग टैब में।

और सभी के लिए 1 लॉगिन बटन का उपयोग करें। यदि आपका इंटरनेट कनेक्शन धीमा है, तो यह एक त्रुटि दे सकता है। जिसका अर्थ है कि एक पृष्ठ अभी तक लोड नहीं हुआ है। तो हम इसे दूर करने के लिए Application.DoEvents में डालते हैं। असेंबली NOP में समान तरीके का उपयोग किया जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.