首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >LEA指令的目的是什么?

LEA指令的目的是什么?
EN

Stack Overflow用户
提问于 2009-11-01 20:57:27
回答 17查看 805.4K关注 0票数 828

对我来说,这就像个古怪的MOV。它的目的是什么,我应该什么时候使用它?

EN

回答 17

Stack Overflow用户

发布于 2009-11-03 06:25:00

正如其他人指出的那样,LEA (load有效地址)经常被用作进行某些计算的“技巧”,但这并不是它的主要目的。x86指令集旨在支持Pascal和C等高级语言,其中数组--特别是ints或小型结构的数组--是常见的。例如,考虑表示(x,y)坐标的结构:

代码语言:javascript
运行
复制
struct Point
{
     int xcoord;
     int ycoord;
};

现在想象一下这样的语句:

代码语言:javascript
运行
复制
int y = points[i].ycoord;

其中points[]Point的数组。假设数组的基已经在EBX中,变量iEAX中,而xcoordycoord分别为32位(因此ycoord在结构中偏移了4个字节),则可以将该语句编译为:

代码语言:javascript
运行
复制
MOV EDX, [EBX + 8*EAX + 4]    ; right side is "effective address"

这将使yEDX登陆。8的比例因子是因为每个Point的大小是8个字节。现在,考虑与“地址”操作符使用的相同表达式&:

代码语言:javascript
运行
复制
int *p = &points[i].ycoord;

在这种情况下,您不需要ycoord的值,而是它的地址。这就是加载有效地址(load effective )出现的地方。编译器可以生成MOV,而不是

代码语言:javascript
运行
复制
LEA ESI, [EBX + 8*EAX + 4]

它将在ESI中加载地址。

票数 951
EN

Stack Overflow用户

发布于 2009-11-01 21:03:38

来自阿布拉什的“集会的禅宗”:

LEA是执行内存寻址计算但实际上不寻址内存的唯一指令。LEA接受标准内存寻址操作数,但只会将计算出的内存偏移量存储在指定的寄存器中,这可能是任何通用寄存器。

那能给我们什么?ADD没有提供两件事:

  1. 可以对两个或三个操作数执行加法,
  2. 可以将结果存储在任何寄存器中;而不仅仅是源操作数之一。

LEA不改变标志。

示例

  • LEA EAX, [ EAX + EBX + 1234567 ]计算EAX + EBX + 1234567 (这是三个operands)
  • LEA EAX, [ EBX + ECX ]计算EBX + ECX,而不用常量覆盖result.
  • multiplication (乘以2、3、5或9),如果您像LEA EAX, [ EBX + N * EBX ]一样使用它(N可以是1、2、4、8)。

循环中的其他usecase很方便:LEA EAX, [ EAX + 1 ]INC EAX的区别是后者改变了EFLAGS,但是前者没有;这保留了CMP状态。

票数 622
EN

Stack Overflow用户

发布于 2012-10-09 17:35:41

LEA指令的另一个重要特性是它不改变条件代码(如CFZF ),而使用算术指令(如ADDMUL )计算地址。此特性降低了指令之间的依赖级别,从而为编译器或硬件调度程序进一步优化提供了空间。

票数 128
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1658294

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档