传送指令:Mov/lea/push/pop
传送指令主要用于将数据进行拷贝赋值等操作。它包括mov,lea,push,pop等指令。现在逐一对它们进行介绍:
MOV指令
指令格式:MOV DST,SRC
指令形式:MOV Reg/Mem, Reg/Mem/Imm
其中:Reg即Register(寄存器),Mem即Memory(存储器),Imm即Immediate(立即数) ,表示指令在第一个操作数可以是寄存器、内存,第二个操作数可以是寄存器、内存和立即数。
Mov指令例子:
Mov eax,5
Mov ds,eax
Mov ds, 5;
上面的代码是错误的,不能直接对段寄存器使用mov 立即数或者内存指令。需要先放入通用寄存器中。所以上面的代码应该改为:
Mov eax,5
Mov ds,eax
MOV EAX,DWORD PTR SS:[EBP
上面的指令将把ebp
类似于C中下面2句代码:
DWORD *p=EBP
eax<=*p
[ ]在汇编中用于获取一个内存地址所指向的内存,以便取得其中的值或者向其赋值。
MOV DWORD PTR DS:[ESI+
上面的代码将把eax中的值赋值到ESI+
DWORD *p=ESI+
*p<=eax
观察下面的代码:
mov ax, word ptr value
mov eax, dword ptr value
mov al,byte ptr value
这里的word ptr/dword ptr/byte ptr实际上是指定地址value的宽度(分别对应2字节,4字节和1个字节,以便按照宽度来取值。
PUSH/POP指令:
指令格式:push reg/mem/seg/imm;
该指令将会把reg/mem/seg/imm中的值入栈,放入栈顶ss:[sp](sp为栈顶指针寄存器)。然后将sp减去步长(入栈数据的长度)上抬。
ss:[sp]<=reg/mem/seg/imm;sp<=sp-len(2个字节或4个字节)
指令格式:pop reg/seg/mem
该指令将会把栈顶的数据放入reg/mem/seg里,然后将sp加上步长。reg/seg/mem<=ss:[sp],sp<=sp+len(2个字节或4个字节)
指令例子:
Push eax;
Push 5;
pop eax
PUSH [2000H]
PUSH CS
POP [2000H]
POP SS
LEA:load effective address
LEA指令是取偏移地址,MOV指令是取数据。这是两个容易混淆的指令,现举例说明。参见下面2条指令:
mov eax,[400000H]//将内存单元400000H中的数据放入eax中,[ ]类似与C语言中的*运算符
lea eax,[400000H]//直接将偏移地址400000H放入eax中,等价于:mov eax,40000H
又比如:
Mov ebx,[eax]//eax中存放的是内存地址,将该内存地址指向的内存数据放入ebx中
Lea ebx,[eax]//将eax直接放入ebx中,等价于mov ebx,eax
Lea ebx,TABLE//将TABLE的偏移地址放入ebx中,等价于mov ebx, offset table
LEA EAX,[EBX+ECX*2+1]//将ebx+ecx*2+1的值放入eax寄存器中
但不能写成:
Mov eax, ebx+ecx*2 +1// 不能这样写,mov指令不支持这种格式
lea eax,[ebx+edx+1]//将ebx+edx+1值放入eax
Mov eax, ebx+edx+1//不能这样写,mov指令不支持这种格式,如果要使用mov来实现,则需要使用3条指令来实现:
mov eax,ebx
add eax,edx
add eax,1
上面3条指令明显不如lea一条指令简洁。
LAHF(Load AH with flags):flags寄存器低8位送AH
用于将标志寄存器的低八位送入AH,即将标志寄存器FLAGS中的SF、ZF、AF、PF、CF五个标志位分别传送到累加器AH的对应位(八位中有三位是无效的)
SAHF(store AH into flags) AH送标志寄存器
PUSHF(push the flags) 标志寄存器进栈 ,等同于:push eflags
POPF(pop the flags) 标志寄存器出栈,等同于:pop eflags