lea
指令("加载有效地址")获取第一个值的内存地址,并将其加到第二个值 - 可以乘以。然后它将该存储器地址加载到给定的寄存器中。
让我举一个例子来澄清我的困惑:
eax = 2
leal (%eax, %eax, 4), %edx
我相信这样做的结果是edx
内部会有值10
(2 + 2 * 4 == 10
)。但是为什么这个内存地址指令只是对整数进行算术运算?
我已阅读其他回复,但他们都谈到内存地址是唯一涉及的内容。有人可以帮我理解leal
正在做什么吗?
答案 0 :(得分:3)
LEA工作原理的原因是因为在原始的8086上,LEA指令重用了处理器的有效地址计算硬件。有效地址硬件计算指令的存储器操作数所作用的地址。由于需要执行许多不同的基本操作来计算有效地址,这意味着相对而言,LEA
指令中存在大量功率。大多数“实际”算术指令一次只执行一个操作,并且大多数要求目标寄存器是源操作数之一。由于它可以实现少量的额外编码空间和硅片面积,考虑到它的功能,它非常便宜。
所以像MOV AX,[BX + SI]
这样的指令(我在这里使用英特尔语法)加载AX
,其中16位值存储在通过添加BX
和{{1}计算的地址处}。指令SI
加载LEA AX,[BX + SI]
,其中包含通过添加AX
和BX
计算的地址。换句话说,LEA指令以不同于其他指令的方式处理存储器操作数。而是在存储器操作数指示的地址处对存储器进行操作,它将计算出的地址直接用作操作数。两条指令使用相同的地址编码,LEA指令只调整内存操作数的解释方式。
换句话说,LEA被称为,因为它正是它所做的。它将内存操作数给出的有效地址加载到目标寄存器中。由于内存操作数实际上并未用作内存操作数,因此它实际上像普通的算术指令一样工作。如果ADD是加法算术指令,则LEA是有效地址算术指令。
答案 1 :(得分:2)
它的命名就是为了它的目的。
大多数指令包含相同的寻址模式。 CPU架构师调用确定寻址模式选择的存储器地址的工作为"计算有效地址"。
指令的目的是将有效地址放入寄存器。因此,"加载有效地址"。
是的,这是真的"它只是执行算术"。如果您考虑一下,几乎所有CPU都会这样做,因此该短语并不能描述任何特定的指令或CPU活动。
如果你想了解有多少指令得到它们的名字(更不用说指令的目的是什么),最好选择一个计算机架构类。
[长时间评论互动后修改]:
这里的大部分答案(包括我的)都挂在"计算有效地址",其中指令用于形成存储器地址,其中指令具有当之无愧的名称。
但是,由于指令实际上没有使用计算出的"地址" LEA指令的极其常见的用法就是简单地执行算法。实际上,从这个角度来看,LEA是计算总和或具有一些特殊小常数的产品的组合,并将结果存储到另一个寄存器而不影响条件位。与进行实际乘法相比,它也很快就能做到这一点。这在实际程序中的效用令人惊讶地高;获得一些在x86上编写汇编代码的经验,你会相信这一点。
因此,例如,可以使用LEA将寄存器乘以5并添加一个大常量。这里的指令名称只会混淆;不幸的是,仍然必须有一个名字。
欢迎来到汇编代码土地,设计师发明指令以达到一个目的,编码员发现他们可以使用指令来计算设计师没有明显考虑的事情。 [AND-immediate指令非常方便计算模拟一些二次幂,作为另一个例子]。因此,理性指令集中的每个指令都由指令架构师放在那里,因为它有一些有用的用途。当编码器发现聪明的应用程序时,它可以用于其他事情。
答案 2 :(得分:0)
为什么lea
在其名称中引用有效地址的概念的简单答案是意图用于计算有效地址。名称和意图经常在一起(虽然我希望他们更频繁地做 - 在这个领域中有无数不必要的模糊术语的例子。)
也许人们经常理解lea的目的的问题更多地与术语“负载”有关。 “加载”表示执行了内存操作,但事实并非如此。这更容易让人感到困惑,因为有效地址和内存之间存在概念关联。最后,lea
的内存操作数的语法是操作数的语法,在其他指令中表示实际的加载。鉴于这一点,对lea
是否产生内存访问的一些初步混淆是可以理解的。
也许更好的助记符是cea
,'计算有效地址'。哦,好吧。