首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >NOPL在x86系统中是做什么的?

NOPL在x86系统中是做什么的?
EN

Stack Overflow用户
提问于 2012-09-24 05:47:18
回答 3查看 34.5K关注 0票数 43

NOPL在x86机中的作用是什么?感觉它什么也不做,但是为什么它总是在汇编代码中呢?

EN

回答 3

Stack Overflow用户

发布于 2012-09-24 05:49:54

NOP是一个单字节的“什么都不做”的操作,字面意思是“没有操作”。NOPW,NOPL等是等效的不做任何事情,但取字和长字节。

例如:

代码语言:javascript
代码运行次数:0
运行
复制
NOP // 1byte opcode
NOP // 1byte opcode

等于做

代码语言:javascript
代码运行次数:0
运行
复制
NOPW // 2byte opcode.

它们非常方便地填充东西,因此代码序列从特定的内存边界开始,占用几个字节的指令空间,但实际上什么也不做。

NOP对CPU的唯一影响是将IP/EIP增加1,NOPx等效值将增加2、4等。

票数 49
EN

Stack Overflow用户

发布于 2012-09-24 11:23:34

根据John的博客: AMD64上NOP的操作数nopwnopl等是gas语法,而不是AT&T语法。

下面是gas为不同的nop来源生成的指令编码,指令长度从3字节到15字节不等。请注意,有些格式与英特尔推荐的nop窗体相同(见下文),但并非全部。特别是在较长的nopgas中,不同nop窗体中使用多个(最多5个)连续的0x66操作数前缀,而英特尔推荐的nop窗体在任何单个推荐的nop指令中都不会使用多个d13操作数和前缀。

nop编码来自源代码 for gas 2.3(为了可读性而重新格式化):

代码语言:javascript
代码运行次数:0
运行
复制
/* 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
};

英特尔使用不同的语法,所有指令长度从1到9个字节都可以使用nop。有几个不同的nop,因为所有nop的长度都超过两个字节,都可以接受一个操作数。单字节nop (0x90)是xchg (e)ax,(e)ax的同义词。

Intel 64和IA-32架构软件开发人员手册,第2卷(2A、2B和2C):指令集参考,A,第4章:指令集参考,M列出了不同指令长度的推荐nop表单:

代码语言:javascript
代码运行次数:0
运行
复制
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,除了将指令与特定的内存边界对齐外,马克?B在他的回答中提到,nop的指令在自修改代码、调试和逆向工程方面也非常有用。

票数 45
EN

Stack Overflow用户

发布于 2013-10-13 05:08:38

实际上,当代码需要修补时,NOP将在汇编代码中使用。

由于新指令的大小可能与旧指令不同,因此需要填充。

填充指令应该与NOP相同,尽管它可能占用几个字节。

我们插入一个更复杂的指令,比如6690,而不是几个NOPs,是因为一条指令的执行速度通常比几条NOPs更快。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12559475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档