(2)立即数送至通用寄存器或存储单元。 例如:MOV AL,3 MOV SI,-5
MOV VARB,-1 ;VARB是变量名,代表一个存储单元 MOV VARW,3456H ;VARW是一个字变量 MOV [SI],6543H
注意:立即数不能直接传送到段寄存器。立即数永远不能作为目的操作。 (3)寄存器与存储器间的数据传送。
例如:MOV AX,VARW ;VARW是一个字变量,存储器操作为直接寻址。MOV AX,[0123] MOV BH,[DI] ;存储器操作数位寄存器间接寻址
MOV DI,ES:[SI+3] ;存储器操作数为相对变址寻址,使用段超越前缀 MOV VARB,DL ;VARB是一个字节变量 MOV DS:[BP],DL ;使用段超越前缀 MOV VARW,DS ;VARW是一个字变量 MOV ES,VARW
注意:源操作数和目的操作数类型要一致。即同时为字节或字,不能一个字节,另一个是字。除了串操作指令外,源操作数和目的操作数不能同时是存储器操作数。两个操作数必须有一个寄存器(立即寻除外)。
例如:把字变量VARW1的内容送到字变量VARW2 MOV AX,VARW1 MOV VARW2,AX
这种利用通用寄存器过度的方法,也适用于段寄存器间的数据传送。 例如:MOV AX,CS
MOV DS,AX ;把CS的内容送到DS MOV AL,'D'
立即数(字符D的ASCII码44H)送到AL寄存器。 MOV BX,OFFSET TABLE
把TABLE的偏移地址(不是内容)送到BX寄存器,其中OFFSET为属性操作符。 例如:BX=1234H BP=5678H要交换两个寄存器的内容。用MOV指令如下: MOV AX,BX MOV BX,BP MOV BP,AX
利用交换指令可方便地实现通用寄存器与通用寄存器或存储单元间的数据交换。
2.交换指令
格式:XCHG OPRD1,OPRD2
此指令把操作数OPRD1的内容与操作数OPRD2的内容交换。操作数同时是字节或字。
例如:XCHG AL,AH XCHG SL,BX
OPRD1和OPRD2可以是通用寄存器和存储单元。但不包括段寄存器,也不能同时是存储单元,还不能有立即数,可采用各种存
储器寻址方式来制定存储单元。
例如:XCHG BX,[BP+SI] 如指令执行前:
(BX)=6F30H, (BP)=0200H, (SI)=0046H, (SS)=2F00H, (2F246)=4154H 物理地址=SS*16+BP+SI=2F000+0200+0046=2F246H 指令执行后:(BX)=4154H (2F246H)=6F30H 注意:使用BP的时候,段地址是SS堆栈段。 3.地址传送指令
(1)指令LEA (传送偏移地址)(Load Effective Address) 格式:LEA REG,OPRD
指令LEA称为传送有效地址指令。该指令把操作数OPRD的有效地址传送到操作数REG。操作数OPRD必须是一个存储器操作数,操作数REG必须是一个16位的通用寄存器。 例如:LEA AX,BUFFER ;BUFFER是变量名 LEA DS,[BS+S] LEA SI,[BP+DI+4] LEA BX,[BX+SI+0F62H]
如指令执行前(BX)=0400H,(SI)=003CH 指令执行后(BX)=0400+003C+0F62=139EH
(2)指令LDS(传送32位地址指针)(Load pointer into DS) 格式:LDS REG,OPRD
段值和段内偏移构成32位的地址指针。该指令传送32位地址指针。 执行的操作:(REG)←(SRC) (DS)←(SRC+2)
该指令把操作数OPRD中所含的一个32位地址指针的段值部分送到数据段寄存器DS,把偏移部分送到指令给出的通用寄存器REG。操作数OPRD必须是一个32位的存储器操作数,操作数REG可以是一个16位的通用寄存器,但实际使用的往往是变址寄存器或指针寄存器。 例如:LDS SI,POINTER ;POINTER是一个双字变量
假设双字变量POINTER 包含的32位地址指针的段值为5678H,偏移为1234H,那么在执行指令后:
(DS)=5678H ,(SI)=1234H
32位地址指针的偏移部分存储在双字变量的低地址字中,段值部分存储在高地址字中。 例如:LDS SI,[10H]
如指令执行前:(DS)=C000H, (C0010H)=0180, (C0012H)=2000H 指令执行后:(DS)=2000H, (SI)=0180H. SRC=DS*16+10H=C0000+10=C0010H SRC+2=C0010+2=C0012H (3)指令LES 格式:LES REG,OPRD
指令LES也传送32位地址指针,该指令把操作数OPRD中所含的32位地址指针的段值部分送到附加段寄存器ES,把偏移部分送
到指令给出的通用寄存器REG。
执行的操作:(REG)←(SRC) (ES)←(SRC+2) 例如:LES DI,[BX]
如指令执行前:(DS)=B000H (BX)=080AH (0B080AH)=05AEH (0B080CH)=4000H
指令执行后:(ES)=4000H (DI)=05AEH
例如:TABLE为数据段中0032单元的符号名,其中存放的内容为1234H,试问以下三条指令有什么区别?指令执行完后AX寄存器的内容是什么? MOV AX,TABLE (AX)=1234H LEA AX,TABLE (AX)=0032H MOV AX,OFFSET TABLE (AX)=0032H
例如:一个有16个字的数据区,它的起始地址为70A0:DDF6。请写出这个首末数据字单元的物理地址。
(首地址)=70A00+DDF6=7E7F6H
16个字=32个字节,是十进制,换算成16进制是20H。但是从首地址到末地址中间是30个字节也就是1E。
(末地址)=7E7F6+1E=7E814H 4.堆栈操作指令
在8086 8088系统中,堆栈是一段RAM区域。称为栈底的一端地址较大(高地址),称为栈顶的一端地址较小(低地址)。堆栈的段值在堆栈段寄存器SS中,堆栈指针寄存器SP始终指向栈顶。
堆栈是以“后进先出”方式工作的一个存储区。堆栈的存取必须以字为单位。堆栈操作指令分为两种:
(1)进栈指令PUSH 格式:PUSH SRC
执行的操作:(SP)←(SP)-2
该指令把源操作数SRC压入堆栈。它先把堆栈指针寄存器SP的值减2,然后把源操作数SRC送入由SP所指的栈顶。源操作数SRC可以是通用寄存器和段寄存器,也可以是字存储单元。 例如:PUSH AX (2)出栈指令POP 格式:POP DST
执行的操作:(SP)←(SP)+2
该指令从栈顶弹出一个字数据到目的操作数DST。它先把堆栈指针寄存器SP所指的字数据送至目的的操作数DST,然后SP值加2。
DST可以是通用寄存器和段寄存器(但CS例外),也可以是字存储单元。
注意:以上两条指令PUSH和POP只能做字操作。它们可以使用除立即数以外的其他寻址方式。但POP指令不允许用CS寄存器。
下面的程序段说明堆栈的一种用途,临时保存寄存器的内容,必要时再恢复其原始内容。 例如:PUSH AX ;保护AX PUSH BX
…… ;其间程序用到AX和BX寄存器 POP BX ;使DS得内容与CS的内容相同 POP AX ;恢复AX
例如:PUSH SI POP SI PUSH DS POP ES
PUSH VARW ;VARW是字变量 POP VARW ;VARW是字变量
PUSH [SI] POP [SI] 通过上面讲过的指令,数据交换有三种方式: 传送指令MOV 交换指令XCHG 堆栈指令PUSH POP
例如:将寄存器AX和SI的内容交换 用MOV指令,利用通用寄存器过度的方法
MOV BX,AX MOV AX,,SI MOV SI,BX 用交换指令XCHG XCHG AX,SI 用堆栈指令 PUSH AX PUSH SI POP AX POP SI 5.标志操作指令 (1)标志传送指令 ①指令LAHF 格式:LAHF
该条指令把标志寄存器的低8位(包括SF、ZF、AF、PF和CF)传送到寄存器AH的指定位。 ②指令SAHF 格式:SAHF
该条指令与LAHF刚好相反,把寄存器AH的指定位送至标志寄存器低8位的SF、ZF、AF、PE和CF标志位。
FLAG:0位是CF;2位是PF;4位是AF;6位是ZF;7位是SF;8位是TF;9位是IF;10位是DF;11位是OF。 例如:MOV AH,0C1H
SAHF 指令执行前:AH=1100 0001
指令执行后:CF=1,PF=0,AF=0ZF=1,SF=1. ③指令PUSHF 格式:PUSHF
该条指令把标志寄存器的内容压入堆栈,即先把堆栈指针寄存器SP的值减2,然后把标志寄存器的内容送入由SP所指的栈顶。 ④指令POPF 格式:POPF
该条指令把当前堆栈顶的一个字传送到标志寄存器,同时相应地修改堆栈指针,即把堆栈指针寄存器SP的值加2.