4.3.1 传送指令
传送类指令的功能是把数据、地址传送到寄存器或存储单元中。传送指令可分为一般数据传送、交换传送、堆栈传送、地址传送和标志传送。
传送类指令总体分类情况如图4.12所示。
图4.12 传送类指令分类
1.一般传送指令
MOV:本指令将源操作数(字节或字)传送到目的操作数中,源操作数内容不变,目的操作数内容与源操作数内容相同。
源操作数可以是累加器、寄存器、存储器操作数和立即数;而目的操作数可以是累加器、寄存器和存储器。注意,源操作数和目的操作数不能同时为存储器操作数,即数据不能通过一条指令从存储器某一单元直接送至另一个单元。
一般传送指令包括movb(字节传送)、movw(字传送)和movl(双字传送)等。
例如:
2.交换传送
XCHG 指令:
功能:将两个操作数互换。例如,XCHGB表示字节交换。
该指令中必须有一个操作数是在寄存器中。因此它可以在寄存器与寄存器之间交换数据,或寄存器与存储器单元之间交换数据。但不能与段寄存器交换数据,段寄存器之间也不能交换数据。存储器与存储器单元之间也不能交换数据。
例如:xchgw%bx,%ax
若在指令执行前,(AX)=780AH,(BX)=0BA98 H,则指令执行后,(AX)=0BA98 H,(BX)=780AH。
3.堆栈传送指令
堆栈是一段特殊组织的存储区域,即在普通随机访问存储器RAM 中,规定一段存储区域,这段存储区域对存储器单元进行操作时,其存取数据的顺序不是任意的,而是按“先进后出(First In Last Out)”原则进行存取。后存入的数据必须先取出,先存入的数据必须后取出。就像堆放的货栈,先放入的东西被压在下面,只能将后放入的东西取走才能将其取出。
从8086CPU 的堆栈形式来看,堆栈是从高地址向低地址方向增长的,堆栈只有一个出入口,所以要设置一个堆栈指针寄存器SP,始终指向堆栈栈顶单元。堆栈的操作有入栈和出栈两种,相应有入栈(PUSH)和出栈(POP)两种指令,最初时堆栈的栈底和栈顶重叠在同一个单元,随着堆栈操作的进行,栈底的位置保持不变,而栈顶的位置却在不断变化。入栈操作时,栈顶向低地址方向变化,而出栈时栈顶向高地址方向变化。堆栈组织示意,如图4.13所示。
图4.13 堆栈示意
堆栈传送指令有两条:PUSH(进栈)和POP(出栈)。堆栈操作的基本方法是先进后出和后进先出。
(1)入栈指令PUSH
将寄存器或存储器单元的内容送入堆栈。
除了不允许用立即数外,通用寄存器、段寄存器和存储器操作数都能入栈。如PUSHL表示双字压栈,PUSHW 表示字压栈。
PUSHW 的具体的操作过程是:SP内容首先减1,操作数的高位字节送入当前SP所指示的单元中,然后SP中的内容再减1,操作数的低位字节又送入当前SP所指示的单元中。
例如:pushw%ax
若在指令执行前,(SP)=00F8 H,(SS)=2500H,(AX)=3142 H,则指令执行后(SP)=00F6 H,(250F6)=3142 H。
(2)POP指令
将栈顶元素传送到寄存器或存储单元中。
其中出栈操作的目的地址,长度必须为16位,除了立即数和CS段寄存器之外,通用寄存器、段寄存器和存储器都可以作为出栈的目的地址。如POPL 表示双字出栈,POPW 表示字出栈。
POPW 的具体操作过程是:首先将SP所指的栈顶单元内容送入目的地址低位字节单元,SP的内容加1,然后将SP 所指栈顶单元内容送入目的的高位字节单元,SP 的内容再加1。
例如:popw%bx
若在指令执行前(SS)=2000H,(SP)=0200H,(BX)=58C2H,(20100H)=4B48H,则指令执行后(BX)=4B48 H,(SP)=0202 H。
注意,除了段寄存器CS以外,通用寄存器和段寄存器都可作为目的操作数。
例如:利用堆栈交换AX 与BX 寄存器中的数值。
4.地址传送
地址传送有3条指令:LEA(送有效地址)、LDS(置有效地址及DS段地址)和LES(置有效地址及ES段地址)。
LEA 指令的功能:将源存储器操作数的偏移地址送给目的操作数指定的16位通用寄存器。
例如:
leaw $table,%bx;BX 指向table,即table的偏移地址送BX
leaw(%bp),%di;(DI)=BP
5.标志传送
标志寄存器传送指令共有4条,这些指令都是单字节指令,指令的操作数以隐含形式规定,字节操作数隐含为AH 寄存器。这四条指令分别是:LAHF(FLAG 寄存器低8 位送AH)、SAHF(AH 送FLAG 寄存器低8位)、PUSHF(FLAG 寄存器进栈)和POPF(出栈给FLAG 寄存器)。
(1)取标志指令LAHF和置标志指令SAHF
LAHF指令将标志寄存器FLAG 中的五个状态标志位SF、ZF、AF、PF 以及CF 分别取出传送到累加器AH 的对应位,SAHF指令的传送方向与LAHF方向相反,将AH 寄存器中的第7、6、4、2、0位分别传送到标志寄存器对应位,如图4.14所示。
图4.14 LAHF(左)和SAHF(右)的功能
SAHF指令将影响标志位,FLAG 寄存器中的SF、ZF、AF、PF 和CF 将被修改成AH寄存器中对应的值,但其他状态位即OF、DF、IF和TF不受影响。
例如:设置SF=1,ZF=0,AF=0,PF=1,CF=0。
分析:要置5个状态标志位可用SAHF 指令,选对应位填充一个立即数送AH,再用SAHF实现对AH 送FLAG 的低8位。
(2)PUSHF、POPF
用于标志位的保存和恢复,PUSHF用于保存所有标志位到栈中;POPF 用于从栈中恢复所有标志位。
例如:设置OF=1,DF=0,IF=1,TF=0,SF=1,ZF=0,AF=0,PF=1,CF=0。
分析:要置9个状态标志位可用POPF指令,先按对应位填充一个立即数送AX,再将AX 进栈,而后再用POPF实现将栈顶元素出栈送FLAG。