对我来说,这就像一部时髦的电影。它的用途是什么?我应该什么时候使用它?


当前回答

也许只是LEA指令的另一件事。您还可以使用LEA将寄存器快速乘以3、5或9。

LEA EAX, [EAX * 2 + EAX]   ;EAX = EAX * 3
LEA EAX, [EAX * 4 + EAX]   ;EAX = EAX * 5
LEA EAX, [EAX * 8 + EAX]   ;EAX = EAX * 9

其他回答

lea是“加载有效地址”的缩写。它将源操作数的位置引用地址加载到目标操作数。例如,您可以使用它:

lea ebx, [ebx+eax*8]

用一条指令进一步移动ebx指针eax项(在64位/元素数组中)。基本上,您可以从x86体系结构支持的复杂寻址模式中受益,从而有效地操作指针。

LEA指令的另一个重要特征是它不会改变条件代码(如CF和ZF),而通过ADD或MUL等算术指令计算地址则会改变。这一特性降低了指令之间的依赖程度,从而为编译器或硬件调度器的进一步优化腾出了空间。

来自Abrash的“装配禅”:

LEA,唯一执行内存寻址计算但实际上不寻址内存的指令。LEA接受标准内存寻址操作数,但只会将计算出的内存偏移量存储在指定寄存器中,该寄存器可以是任何通用寄存器。这给了我们什么?ADD没有提供的两件事:使用两个或三个操作数执行加法的能力,以及将结果存储在任何寄存器中的能力;而不仅仅是源操作数之一。

执法机关不改变旗帜。

示例

LEA EAX,[EAX+EBX+1234567]计算EAX+EBX+134567(即三个操作数)LEA EAX,[EBX+ECX]计算EBX+ECX,而不使用结果覆盖两者。乘以常数(乘以2、3、5或9),如果你像LEA EAX那样使用,[EBX+N*EBX](N可以是1,2,4,8)。

其他用例在循环中很方便:LEA EAX、[EAX+1]和INC EAX之间的区别在于后者更改EFLAGS,但前者不更改;这保持了CMP状态。

LEA:只是一个“算术”指令。。

MOV在操作数之间传输数据,但lea只是在计算

如果有人已经提到了,请原谅我,但如果有人想知道x86糟糕的旧时代,内存分割仍然是相关的:您将始终从以下两条指令中得到相同的结果:

LEA AX, DS:[0x1234]

and

LEA AX, CS:[0x1234]

“有效地址”只是seg:off逻辑地址的偏移部分。在本例中,0x1234。

LEA不添加段基础。这将击败最初的一个用例,即进行地址计算以获得指针(偏移量),实际上可以取消引用。例如lea bx,[array+si]。如果添加了DS基以给出线性地址,则稍后的mov ax,[bx]将再次添加DS基。此外,20位结果通常不适合16位寄存器。

看见https://www.stevemorse.org/8086/index.html8086的建筑师写了一本关于指令集的书,现在在他的网站上免费。关于LEA的部分提到了他的一些设计意图。