41

x86 マシンの NOPL の機能は何ですか? 何もしていないように感じますが、なぜアセンブリ コードに常にあるのでしょうか。

4

3 に答える 3

48

NOP1バイトの「何もしない」操作であり、文字通り「操作なし」です。NOPW、NOPL などは同等の何もしないものですが、単語と長いサイズのバイトを消費します。

例えば

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

することと同等です

NOPW // 2byte opcode.

これらは、実際には何もせずに数バイトの命令空間を占有することにより、コードシーケンスが特定のメモリ境界で開始されるように、何かをパディングするのに非常に便利です。

CPU に対する NOP の唯一の効果は、IP/EIPを 1 ずつインクリメントすることです。NOPx に相当するものは、2、4 などでインクリメントします...

于 2012-09-24T05:49:54.063 に答える
44

John Fremlin のブログによると、AMD64のNOP へのオペランドnopwnoplなどはgas構文であり、AT&T 構文ではありません。

以下は、命令長が 3 ~ 15 バイトの場合に、ソースgasとは異なるによって生成される命令エンコーディングです。一部は Intel の推奨フォーム (以下を参照) と同じですが、すべてではないことに注意してください。特に、 in longでは、異なる形式で複数 (最大 5 つ) の連続したオペランド プレフィックスを使用しますが、Intel の推奨形式では、単一の推奨命令で複数のオペランド プレフィックスを使用することはありません。nopgasnopnopgas0x66nopnop0x66nop

nopガス2.30 のソース コードからのエンコーディング(読みやすくするために再フォーマット):

/* nopl (%[re]ax) */
static const unsigned char alt_3[] = {0x0f,0x1f,0x00};
/* nopl 0(%[re]ax) */
static const unsigned char alt_4[] = {0x0f,0x1f,0x40,0x00};
/* nopl 0(%[re]ax,%[re]ax,1) */
static const unsigned char alt_5[] = {0x0f,0x1f,0x44,0x00,0x00};
/* nopw 0(%[re]ax,%[re]ax,1) */
static const unsigned char alt_6[] = {0x66,0x0f,0x1f,0x44,0x00,0x00};
/* nopl 0L(%[re]ax) */
static const unsigned char alt_7[] = {0x0f,0x1f,0x80,0x00,0x00,0x00,0x00};
/* nopl 0L(%[re]ax,%[re]ax,1) */
static const unsigned char alt_8[] = {0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* nopw 0L(%[re]ax,%[re]ax,1) */
static const unsigned char alt_9[] =
  {0x66,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
/* nopw %cs:0L(%[re]ax,%[re]ax,1) */
static const unsigned char alt_10[] =
  {0x66,0x2e,0x0f,0x1f,0x84,0x00,0x00,0x00,0x00,0x00};
static const unsigned char *const alt_patt[] = {
  f32_1, f32_2, alt_3, alt_4, alt_5, alt_6, alt_7, alt_8,
  alt_9, alt_10
};

Intel は異なる構文を使用しておりnop、1 から 9 バイトまでのすべての命令長に使用できる があります。2 バイトより長いnopすべての は 1 つのオペランドを受け入れるため、いくつかの異なる があります。nop半角nop0x90)は と同義xchg (e)ax,(e)axです。

Intel® 64 and IA-32 Architectures Software Developer's Manual, Volume 2 (2A, 2B & 2C): Instruction Set Reference, AZ, Chapter 4: INSTRUCTION SET REFERENCE, MZnopには、さまざまな命令長の推奨形式がリストされています。

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

したがって、nopIntel が推奨するこれらの に加えて、他にも多くの がありnopます。Marc B が回答で述べているように、命令を特定のメモリ境界に揃えることに加えて、nopコードの自己変更、デバッグ、およびリバース エンジニアリングにも非常に役立ちます。

于 2012-09-24T11:23:34.737 に答える