2012-09-24 19 views
22

x86マシンでNOPLの機能は何ですか?それは何もしないように感じますが、なぜそれがアセンブリコード内にあるのですか?NOPLはx86システムで何をしますか?

+5

「なぜアセンブリコードにはいつも入っていますか? - 通常、アセンブリコードには多くのNOPがありません。あなたが見ている特定のコードには多くのNOPがありますか? – ugoren

+5

男、コードがしていることを「感じる」ことができたらよかった! –

+0

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

答えて

31

NOPは、1バイトの「何もしない」操作であり、文字通り「操作なし」です。 NOPW、NOPLなどは同等の注意点ですが、単語とロングサイズのバイトを取ります。

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

は、彼らはパディング物事アウトのために非常に便利です

NOPW // 2byte opcode. 

を行うことと等価であるので、コードシーケンスは、命令スペースの数バイトを取ることで、特定のメモリ境界から始まり、まだありません実際に何かをしている。

CPUのNOPの唯一の効果はNOPX同等物は、2、4、などによってそうします。1.でIP/EIPをインクリメントすることです...

+1

x86の命令セットの操作NOPWおよびNOPLについて聞いたことはありません。彼らはIntelの命令セットリファレンスに表示されます:)別のアーキテクチャを混在させているかもしれません – Jack

+4

@ジャックはAT&Tの構文のようなにおいが私にあります – harold

+0

@harold分かりませんgopはnopw/noplをnopの代わりに使用すると文句を言います。 – Jack

28

編集:gasドキュメントへの追加しまし参照とgasエンコーディング異なるnop形態について:John Fremlin's blog: Operands to NOP on AMD64nopwnoplなどによると

ない& T構文AT gas構文、です。

以下は、命令長が3〜15バイトの場合のの場合のgasによって生成された命令エンコードです。gas sourceです。いくつかはインテルが推奨するnopフォーム(以下を参照)と同じであるが、すべてではないことに注意してください。インテルのは、任意の単一推奨nopの命令で複数の0x66オペランドの接頭辞を使用することはありませんnopフォームを推奨一方長いで、特定のnopのではgasは、(5まで)、複数の異なる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}; 

Intelは異なる構文を使用して、1〜9バイトからすべての命令長のために利用可能なnop」Sが存在します。 nopにはいくつかの異なるものがあります。すべてnopの2バイトより長いものは1オペランドを受け入れます。 1バイトnop0x90)は、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に加えて、Sあまりにも「はインテルが推奨するのは、多くの他の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のフォームをお勧めします。マークBが答えで述べるように、命令を特定のメモリ境界に合わせることに加えて、nopは、自己修正コード、デバッグ、リバースエンジニアリングにも非常に役立ちます。

+7

amd64では、 'nop'はもはや' xchg eax、eax'と同義ではないことに注意してください。 'nop'は' eax'の上位32ビットをゼロにしませんが、 'xchg eax、eax'は行いません。 – fuz

5

実際には、コードをパッチする必要がある場合、アセンブリコードにNOPが使用されます。

新しい命令のサイズが古い命令のサイズと異なる可能性があるため、パディングが必要です。

パディング命令は、いくつかのバイトを占める可能性がありますが、NOPと同じように動作する必要があります。

いくつかのNOPの代わりに66 90のようなより複雑な命令を挿入する理由は、1つの命令が一般的にいくつかのNOPよりも速く実行されるからです。

関連する問題