关于len指令汇总

需要正确理解LEA指令的功能。 
该指令有两个操作数。左边是目的操作数,表示操作结果保存在此,该指令目的操作数只能是8个通用寄存器之一。逗号右边的是源操作数,该指令的源操作数只能是一个存储单元,表达存储单元有多种寻址方式。 
LEA指令的功能是将源操作数、即存储单元的有效地址(偏移地址)传送到目的操作数。 
示例指令中,[BX+SI+0F54H]采用相对基址变址的寻址方式表达存储单元,它表示的存储单元的有效地址是:BX内容加SI内容加0F54H。这个结果被传送到BX中。 
是否是很烦琐? 
该指令涉及了多个基本知识点,尤其是存储器寻址方式。问题很有可能是前面的内容并没有真正理解和掌握。 
这是汇编语言程序设计课程的一个特点,知识点点滴滴,需要静心学习。

--------------------------------------------

这个指令一般用于加法或者乘法的优化,以获得更高的运行效率

这个指令是用来取EA地址的,一般情况是可以和MOV AX,OFFSET BUFFER等效,但是还是有区别的:1,运行一条LEA大约是100条OFFSET指令的时间,2,OFFSET不可以用于相对基址变址这样的复杂寻址方式

offset属伪指令范畴,是在汇编时处理的,对地址不变的变量可以取其有效地址。如楼上的“MOV DX,OFFSET A” 

但是,如果地址是变量(也就是指针),其有效地址是随程序运行而变化的,offset是肯定无法取其有效地址的。因为“伪指令”不可能在程序运行时起作用。例如,“MOV DX,OFFSET 1234[SI+BX]”肯定是不行的。 

LEA是指令,可以在地址是变量(也就是指针)的情况下,取其有效地址。 
例如,“LEA DX,1234[SI+BX]”肯定是可以的。因此,它从来就不是多余的。

------------------------------------------

堆栈种分配的局部变量所谓的“标号”,你以为是什么?(都是那些该死的宏惹的祸,大家要都是老老实实写代码,就不会有这些疑问了)。 
比如你用local在栈上定义了一个局部变量LocalVar,你知道实际的指令是什么么?一般都差不多像下面的样子: 
push   ebp 
mov   esp,   ebp 
sub   esp,   4 
现在栈上就有了4各字节的空间,这就是你的局部变量。 
接下来,你执行mov   LocalVar,   4,那么实际的指令又是什么?是这样: 
mov   dword   ptr   [ebp-4],   4 
于是,这个局部变量的“地址”就是ebp-4——显然,它不是一个固定的地址。现在需要将它的“地址”作为参数传给某个函数,你这样写: 
invoke/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]

你可能感兴趣的:(汇编)