2012-09-24 8 views
22

x86 मशीन में एनओपीएल का कार्य क्या है? ऐसा लगता है कि यह कुछ भी नहीं करता है, लेकिन यह हमेशा असेंबली कोड में क्यों है?एनओपीएल x86 सिस्टम में क्या करता है?

+5

आप पूछते हैं "यह हमेशा असेंबली कोड में क्यों है?" - आम तौर पर आपको असेंबली कोड में बहुत सारे एनओपी नहीं मिलते हैं। क्या आपके द्वारा देखे जा रहे कुछ विशिष्ट कोड में बहुत सारे एनओपी हैं? – ugoren

+5

मैन, मेरी इच्छा है कि मैं "महसूस" कर सकता हूं कि कौन सा कोड करता है! –

+0

http://stackoverflow.com/questions/6776385/what-is-faster-jmp-or-string-of-nops/6777644 –

उत्तर

31

NOP एक-बाइट "कुछ भी नहीं" ऑपरेशन है, जो वास्तव में "कोई ऑपरेशन नहीं" है। एनओपीडब्ल्यू, एनओपीएल, इत्यादि समकक्ष काम करते हैं, लेकिन शब्द और लंबे आकार के बाइट्स लेते हैं।

उदा।

NOP // 1byte opcode 
NOP // 1byte opcode 

NOPW // 2byte opcode. 

कर के बराबर है वे गद्दी बातें बाहर के लिए बहुत आसान कर रहे हैं तो एक कोड अनुक्रम एक विशेष स्मृति सीमा पर शुरू होता है, निर्देश अंतरिक्ष के कुछ बाइट्स लेने से, अभी नहीं वास्तव में कुछ भी कर रहा हूँ।

एनओपी के CPU पर एकमात्र प्रभाव 1. द्वारा IP/EIP बढ़ाने के लिए NOPx समकक्ष 2, 4, आदि द्वारा ऐसा करेंगे है ...

+1

मैंने x86 के निर्देश सेट में ऑपरेशन एनओपीडब्ल्यू और एनओपीएल के बारे में कभी नहीं सुना है .. न ही वे इंटेल इंस्ट्रक्शन सेट रेफरेंस में दिखाई देते हैं :) हो सकता है कि आप विभिन्न आर्किटेक्चर को मिला रहे हों – Jack

+4

@ जैक मुझे एटी एंड टी सिंटैक्स की तरह गंध करता है – harold

+0

@harold पता नहीं है .. gcc शिकायत करता है अगर मैं nop – Jack

28

संपादित करें: gas दस्तावेज और gas एनकोडिंग को जोड़ा संदर्भ विभिन्न nop रूपों के लिए:

John Fremlin's blog: Operands to NOP on AMD64, nopw, nopl आदि के अनुसार

gas वाक्य रचना, एटी नहीं & टी वाक्य रचना कर रहे हैं।

नीचे अनुदेश gas द्वारा 3 से 15 बाइट्स से निर्देश लंबाई के लिए gas source से अलग nop के लिए उत्पन्न एन्कोडिंग कर रहे हैं। ध्यान दें कि कुछ इंटेल की सिफारिश की गई nop रूपों (नीचे देखें) के समान हैं, लेकिन सभी नहीं। लंबे समय तक में विशेष रूप से, nop के अलावा gas, कई (5 तक) विभिन्न nop रूपों में लगातार 0x66 संकार्य उपसर्गों का उपयोग करता है इंटेल की सिफारिश की है, जबकि nop रूपों किसी एक की सिफारिश की nop अनुदेश में एक से अधिक 0x66 संकार्य उपसर्ग का उपयोग कभी नहीं। gas source से

nop एनकोडिंग (पठनीयता के लिए पुन: स्वरूपित):

