43
LEA EAX, [EAX]

我在使用 Microsoft C 编译器编译的二进制文件中遇到了这条指令。它显然不能改变 EAX 的值。那为什么会在那里?

4

3 回答 3

82

它是一个NOP.

以下通常用作NOP. 它们都做同样的事情,但它们会产生不同长度的机器码。根据对齐要求,选择其中之一:

xchg eax, eax         = 90
mov eax, eax          = 89 C0 
lea eax, [eax + 0x00] = 8D 40 00 
于 2010-04-24T06:17:43.160 回答
35

这篇文章:

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 指令的目标之前以对齐它们。

有趣的是,您可以从此类指令的特征中识别编译器。

于 2010-04-24T06:18:31.390 回答
3
LEA EAX, [EAX]

Indeed 不会改变 EAX 的值。据我了解,它的功能与以下内容相同:

MOV EAX, EAX

您是在优化代码还是未优化代码中看到它?

于 2010-04-24T06:03:34.767 回答