前言
8086指令系统格式可以分为下列三种形式
- 双操作数形式:OPR OPD,OPS
- 单操作数形式:OPR OPD
- 无操作数形式:OPR
数据传送类指令
1.通用数据传送指令
1)传送指令MOV
语句格式:MOV OPD,OPS
功能:将源操作数传送入目的地址,源地址内容不变,即(OPS)->OPD
注意事项
- MOV指令可以传8位数据,也可以传16位数据,这决定于寄存器是八位还是16位,或立即数是8位还是16位。
- MOV指令中的目的操作数和源操作数不能都是存储器操作数,即不允许用MOV实现两个存储单元之间的数据传输。
- 不能用CS和IP作为目的操作数,因为这两个寄存器的内容不能随便改变
- 不允许在段寄存器之间传输数据,如MOV DS,ES是错误的
- 不允许用立即数作为目的操作数
- 不能向段寄存器传送立即数,如果需要对段寄存器赋值,可以通过CPU的通用寄存器AX来完成
2)数据交换指令XCHG
语句格式:XCHG OPD,OPS
功能:交换源操作数和目的操作数的内容(不能为段寄存器),操作数可分为字类型(16位)和字节类型(8位)
注意事项
- 两个操作数不能同时为存储器操作数
- 任一个操作数都不能使用段寄存器,也不能使用立即数
3)查表转换指令XLAT
语句格式:XLAT OPS或XLAT
功能:将(BX)为首址、(AL)为位移量的字节存储单元的数据送AL寄存器,即(DS):(BX)+(AL) ->AL
2.堆栈操作指令
堆栈是在内存中开辟的一块特殊存储区,它有特殊的访问方式,具有“先进后出”或“后进先出”的特点。
堆栈所在的逻辑段就是堆栈段,其段基址由SS提供。堆栈的出/入口称为栈顶,所有的进栈和出栈操作都是从栈顶进行,栈顶指针SP的内容的内容始终指向当前的栈顶,即栈顶的逻辑地址为(SS):(SP)。SP的初值所指向的单元称为栈底,可以由程序设置。栈底的下一个单元开始存放进栈的数据
8086/8088的栈顶单元内存放着最后进栈的数据,即SP总是指向最后压进栈的数据字。
8086/8088的堆栈是以字为单位组织的,即进栈和出栈操作是按16位的字进行的,而且堆栈是从高地址向低地址方向方向生长,每进一个数据,SP的内容要减2,;每出栈一个数据,SP的内容要加2.当栈为空时,栈中没有元素,相应的不存在栈顶元素,此时栈指针SS:SP指向栈的最底部单元下面的单元,该单元的偏移地址为栈的最底部的字单元的偏移地址加2.
1)进栈指令push
语句格式:PUSH OPS
功能:将寄存器、段寄存器或存储器中的一个字数据压入堆栈,堆栈指针减2。高字节先进栈,低字节后进栈。
2)出栈指令POP
语句格式:POP OPS
功能:将栈顶元素弹出送至某一寄存器、段寄存器(除CS外)或存储器,堆栈指针加2,低字节先出栈,高字节后出栈。
- POP和PUSH指令在执行时,通过SS:SP保证数据在进栈和出栈的时候指向栈顶,但是在8086CPU中存在一个栈顶越界问题。栈顶越界有两种情况:一是当栈满的时候,继续通过PUSH指令使数据进栈;二是当栈空时,继续使用POP指令出栈。栈顶越界有可能导致栈外的数据被覆盖,从而引发一系列错误,因此编程时要安排合理的栈空间,防止进栈数据过多导致越界;在使用POP指令时要防止空栈时继续出栈导致越界。
3.标志寄存器传送指令
1)标志送AH指令LAHF
语句格式:LAHF
功能:将标志寄存器的低8位送入AH寄存器(累加器,通用寄存器的一种)。该指令的执行对标志位无影响。
2)AH送标志寄存器SAHF
语句格式:SAHF
功能:将AH的内容送入标志寄存器的低8位,高8位不变。
3)标志寄存器进栈指令PUSHF
语句格式:PUSHF
功能:将标志寄存器的内容压入堆栈。
4)标志寄存器出栈指令POPF
语句格式:POPF
功能:将栈顶内容弹出送入标志寄存器当中。
4.地址传送指令
1)传送偏移地址指令LEA
语句格式:LEA OPD,OPS
功能:按源操作数的寻址方式计算偏移地址,将偏移地址送入指定寄存器(将源操作数的有效地址送到目的操作数中)。其中源操作数是mem(存储器操作数),目的操作数是一个16位的reg(通用寄存器)。
2)传送偏移地址及数据段首址指令LDS
语句格式:LDS OPD,OPS
功能:该指令完成一个存放在内存中的32位地址指针的传送,地址指针包括段基址和偏移地址两部分。源操作数mem,目的操作数是16位的reg。该指令将主存中指定字单元数据送入指定寄存器,下一单元数据送DS(将源操作数寻到mem地址的第一个字送到reg指定的通用寄存器,然后再将后续的第二个字送到DS中)。本指令常用于将32位的地址指针装入SI和DS。
3)传送偏移地址及附加段指令LES
语句格式:LES OPD,OPS
功能:功能与LDS基本一样,将主存某字单元内容送指定寄存器,只是将DS换成ES,即(OPS)
->(OPD),(OPS+2)->ES
5.输入/输出指令
8086/8088所有I/O端口和微处理器之间的数据交换都是由IN指令和OUT指令完成,其中IN指令完成从I/O端口向微处理器传递数据,OUT指令则相反。微处理器只能用累加器(AL或AX)与I/O端口交换数据,I/O端口的地址(称为端口号)编码为0000H~FFFFH,其中端口号为00H~FFH可以直接在指令中指定,端口号大于等于256(即端口地址在FFH之后)时,要访问这些端口,必须先把端口地址放在DX寄存器中,然后再用IN指令或OUT指令来传送数据。
输入输出指令不影响标志位
1)输入指令IN
输入指令用来从指定的外设寄存器取信息送入累加器,它有四种形式。
语句格式:IN AL,PORT 功能:(PORT)->AL
语句格式:IN AX,PORT 功能:(PORT)->AX
语句格式:IN AL,DX 功能:(【DX】)->AL
语句格式:IN AX,DX 功能:(【DX】)->AX
其中,PORT表示端口号,DX的内容也为地址;源操作数可以采用对端口的直接寻址或间接寻址提供端口数据,目的操作数只能是AL或AX。
2)输出指令OUT
输出指令用来把累加器的内容送往指定的外设存储器,它有4种形式。
语句格式:OUT PORT,AL 功能: (AL)->PORT
语句格式:OUT PORT,AX 功能:(AX)->PORT
语句格式:OUT DX,AL 功能:(【AL】)->DX
语句格式:OUT DX,AX 功能:(【AX】)->DX
源操作数只能是AL和AX,目的操作数可以是采用对端口的直接寻址方式或间接寻址方式确定的端口单元。
算数运算类指令
8086/8088可以对二进制无符号或有符号进行加、减、乘、除4种基本运算。通过BCD码调整指令还可以完成无符号十进制数的四则运算。无符号十进制数用压缩型BCD码或非压缩型BCD码调整。对非压缩型BCD码,做除法时,高四位必须是0,做加/减法运算时,高四位可以为任意值。
算术运算指令影响标志位
1.加法指令
1)加1指令INC
语句格式:INC OPD
功能:将目的操作数加1,结果送目的地址,即(OPD)+1->(OPD)
INC指令是一个单操作数指令,操作数可以是寄存器或存储器操作数,且按无符号的二进制数处理。
影响标志位:AF、OF、PF、SF和ZF
加1指令可用于对计数器和地址指针进行调整
2)不带进位的加指令ADD
语句格式:ADD OPD,OPS
功能:将目的操作数和源操作数相加,结果存入目的操作数中,源地址的内容不改变。即(OPD)+(OPS)->OPD
两个操作数可以是有符号或无符号的8位和16位二进制数。源操作数可以是reg、mem或data;目的操作数可以是reg或mem。立即数不能为目的操作数,且两个操作数不能同时为mem。
影响标志位:AF、CF、OF、PF、SF和ZF
3)带进位加指令ADC
语句格式:ADC OPD,OPS
功能:将目的操作数加源操作数再加低位进位,结果送目的地址。即(OPD)+(OPS)+CF->(OPD)。
影响标志位:同ADD指令
2.减运算指令
1)减1指令DEC
语句格式:DEC OPD
功能:将目的操作数减1,结果送目的地址。即(OPD)-1 ->OPD
INC指令是一个单操作数指令,操作数可以是寄存器或存储器操作数,且按无符号的二进制数处理。
影响标志位:AF、OF、PF、SF和ZF
减1指令也可用于对计数器和地址指针进行调整
2)不带进位的减指令SUB
语句格式:SUB OPD,OPS
功能:目的操作数减源操作数,结果存于目的地址,源地址内容不变 。即(OPD)-(OPS)->(OPD)
两个操作数可以是有符号或无符号的8位和16位二进制数。源操作数可以是reg、mem或data;目的操作数可以是reg或mem。立即数不能为目的操作数,且两个操作数不能同时为mem。
影响标志位:AF、CF、OF、PF、SF和ZF
3)带借位减指令SBB
语句格式:SBB OPD,OPS
功能:目的操作数减源操作数再减低位借位CF,结果送目的地址。即(OPD)-(OPS)-CF->
OPD
影响标志位:与SUB命令相同
4)求补指令NEG
语句格式:NEG OPD
功能:将目的操作数的每一位求反(包括符号位)后加1,结果送目的地址(将零减去指定的8位或16位的目的操作数,并将结果送回目的操作数单元)。即(OPD)+1->OPD
影响标志位:同SUB指令
5)比较指令CMP
语句格式:CMP OPD,OPS
功能:目的操作数减源操作数,结果只影响标志位,不送入目的地址。即只进行(ODS)-(OPS)操作
影响标志位:与SUB相同
3.乘运算指令
1)无符号数乘法指令MUL
语句格式:MUL OPS
功能:若是字节数相乘,(AL)与OPS相乘得到字数据存入AX中;若是字数据相乘,则(AX)与OPS相乘得到双字数据,高字存入DX,低字存入AX中。其中,OPS为寄存器或存储单元。
字节乘法:(AL)*(OPS)->AX;字乘法:(AX)*(OPS)->DX,AX
影响标志位:若乘积的高半部,即(AH)或(DX)不为零时,则CF和OF置“1”,表示AH或DX的内容为乘积的有效数字;否则,CF和OF置“0”。AF、PF、SF和ZF无定义(指令执行后这些条件码位的状态不定)
2)有符号乘指令IMUL
语句格式:IMUL OPS
功能:字节乘法功能指令为(AL)*(OPS)->AX;字乘法功能指令为(AX)*(OPS)->DX、AX。
IMUL指令除计算对象是带符号二进制数外,其他与MUL一样,但计算结果不同。
影响标志位:若结果的高半部不是低半部的符号扩展,则OF和CF置1,说明AH和DX是有效数位;
否则OF和CF置0。AF、PF、SF、和ZF不定。
4.除运算指令
1)无符号除指令DIV
语句格式:DIV OPS
功能:字节除法功能指令为(AX)/(OPS)->AL(商)、AH(余数);
字除法功能指令为(DX、AX)/(OPS)->AX(商)、DX(余数)。
其中,OPS为寄存器或存储单元
影响标志位:AF、CF、OF、PF、SF和ZF都是任意的,无有效标志。
2)有符号除指令IDIV
语句格式:IDIV OPS
功能:字节除法功能指令为(AX)/(OPS)->AL(商)、AH(余数);
字除法功能指令为(DX、AX)/(OPS)->AX(商)、DX(余数)。
影响标志位:无有效标志。
除法指令DIV和IDIV虽然对标志的影响未定义,但可产生溢出。
5.符号扩展指令
1)字节转换成字指令CBW
语句格式:CBW
功能:将AL中的符号位数据扩展至AH。若AL的最高位为1,则把FFH存入AH,否则把00H存入AH。
影响标志位:无
在执行IMUL或IDIV指令之前,该指令可用于扩展AL的内容。
2)字转换成双字指令CWD
功能:将AX中的符号位数据扩展至DX。若AX最高位为1,则把FFFFH存入DX,否则把0000H存入DX。
影响标志位:无
在执行IDIV指令之前用于扩展成双字数据。
位操作类指令
位操作指令分别为逻辑运算指令和移位指令两类。
1.逻辑运算指令
逻辑运算指令是按位运算的指令,没有进位问题。其中NOT指令是单操作数的,NOT指令中的操作数不允许为立即数;其余4条指令为双操作数指令,不允许两个操作数均为存储单元,如果源操作数为立即数,则目的操作数可以为存储单元或寄存器。
1)求反指令NOT
语句格式:NOT OPD
功能:将目的地址中的内容逐位取反后送入目的地址。
影响标志位:无
2)逻辑乘指令AND
语句格式:AND OPD,OPS
功能:将目的操作数和源操作数进行逻辑乘运算(按位运算),结果存目的地址。
即(OPS)∧(OPS)->OPD。
该指令用于清除目的操作数中与源操作数置0的对应位。
说明:逻辑乘的运算法则为1∧1=1,1∧0=0,0∧1=0,0∧0=0
影响标志位:OF=0,CF=0,AF不定,SF、ZF、PF根据逻辑运算的结果设置为0或1。
3)测试指令TEST
语句格式:TEST OPD,OPS
功能:源地址和目的地址的内容执行按位的逻辑乘运算,结果不送入目的地址。即(OPD)∧(OPS)
影响标志位:同AND指令
4)逻辑加指令OR
语句格式:OR OPD,OPS
(OPD)∨(OPS)->OPD
说明:逻辑加的运算法则为1∨1=1,1∨0=1,0∨1=1,0∨0=0
影响标志位:同AND指令
5)按位加指令XOR
语句格式:XOR OPD,OPS
功能:目的操作数与源操作数做按位加运算,
目的操作数与源操作数做按位加运算,结果送入目的地址。
说明:按位加的运算法则为异或,与0异或不变,与1异或取反
影响标志位:同AND指令
2.移位指令
移位指令包括算术移位指令、逻辑移位指令和循环移位指令,分别进行左移和右移操作。这些指令均有统一的语句格式:
【标号:】操作符OPD,1或【标号:】操作符OPD,CL
其功能为将目的操作数的所有位按操作符号规定的方式移动1位或按寄存器CL规定的次数(0~255)移动,结果送入目的地址。目的操作数为8位(或16位)的寄存器数据或存储器数据
1)算术左移和逻辑左移指令SAL(SHL)
语句格式 :SAL OPD,1或SHL OPD,1
SAL OPD,CL或SHL OPD,CL
功能:将(OPD)向左移动CL指定的次数,在低位补入相应个数的0,CF的内容为后移入位的值。
影响标志位:CF总是等于目的操作数最后移出位的值。对OF,若只移动一位,且结果使最高位(符号位)发生变化,则OF置1,否则置零;若移动位数为一次以上,则OF不定。SF、ZF、PF根据结果设置,AF不定。
2)算术右移指令SAR
语句格式:SAR OPD,1或SAR OPD,CL
功能:将(OPD)向右移动CL规定的次数,最高补入相应的个数0,CF的内容为最后移入位的值。
影响标志位:同上
3)逻辑右移指令SHR
语句格式:SHR ORD,1或SHR OPD,CL
功能:将(OPD)向右移动CL规定的次数,最高位补入相应个数的0,CF的内容为最后移入的值。
影响标志位:同上
4)循环左移指令ROL
语句格式:ROL OPD,1或ROL OPD,CL
功能:将目的操作数的最高位和最低位连成一个环,将环中所有位一起向左移动CL规定的次数。CF的内容为最后移入位的值。
影响标志位:CF、OF同上,SF、ZF、PF不变,AF不定
5)循环右移指令ROR
语句格式:ROR OPD,1或ROR OPD,CL
功能:将目的操作数的最高位和最低位连成一个环,将环中所有位一起向右移动CL规定的次数。CF的内容为最后移入位的值。
影响标志位:CF、OF同上,SF、ZF、PF不变,AF不定
6)带进位的循环左移指令RCL
语句格式:RCL OPD,1或RCL OPD,CL
功能:将目的操作数连同CF标志,一起向左循环移动CL规定的次数
影响标志位:CF、OF同上,SF、ZF、PF不变,AF不定
6)带进位的循环左移指令RCR
语句格式:RCR OPD,1或RCR OPD,CL
功能:将目的操作数连同CF标志,一起向右循环移动CL规定的次数
影响标志位:CF、OF同上,SF、ZF、PF不变,AF不定
串操作类指令
串是指连续存放在存储器中的一些数据。数据传送指令每次只能传送一个数据,若要传送大批数据就需要重复编程,这样就浪费了大量的时间和空间。为此8086提供了一组处理主存中连续存放数据串的指令,这就是串操作指令。
串操作通常以DS:SI来寻址源串,以ES:DI来寻址目的串,对于源串可以进行跨段操作,但目的串的段寄存器只能是ES。指针SI、DI在每次串操作后都会自动修改,以指向串中的下一个元素,修改时按方向标志DF的值来决定是增量还是减量。当DF=0时,增量修改;当DF=1时,减量修改。
需要注意的是:串操作类指令每次执行只能对数据串中当前这个数据进行操作。如果需要进行连续串操作,通常要在串操作指令前加重复前缀,重复前缀可以和任何串操作指令组合,形成复合指令,重复前缀规定了串操作指令重复执行的次数,对于无重复前缀的串操作指令只能操作一个串元素。
串操作指令包括串传送、串比较、串搜索、串装入、串储存五类。
1.传送指令MOVS
语句格式:1)MOVSB:字节串传送
2)MOVSW:字串传送
功能:将以SI为指针的串源中的一个字节(或字)存储单元中的数据传送至以DI为指令的目的地址中去,并自动修改指针SI、DI,使之指向下一个字节
影响标志位:无
2.串比较指令CMPS
语句格式:1)CMPSB:字节串比较
2)CMPSW:字串比较
功能:将SI所指的源串中的一个字节(或字)存储单元中的数据与DI所指的目的串中的一个字节(或字)存储单元中的数据相减,并根据相减的结果设置标志,但结果并不保存。
影响标志:OF、SF、ZF、AF、PF、CF
3.串搜索指令SCAS
语句格式:1)SCASB:字节串搜索
2)SCASW:字串搜索
功能:AL(字节)或AX(字)中的内容与DI所指的目的串中的一个字节(或字)存储单元中的数据相减,根据相减结果设置标志位,结果不保存。
与串比较指令一样,在串扫描指令后也通常有一条条件转移指令。
4.从源串中取数(串装入)指令LODS
语句格式:1)LODSB:从字节串中取数
2)LODSW:从字串中取数
功能:将SI所指的源串中的一个字节(或字)存储单元中的数据取出来送入AL(或AX)中。
当DF=0时,(SI)增量;当DF=1时,(SI)减量。
影响标志位:无
通常不重复执行LODS
5.往目的串中存数(串存储)指令STOS
语句格式:1)STOSB:往字节串中存数
2)STOSW:往字节中存数
功能:将AL或AX中的数据送入DI所指的目的串中的字节(或字)存储单元中。
当DF=0时,(DI)增量;当DF=1时,(DI)减量。
影响标志位:无
利用重复前缀REP可以在串中建立一串相同的值。
6.重复前缀指令REP/REPZ/REPNZ
1)REP,用在MOVS,STOS,LODS前
功能:每执行一次串指令(CX)-1,直到(CX)=0,重复执行结束。
2)REPZ/REPE,该指令一般用在CMPS、SCAS指令前。
功能:每执行一次串指令(CX)-1,并判断ZF标志是否为0,只要(CX)=0或ZF=0,则重复执行结束。
3)REPNZ/REPNE,该指令一般用在CMPS、SCAS指令前。
功能:每执行一次串指令(CX)-1,并判断ZF标志是否为0,只要(CX)=0或ZF=1,则重复执行结束。
---------------------------------------------------------------------------------------------------------------------------------
本文内容摘自机械工业出版社出版的《汇编语言与接口技术》第2版