lea指令
load effective address, 加载有效地址,可以将有效地址传送到指定的的寄存器。指令形式是从存储器读数据到寄存器, 效果是将存储器的有效地址写入到目的操作数, 简单说, 就是C语言中的”&”.
mov指令
在CPU内或CPU和存储器之间传送字或字节,它传送的信息可以从寄存器到寄存器,立即数到寄存器,立即数到存储单元,从存储单元到寄存器,从寄存器到存储单元,从寄存器或存储单元到除CS外的段寄存器(注意立即数不能直接送段寄存器),从段寄存器到寄存器或存储单元。
但是注意
(1) MOV指令中的源操作数绝对不能是立即数和代码段CS寄存器;
(2) MOV指令中绝对不允许在两个存储单元之间直接传送数据;
(3) MOV指令中绝对不允许在两个段寄存器之间直接传送数据;
(4) MOV指令不会影响标志位
使用[]区别
第二操作数加不加中括号[]的区别就是:
lea对变量没有影响是取地址,对寄存器来说加[]时取值,第二操作数不加[]非法
mov对变量来说没有影响是取值,对寄存器来说是加[]时取地址,第二操作数不加[]是取值
lea指令load effective address, 加载有效地址,可以将有效地址传送到指定的的寄存器。指令形式是从存储器读数据到寄存器, 效果是将存储器的有效地址写入到目的操作数, 简单说, 就是C语言中的”&”.mov指令在CPU内或CPU和存储器之间传送字或字节,它传送的信息可以从寄存器到寄存器,立即数到寄存器,立即数到存储单元,从存储单元到寄存器,从寄存器到存储单元,从寄存器或存储单元到
LEA
是微机8086/8088系列的一条
指令
,取自英语Load effect address——取有效地址,也就是取偏移地址。在微机8086/8088中有20位物理地址,由16位段基址向左偏移4位再与偏移地址之和得到。
取偏移地址
指令
指令
格式如下:
LEA
reg16,mem
LEA
指令
将存储器操作数mem的4位16进制偏移地址送到指定的寄存器。这里,源
LEA
指令
要求源操作数必须是存储单元,而且目的操作数必须是一个除段寄存器之外的16位或32位寄存器。当目的操作数是16位通用寄存器时,那么只装入有效地址的低16位。使用时要注意它与
MOV
指令
的区别,
MOV
指令
传送的一般是源操作数中的内容而不是地址。
例1 假设:SI=1000H , DS=5000H, (51000H)=1234H
执行
指令
LEA
BX , [SI]后,BX=1000H
执行...
LEA
指令
的功能是将源操作数、即存储单元的有效地址(偏移地址)传送到目的操作数。
示例
LEA
BX,[BX+SI+0F54H]
指令
中,[BX+SI+0F54H]采用相对基址变址的寻址方式表达存储单元,它表示的存储单元的有效地址是:BX内容加SI内容加0F54H。这个结果被传送到BX中。
intel 开发手册上的官方描述:
lea
r16,m Store Effective Address for m in register r16;
LEA
是微机8086/8088系列的一条
指令
,取自英语Load effect address——取有效地址,也就是取偏移地址。在微机8086/8088中有20位物理地址,由16位段基址向左偏移4位再与偏移地址之和得到。
取偏移地址
指令
指令
格式如下:
LEA
reg16, mem
lea
reg16, m...
首先
lea
指令
是
mov
指令
的变种,据说,
lea
指令
是x86体系结构中,是一条最古老但是从某个方面来讲又是最神奇的
指令
。
表面上看,它做的事情非常简单,根据括号里的源操作数来计算地址,然后把地址加载到目标寄存器中。
例如:
lea
q a(b, c, d), %rax 先计算地址a + b + c * d,然后把最终地址载到寄存器rax中。
刚开始学
汇编
都会接触到
指令
lea
和
mov
,但是这两个
指令
用法看起来很像,会经常误以为两者其实没有很大区别,甚至会误认为两者就是相等的,笔者本人也是很迷,而且书上对
lea
的讲解又十分有限,但是通过不懈的知识搜素,终于搞明白了这其中的差别,两者还是又很大不同的。
让我们一起看看下面的例子:
大家可以看到,第三行和第四行,看到右边的注释大家是不是有点明白了呢,
lea
代表的就是加载有效地址(load effective address),而(%rsi , %rdi , 4)代表的是以数值 %rsi + %r
加载有效地址(load effective address)
指令
就是
lea
,他的
指令
形式就是从内存读取数据到寄存器,但是实际上他没有引用内存,而是将有效地址写入到目的的操作数,就像是C语言地址操作符&一样的功能,可以获取数据的地址。在实际使用中他有两种使用方式。
1.
lea
指令
获取偏移地址
assume cs:code
code segment
start:
mov
byte pt...
lea
ebx,[eax];执行后ebx=2
mov
ebx,eax;等同于上句
lea
ebx,eax;编译器报错: error A2070: invalid instruction operands
对于变量来说加不加[]都是一样的效果,都是取变量的地址,相当于指针
num dword 2
lea
ebx,num
lea
eax,[num]; eax为
offset在
汇编
时就获得了变量的偏移地址,执行起来很快;
LEA
指令
是在执行过程中获得地址,当无法在
汇编
阶段获得地址时,就用
LEA
指令
。
LEA
指令
实现运算功能
用
汇编
指令
表达“笑死我了”可能比较困难,因为
汇编
语言主要用于编写底层系统代码,如操作系统和驱动程序等,而不是用于表达情感或语言。
但是,我们可以编写一些
汇编
指令
来打印“笑死我了”的文本消息。下面是一些可能的实现方式,假设我们使用的是 x86
汇编
语言:
section .data
message db '笑死我了', 0
section .text
global _start
_start:
; 将系统调用号 4 存储在 EAX 寄存器中,表示打印字符串
mov
eax, 4
; 将文件描述符 1 存储在 EBX 寄存器中,表示标准输出
mov
ebx, 1
; 将 message 变量的地址存储在 ECX 寄存器中
lea
ecx, [message]
; 将 message 变量的长度存储在 EDX 寄存器中
mov
edx, 12
; 执行系统调用,将消息打印到标准输出
int 0x80
; 退出程序
mov
eax, 1
xor ebx, ebx
int 0x80
上述代码使用 Linux 中的系统调用来打印字符串。首先,它在数据段中定义了一个 message 变量,并将“笑死我了”字符串存储在其中。然后,在代码段中,它将系统调用号 4 存储在 EAX 寄存器中,表示打印字符串,将文件描述符 1 存储在 EBX 寄存器中,表示标准输出,将 message 变量的地址存储在 ECX 寄存器中,将 message 变量的长度存储在 EDX 寄存器中,最后执行系统调用以将消息打印到标准输出。最后,它使用系统调用号 1 退出程序。