LEA EAX有什么意义,[EAX]?

Fre*_*ool 43 c x86 assembly instruction-set

LEA EAX, [EAX]
Run Code Online (Sandbox Code Playgroud)

我在使用Microsoft C编译器编译的二进制文件中遇到此指令.它显然无法改变EAX的价值.那为什么呢?

cod*_*ict 81

这是一个NOP.

以下是典型的用途NOP.他们都做同样的事情,但他们导致不同长度的机器代码.根据对齐要求,选择其中一个:

xchg eax, eax         = 90
mov eax, eax          = 89 C0 
lea eax, [eax + 0x00] = 8D 40 00 
Run Code Online (Sandbox Code Playgroud)

  • 实际上,`nop`的操作码是`0x90`,它与`xchg eax,eax`相同. (11认同)
  • 实际上,它并不是严格意义上的"NOP",因为它引入了对"EAX"的数据依赖性.现代CPU将此特定模式检测为"NOP"并忽略数据依赖性,但某些较旧的CPU可能不会. (6认同)
  • ++这是有道理的 (3认同)

Fre*_*ool 34

这篇文章:

MSVC++编译器使用此技巧发出不同长度的NOP指令(用于跳转目标之前的填充).例如,如果MSVC++需要4字节和6字节填充,则会生成以下代码:

8d6424 00 lea [ebx + 00],ebx; 4字节填充8d9b 00000000
lea [esp + 00000000],esp; 6字节填充

第一行在编译器生成的汇编列表中标记为"npad 4",第二行是"npad 6".寄存器(ebx,esp)可以从很少使用的寄存器中选择,以避免代码中的错误依赖.

所以这只是一种NOP,出现在jmp指令的目标之前,以便对齐它们.

有趣的是,您可以从这些指令的特征性质中识别编译器.

  • 说它是一个"NOP"只是答案的一半(奇怪的是,所选的一个).解释为什么你想要做这些'NOP'是完整的答案.做得好. (2认同)