汇编lea 指令与 mov 指令
(2013-04-07 10:53:39)
标签:
汇编语言leamov |
分类: 学习笔记 |
该指令有两个操作数。左边是目的操作数,表示操作结果保存在此,该指令目的操作数只能是8个通用寄存器之一。逗号右边的是源操作数,该指令的源操作数只能是一个存储单元,表达存储单元有多种寻址方式。
LEA指令的功能是将源操作数、即存储单元的有效地址(偏移地址)传送到目的操作数。
示例LEABX,[BX+SI+0F54H]指令中,[BX+SI+0F54H]采用相对基址变址的寻址方式表达存储单元,它表示的存储单元的有效地址是:BX内容加SI内容加0F54H。这个结果被传送到BX中。
LEA是INTEL颇为得意的一条指令(虽然大多数程序员并不以为然)。在INTELOPTIMIZATION REFERFENCE MANUAL中,特别提到了这条指令的好处。
0.LEA指令具有单时钟周期,执行效率很高。
1.它是CPU地址生成单元参与运算的,而不是ALU参与运算的,所以在流水线上不会与上下文的算术逻辑指令产生流水相关
2.INTEL指令集中不存在很多RISC机器所具有的三操作数算术运算指令,比如像ARM的"addr0,r1,r2",而LEA指令恰好提供了同样的功能,以模拟“三元算术逻辑指令”。
举个例子,要计算两个寄存器的和,但又不想破坏原来的值,那么可以执行lea ebx ,[eax+edx], 这条指令,执行的就是 ebx = eax + edx 这条加法运算。如果用add指令,则不可能一条指令内完成。
3.在汇编语言程序设计中,在需要取得一个变量地址时,使用LEA是很方便的。而MOV指令则常常出错,因为在微软MASM汇编语法中,label和variable是不同的
看下面关于lea指令与mov指令的一些简单用法:
比如你用local在栈上定义了一个局部变量LocalVar,你知道实际的指令是什么么?一般都差不多像下面的样子:
push ebp
mov esp,
ebp
sub esp, 4
现在栈上就有了4各字节的空间,这就是你的局部变量。
接下来,你执行mov LocalVar,
4,那么实际的指令又是什么?是这样:
mov dword ptr
[ebp-4], 4
于是,这个局部变量的“地址”就是ebp-4——显然,它不是一个固定的地址。现在需要将它的“地址”作为参数传给某个函数,你这样写:
call SomeFunc,
addr LocalVar
实际生成的指令是:
lea eax,
[ebp-4]
push eax
call SomeFunc
当然,你也可以写成:
mov eax,
ebp
sub eax, 4
push eax
call SomeFunc
看到了,这里多了一条指令。这就是lea的好处。于是,lea又多了一个非常美妙的用途:作简单的算术计算,特别是有了32位指令的增强寻址方式,更是“如虎添翼”:
比如你要算EAX*4+EBX+3,结果放入EDX,怎么办?
mov edx,
eax
shl edx, 2
add edx,
ebx
add edx, 3
现在用lea一条指令搞定:
lea edx,
[ebx+eax*4+3]
lea的英文解释是: Load Effective
Address.(加入有效地址,开始迷惑效地址是什么???既然是有效地址与mov ax , [address]
又有什么不同呢?其实他们都是等效的。
后来知道实际上是一个偏移量可以是立即数,也可以是经过四则运算的结果,更省空间,更有效率)
当源操作数很简单的情况下,完全可以用mov指令代替lea指令,如lea esi,Buffer,完全可以用指令mov esi,offset Buffer代替;但当源操作数稍微复杂一点的话,单用mov指令就代替不了了,至少要用到算术运算指令。指令集中提供lea指令,就是为了减少这些计算 上的麻烦.
LEA指令的功能是将源操作数、即存储单元的有效地址(偏移地址)传送到目的操作数。
示例LEA
LEA是INTEL颇为得意的一条指令(虽然大多数程序员并不以为然)。在INTEL
0.LEA指令具有单时钟周期,执行效率很高。
1.它是CPU地址生成单元参与运算的,而不是ALU参与运算的,所以在流水线上不会与上下文的算术逻辑指令产生流水相关
2.INTEL指令集中不存在很多RISC机器所具有的三操作数算术运算指令,比如像ARM的"add
3.在汇编语言程序设计中,在需要取得一个变量地址时,使用LEA是很方便的。而MOV指令则常常出错,因为在微软MASM汇编语法中,label和variable是不同的
看下面关于lea指令与mov指令的一些简单用法:
比如你用local在栈上定义了一个局部变量LocalVar,你知道实际的指令是什么么?一般都差不多像下面的样子:
现在栈上就有了4各字节的空间,这就是你的局部变量。
接下来,你执行mov
mov
于是,这个局部变量的“地址”就是ebp-4——显然,它不是一个固定的地址。现在需要将它的“地址”作为参数传给某个函数,你这样写:
lea的英文解释是:
当源操作数很简单的情况下,完全可以用mov指令代替lea指令,如lea esi,Buffer,完全可以用指令mov esi,offset Buffer代替;但当源操作数稍微复杂一点的话,单用mov指令就代替不了了,至少要用到算术运算指令。指令集中提供lea指令,就是为了减少这些计算 上的麻烦.