LEA EAX, [EAX]
我在使用 Microsoft C 编译器编译的二进制文件中遇到了这条指令。它显然不能改变 EAX 的值。那为什么会在那里?
LEA EAX, [EAX]
我在使用 Microsoft C 编译器编译的二进制文件中遇到了这条指令。它显然不能改变 EAX 的值。那为什么会在那里?
它是一个NOP
.
以下通常用作NOP
. 它们都做同样的事情,但它们会产生不同长度的机器码。根据对齐要求,选择其中之一:
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)可以从很少使用的寄存器中选择,以避免代码中的错误依赖。
所以这只是一种 NOP,出现在 jmp 指令的目标之前以对齐它们。
有趣的是,您可以从此类指令的特征中识别编译器。
LEA EAX, [EAX]
Indeed 不会改变 EAX 的值。据我了解,它的功能与以下内容相同:
MOV EAX, EAX
您是在优化代码还是未优化代码中看到它?