/* nopl (%[re]ax) */ 
static const char alt_3[] = {0x0f,0x1f,0x00}; 
/* nopl 0(%[re]ax) */ 
static const char alt_4[] = {0x0f,0x1f,0x40,0x00}; 
/* nopl 0(%[re]ax,%[re]ax,1) */ 
static const char alt_5[] = {0x0f,0x1f,0x44,0x00,0x00}; 
/* nopw 0(%[re]ax,%[re]ax,1) */ 
static const char alt_6[] = {0x66,0x0f,0x1f,0x44,0x00,0x00}; 
/* nopl 0L(%[re]ax) */ 
static const char alt_7[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; 
/* nopl 0L(%[re]ax,%[re]ax,1) */ 
static const char alt_8[] = {0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; 
/* nopw 0L(%[re]ax,%[re]ax,1) */ 
static const char alt_9[] = {0x66,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; 
/* nopw %cs:0L(%[re]ax,%[re]ax,1) */ 
static const char alt_10[] = {0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; 
/* data16 
nopw %cs:0L(%[re]ax,%[re]ax,1) */ 
static const char alt_long_11[] = {0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; 
/* data16 
data16 
nopw %cs:0L(%[re]ax,%[re]ax,1) */ 
static const char alt_long_12[] = {0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; 
/* data16 
data16 
data16 
nopw %cs:0L(%[re]ax,%[re]ax,1) */ 
static const char alt_long_13[] = {0x66,0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; 
/* data16 
data16 
data16 
data16 
nopw %cs:0L(%[re]ax,%[re]ax,1) */ 
static const char alt_long_14[] = {0x66,0x66,0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; 
/* data16 
data16 
data16 
data16 
data16 
nopw %cs:0L(%[re]ax,%[re]ax,1) */ 
static const char alt_long_15[] = {0x66,0x66,0x66,0x66,0x66,0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; 
/* nopl 0(%[re]ax,%[re]ax,1) 
nopw 0(%[re]ax,%[re]ax,1) */ 
static const char alt_short_11[] = {0x0f,0x1f,0x44,0x00,0x00,0x66,0x0f,0x1f,0x44,0x00,0x00}; 
/* nopw 0(%[re]ax,%[re]ax,1) 
nopw 0(%[re]ax,%[re]ax,1) */ 
static const char alt_short_12[] = {0x66,0x0f,0x1f,0x44,0x00,0x00,0x66,0x0f,0x1f,0x44,0x00,0x00}; 
/* nopw 0(%[re]ax,%[re]ax,1) 
nopl 0L(%[re]ax) */ 
static const char alt_short_13[] = {0x66,0x0f,0x1f,0x44,0x00,0x00,0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; 
/* nopl 0L(%[re]ax) 
nopl 0L(%[re]ax) */ 
static const char alt_short_14[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00,0x0f,0x1f,0x80,0x00,0x00,0x00,0x00}; 
/* nopl 0L(%[re]ax) 
nopl 0L(%[re]ax,%[re]ax,1) */ 
static const char alt_short_15[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00}; 

इंटेल विभिन्न सिंटैक्स का उपयोग करता है, और nop के 1 से 9 तक बाइट्स से सभी अनुदेश लंबाई के लिए उपलब्ध नहीं है। कई अलग-अलग nop हैं, क्योंकि सभी nop दो बाइट्स से अधिक लंबे समय तक 1 ऑपरेंड स्वीकार करते हैं। वन-बाइट nop (0x90) xchg (e)ax,(e)ax के समानार्थी है।

Table 4-12. Recommended Multi-Byte Sequence of NOP Instruction 

Length Assembly         Byte Sequence 
2 bytes 66 NOP          66 90H 
3 bytes NOP DWORD ptr [EAX]      0F 1F 00H 
4 bytes NOP DWORD ptr [EAX + 00H]     0F 1F 40 00H 
5 bytes NOP DWORD ptr [EAX + EAX*1 + 00H]   0F 1F 44 00 00H 
6 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00H]  66 0F 1F 44 00 00H 
7 bytes NOP DWORD ptr [EAX + 00000000H]   0F 1F 80 00 00 00 00H 
8 bytes NOP DWORD ptr [EAX + EAX*1 + 00000000H] 0F 1F 84 00 00 00 00 00H 
9 bytes 66 NOP DWORD ptr [EAX + EAX*1 + 00000000H] 66 0F 1F 84 00 00 00 00 00H 

तो इन nop के अलावा रों भी 'इंटेल द्वारा की सिफारिश की है, कई अन्य nop हैं':

Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2 (2A, 2B & 2C): Instruction Set Reference, A-Z, CHAPTER 4: INSTRUCTION SET REFERENCE, M-Z सूचियों अलग निर्देश लंबाई के लिए nop रूपों की सिफारिश की। एक विशिष्ट मेमोरी सीमा के लिए निर्देश संरेखित करने के अलावा, जैसा कि मार्क बी ने अपने उत्तर में उल्लेख किया है, nop स्व-संशोधित कोड, डिबगिंग और रिवर्स-इंजीनियरिंग में भी बहुत उपयोगी हैं।

+7

ध्यान दें कि amd64 पर, 'nop' अब' xchg eax, eax' के समानार्थी नहीं है। 'nop'' eax' के शीर्ष 32 बिट्स को शून्य नहीं करता है, लेकिन 'xchg eax, eax' करता है। – fuz

5

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

क्योंकि नए निर्देशों का आकार पुराने लोगों के लिए अलग हो सकता है, पैडिंग की आवश्यकता है।

पैडिंग निर्देश एनओपी के समान कार्य करना चाहिए, हालांकि यह कई बाइट्स पर कब्जा कर सकता है।

कारण है कि हम कई एनओपी की बजाय 66 9 0 की तरह अधिक जटिल निर्देश डालते हैं, एक निर्देश आमतौर पर कई एनओपी की तुलना में अधिक तेज़ी से निष्पादित होता है।

संबंधित मुद्दे