LEA EAX,EAX有什么意义?

LEA EAX, [EAX] 

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

这是一个NOP

以下典型地用作NOP 。 他们都做同样的事情,但他们导致不同长度的机器码。 根据alignment要求,select其中一个:

 xchg eax, eax = 90 mov eax, eax = 89 C0 lea eax, [eax + 0x00] = 8D 40 00 

从这篇文章:

这个技巧被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)可以从很less使用的寄存器中select,以避免代码中的错误依赖。

所以这只是一种NOP,正好在jmp指令的目标之前出现,以便alignment它们。

有趣的是,你可以从这些指令的特性中识别编译器。

 LEA EAX, [EAX] 

确实不会改变EAX的价值。 据我所知,它的function与以下相同:

 MOV EAX, EAX 

你有没有看到它在优化的代码,或未优化的代码?