首页
学习
活动
专区
圈层
工具
发布

X86 Assemble指令--LEA

LEA指令描述

Opcode

Mnemonic

Description

8D /r

LEA r16,m

Store effective address for m in register r16

8D /r

LEA r32,m

Store effective address for m in register r32

LEA指令

LEA指令用来计算第二个操作数(源操作数)的有效地址,并且将该地址保存到第一个操作数(目的操作数)中。源操作数是CPU寻址模式中的内存寻址模式(支持偏移量)。而目标操作数是一个通用寄存器(GPR,general-purpose register)。这条指令被地址大小和操作数大小属性所影响,如上表所示。指令的操作数大小决定于使用的寄存器,而地址大小决定于代码段。

作用

LEA:Load Effective Address。加载有效地址。将源操作数的地址加载到目的寄存器中。注意:不是实际地址

如LEA EAX, [ EBX + ECX ],它相当于计算EBX和ECX的值,将这个值保存到EAX寄存器中。原因:由于EBX+ECX计算出来的值是该内存地址,而通过[EBX+ECX]得到的是内存地址保存的值,而LEA命令是加载该值的有效地址并且保存到目标寄存器中,也就是将EBX+ECX的值保存到EAX寄存器中 由于加载的是有效地址,而不是实际地址,所以EAX中保存的是EBX+ECX,而不是ds:EBX+ECX

实例

  1. 计算多个数据的运算 一般要计算多个数据相加,例如,将1+2+EBX的值放入EAX寄存器中,ADD需要三条指令
代码语言:javascript
复制
ADD EAX,1;
ADD EAX,2;
ADD EAX,EBX;

而使用LEA的话,只需要一条指令

代码语言:javascript
复制
LEA EAX,[1+2+EBX];
  1. 计算地址指针 例如现在有一个struct为Point,其中int占32位,4个byte。所以其中xcoord的偏移量为0,而ycoord的偏移量为4,整个struct大小为8byte。
代码语言:javascript
复制
struct Point
{
     int xcoord;
     int ycoord;
};

假如现在有一条语句为:

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

其中points是一个Point结构体的数组。而该数组的基址已经保存到了EBX寄存器中,而i的值保存在了EAX寄存器中。所以该条语句的汇编指令为:

代码语言:javascript
复制
MOV EDX [EBX+8*EAX+4];

由于数组基址在EBX寄存器中,并且每一个Point元素都占8个字节,而i保存在EAX寄存器中,所以EBX+8EAX得到的就是points[i]的基址,而ycoord的偏移量为4,所以EBX+8EAX+4得到的就是points[i].ycoord

y的值保存到了EDX寄存器中,并且EBX+8EAX+4的值为有效地址(effective address)。

而在C中有指针这一说,例如:

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

这时候就需要LEA指令了。

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

结果就将数组第i个数据结构的ycoord的地址保存在ESI寄存器中,也就是p中。

参考资料

What's the purpose of the LEA instruction? Load Effective Address

举报
领券