8086/8088指令系统8086/8088的指令系统丰富,而且指令的功能也强。
大多数指令既能处理字数据,又能处理字节数据;算术运算和逻辑运算不局限于累加器,存储器操作数也可直接参加算术逻辑运算。
8086/8088的指令系统可分为如下六个功能组:(1)数据传送(2)算术运算(3)逻辑运算(4)串操作(5)程序控制(6)处理器控制汇编语言语句的一般格式。
指令语句可由四部分组成,一般格式如下:[标号:] 指令助记符[操作数1] [操作数2] [;注释]指令是否带有操作数,完全取决于指令本身标号的使用取决于程序的需要,标号只被汇编程序识别,它与指令本身无关。
(一)数据传送指令数据传送指令组又可分为:传送指令,交换指令,地址传送指令,堆栈操作指令,标志传送指令,查表指令,输入输出指令在有关章节介绍。
除了SAHF和POPF指令外,这组指令对各标志没有影响。
1,传送指令其格式如下:MOV DST,SRC目的,源源操作数可以是累加器,寄存器,存储单元以及立即数,而目的操作数可以是累加器,寄存器和存储单元。
传送不改变源操作数。
传送指令能实现下列传送功能:(1)CPU内部寄存器之间的数据传送。
例如:MOV AH,ALMOV DL,DHMOV BP,SPMOV AX,CS注意:源和目的操作数不能同时是段寄存器;代码段寄存器CS不能作为目的;指令指针IP即不能作为源,也不能作为目的。
注意,这种例外永远存在。
(二)交换指令利用交换指令可方便地实现通用寄存器与通用寄存器或存储单间的数据交换,交换指令的格式如下:XCHG OPRD1,OPRD2此指令把操作数OPRD1R的内容与操作数OPRD2的内容交换。
操作数同时是字节或字。
例如:XCHG AL,AH;XCHG SI,BXOPRD1和OPRD2可是通用寄存器和存储单元。
但不包括段寄存器,也不能同时是存储单元,还不能有立即数,可采用各种存储器寻址方式来指定存储单元。
例如:XCHG BX,[BP+SI] 如指令执行前:(BX)=6F30H,(BP)=0200H,(SI)=0046H,(SS)=2F00H,(2F246)=4154H 物理地址=2F000+0200+0046=2F246H指令执行后:(BX)=4154H (2F246H)=6F36H此指令不影响标志位(三)地址传送指令80686/8088有如下三条地址传送指令。
(1)指令LEA (Load Effective Address)指令LEA称为传送有效地址指令,其格式如下:LEA REG,OPRD该指令把操作数OPRD的有效地址传送到操作数REG操作数OPRD必须是一个存储器操作数,操作数REG必须是一个16位的通用寄存器。
例如:LEA AX,BUFFER ;BUFFER是变量名LEA DS,[BS+S]LEA SL,[BP+DI+4]例如:LEA BX,[BX+SI+0F62H]如指令执行前(BX)=0400H,(SI)=003CH指令执行后(BX)=0040+003C+0F62=139EH(2)指令LDS (Load pointer into DS)段值和段内偏移构成32位的地址指针。
该指令传送32位地址指针,其格式如下:LDS REG,OPRD执行的操作:(REG)←(SRC)(DS)←(SRC+2)该指令把操作数OPRD中所含的一个32位地址指针的段值部分送到数据段寄存器DS,把偏移部分送到指令给出的通用寄存器REG。
操作数OPRD必须是一个32位的存储器操作数,操作数REG可以是一个16的通用寄存器,但实际使用的往往是变址寄存器或指针寄存器。
LDS SL,POINTER ;POINTER是一个双字变量假设双字变量POINTER包含的32位地址指令的段值为5678H,偏移为1234H,那么在执行指令后:(DS)=5678H,(SI)=1234H32位地址指针的偏移部分存储在双字变量的低地址字中,段值部分存储在高地址中。
例如:LDS SI,[10H]如指令执行前:(DS)=C000H,(C0010H)=0180,(C0012H)=2000H指令执行后:(SI)=0180H,(DS)=2000H(3)指令LES(Load pointer into ES)LES 指令也传送32位地址指针,其格式如下:LES REG,OPRD该指令把操作数OPRD中包含的32位地址指针的段值送到附加段寄存器ES,把偏移部分送到指令给出的通用寄存器REG。
执行的操作:(REG)←(SRC)(ES)←(SRC+2)例如: LES DI, [BX]如指令执行前: (DS)=B000H, (BX)=080AH, (0B080AH)=05AEH, (0B080CH)=4000H 执令执行后(DI)=05AEH, (ES)=4000H(四)堆栈操作指令在80686/8088系统中,堆栈是一段RAM区域.称为栈底的一端地址比较大,称为栈顶的一端比较小.(高地址) (低地址)堆栈的段值在堆栈段寄存器SS中,堆栈指针寄存器SP始终指向栈顶.堆栈是以”后进先出”的方式工作的一个存储区.堆栈的存取必须以字为单位.堆栈操作指令分为两种:(1)进栈指令格式如下: PUSH SRC执行的操作: (SP)←(SP)-2该指令把源操作数SRC压入堆栈.它先把堆栈指针寄存器SP的值减2,然后把源操作数SRC送入由SP所指指的栈顶.源操作数SRC可以是通用寄存器和段寄存器,可以是字存储单元.例如: PUSH AX假设AX=2107H(2)出栈指令POP格式如下: POP DST执行的操作: (SP)←(SP)+2POP DST该指令从栈顶弹出一个字数据到目的操作数DST.它先把堆栈指针寄存器SP所指的字数据送至目的操作数DST,然后SP值加2. DST可以是通用寄存器和段寄存器(但CS例外),也可是字存储单元.(五)标志传送指令(1)标志传送指令标志传送指令属于数据传送指令组.1,指令LAHF(Load AH with Flags)指令LAHF采用固定寻址方式,指令格式如下 :LAHF该条指令把标志寄存器的低8位(包括SF,ZF,AF,PF和CF)传送到寄存器AH的指定位,如下图所示:这条指令本身不影响这些标志和其他标志.2,指令SAHF采用回定寻址方式 , 其格式如下:SAHF这条指令与指令LAHF刚好相反,把寄存器AH的指定位送至标志寄存器低8位的SF,ZF,AF,PF和CF标志位.因而这些标志的内容就要受到影响,并取决于AH中相应位的状态.但这条指令不影响溢出标志OF,方向标志DF,中断允许标志IF和追踪标志TF,也即不影响标志寄存器的高位字节.例如:MOV AH ,0C1HSAHF ; CF=1,PF=0,AF=0,ZF=1,SF=13,指令PUSHF指令PUSHF的格式如下:PUSHF该条指令把标志寄存器的内容压入堆栈,即先把堆栈指针寄存器SP的值减2,然后把标志寄存器的内容送入由SP所指的栈顶.4,指令POPF指令POPF的格式如下:POPF该条指令把当前堆栈顶的一个传送到标志寄存器,同时相应地修乞讨堆栈指针,即把堆栈指针寄存器SP的值加2.这条指令和PUSHF指令一起可以保存和恢复标志寄存器的内容,即保存和恢复各标志的值.另外,这两条指令也可以用来改变追踪标志TF.为了改变TF标志,可先用PUSHF指令将标志压入堆栈,然后设法改变栈顶字单元中的第8位(把整个标志寄存器看成是一个字),再用POPF指令把该字弹回到标志寄存器,这样其余的标志不受影响,而只有TF标志按需要改变了.(2)标志位操作指令标志位操作指令公对指令规定的标志产生指令规定的影响,对其他标志没有影响.产生指令规定的影响,对其它标志没有影响.1,清进位标志CLC (Clear Carry flag)清进位标志指令的格式如下:CLC该指令使进位标志为0.2,置进位标志指令STC (SeT Carry Flag)置进位标志指令的格式如下:STC该指令使进位标志为0.3,进位标志取反指令CMC (CoMpleinent carry flag)进位标志取反指令的格式如下:CMC该指令使进位标志取反.如CF为1,则使CF为0; 如CF为0,则CF为1.4,清方向标志CLD (Clear Direction flag)清方向标志指令的格式如下:CLD该条指令使主向标志DF为0.从而在执行串操作指令时,使地址按递增方式变化.5,置方向标志STD (SeT Direction flag)置方向标志指令的格式如下:STD该条指令使方向标志DF为1,从而在执行串操作指令进,使地址按递减方式变化. 6,清中断充许标志CLI (Clera Interrupt enable flag)清中断允许标志指令的格式如下:CLI该条指令使中断允许标志IF为0,于是CPU就不响应来自外部装置的可屏蔽中断.但对不可屏蔽中断和内部中断都没有影响.7,置中断允许标志STI (SeT Interrupt enable flag)置中断允许标志指令的格式如下:STI该条指令使中断允许标志IF为1,则CPU可以响应可响应屏蔽中断.(六)加减运算指令(1)加法指令 ADD格式如下: ADD OPRD1,OPRD2执行的操作:(OPRD1)←(OPRD1)+(OPRD2)例如: MOV AX,7896H ; AX=7890H即AH=78H,AL=96;各标志保持不变ADD AL,AH ; AL=0EH,AH=78H,即AX=780EH;CF=1,ZF=0,SF=0,OF=0,AF=0,PF=0例如: ADD DX,0F0F0H执行前(DX)=4652H执行后(DX)=3742H ZF=0,SF=0,CF=1,OF=0例如: ADD AX,4321执行前(AX)=62A0执行后(AX)=A5C1H SF=1,ZF=0,CF=0,OF=1从上面的例子可看出:加法指令影响标志位OF位则根据操作数的符号及其变化情况来设置:若两个操作的符号相同而结果的符号与相反时OF=1,否则OF=0CF位可以用来表示无符号数的溢出,由于无符号数的最高有效位只有数值意义而无符号意义,所以从该位产生的进位应该是结果的实际进位值,但是有限数的范围内就说明了结果。
(1)带进位加法指令ADD(Add with Carry )带进位加法指令的格式如下:ADC OPRD1,OPRD2OPRD1←OPRD1+OPRD2+CF例如:下列指令序列执行两个双精度的加法.设目的操作数放在DX和AX寄存器,其中DX存放高位字.源操作数存放在BX,CX中,其中BX存放高位字.如指令执行前:(DX)=0002H, (AX)=0F365H(BX)=0005H, (CX)=0E024H指令序列为: ADD AX,CXADC DX,BX执行第一条指令后:(AX)=0D389H, SF=1,ZF=0,ZF=1,OF=0执行第二条指令后:(DX)=0008H, SF=0,ZF=0,CF=0,OF=0则该指令序列执行完后(DX)=0008H, (AX)=D389H(3)加1指令INC (INCrement)加1指令的格式如下:INC OPRD这条指令完成对操作数OPRD加1,然后把结果送回OPRD,即:OPRD←OPRD+1操作数OPRD可以是通用寄存器,也可以是存储单元.这条指令执行的结果影响标志ZF,SF,OF,PF和AF,但它不影响CF.该指令主要用于调整地址指针和计数器.例如:写出把首地址为BLOCK的字数组的第6个字送到DX寄存器的指令.要求使用以下几种寻址方式:1.寄存器间接寻址 MOV BX,OFFSET BLOCKADD BX,000AH MOV DX,[BX]2,寄存器相对寻址 MOV BX,OFFSET BLOCKMOV DX,[BX+000AH](3)减法指令SUB(SUBtraction)减法指令的格式如下:目的源SUB OPRD1,OPRD2执行的操作:(OPRD1)←(OPRD1)-(OPRD2)例如:SUB [SI+14H],0136指令执行前(DS)=3000H,(SI)=0040H,(30054H)=4336指令执行后(30054H)=4200HSF=0,ZF=0,CF=0,OF=0例如:SUB DH,[BP+4]指令执行前(DH)=40H,(SS)=0000H,(BP)=00E4H,(000E8H)=5AH指令执行后(DH)=0E7H,SF=1,ZF=0,CF=1,OF=0此指令影响标志位CF位说明无符号数想减的溢出,同时它又是被减数的最高有效位向高位的借位,OF位则说明带符号的溢出.减法的OF位的设置方法为:若两个数的符号相反,而结果的符号与减数相同则OF=1,说明结果是错误的.(4)带借位减法指令SBB(SuBtract with Borrow)带借位指令的格式如下:SBB OPRD1,OPRD2执行的操作:(OPRD1)←(OPRD1)-(OPRD2)-CF例如:SBB AL,DLSBB DX,AX该指令主要用于多字节相减的场合(5)减1指令DEC(DECreinent)减1指令的格式如下:DES OPRD执行的操作:(OPRD)←(OPRD)-1例如:DEC VARB ; VARB是字节变量操作数OPRD可以是通用寄存器,也可以是存储单元。