x86 マシンの NOPL の機能は何ですか? 何もしていないように感じますが、なぜアセンブリ コードに常にあるのでしょうか。
3 に答える
NOP
1バイトの「何もしない」操作であり、文字通り「操作なし」です。NOPW、NOPL などは同等の何もしないものですが、単語と長いサイズのバイトを消費します。
例えば
NOP // 1byte opcode
NOP // 1byte opcode
することと同等です
NOPW // 2byte opcode.
これらは、実際には何もせずに数バイトの命令空間を占有することにより、コードシーケンスが特定のメモリ境界で開始されるように、何かをパディングするのに非常に便利です。
CPU に対する NOP の唯一の効果は、IP
/EIP
を 1 ずつインクリメントすることです。NOPx に相当するものは、2、4 などでインクリメントします...
John Fremlin のブログによると、AMD64のNOP へのオペランドnopw
、nopl
などはgas
構文であり、AT&T 構文ではありません。
以下は、命令長が 3 ~ 15 バイトの場合に、ソースgas
とは異なるによって生成される命令エンコーディングです。一部は Intel の推奨フォーム (以下を参照) と同じですが、すべてではないことに注意してください。特に、 in longでは、異なる形式で複数 (最大 5 つ) の連続したオペランド プレフィックスを使用しますが、Intel の推奨形式では、単一の推奨命令で複数のオペランド プレフィックスを使用することはありません。nop
gas
nop
nop
gas
0x66
nop
nop
0x66
nop
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
半角nop
(0x90
)は と同義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
したがって、nop
Intel が推奨するこれらの に加えて、他にも多くの がありnop
ます。Marc B が回答で述べているように、命令を特定のメモリ境界に揃えることに加えて、nop
コードの自己変更、デバッグ、およびリバース エンジニアリングにも非常に役立ちます。