8086/8088指令系统
名称 | 含义 |
---|---|
IM (Immediate) | 立即数 |
REG (Register) | 寄存器操作数 |
MEM (Memory) | 存储器操作数 |
SEG (Segment) | 段寄存器(CS、DS、ES、SS) |
OPR (Operand) | 操作数 |
OPS (Source Operand) | 源操作数 |
OPD (Destination Operand) | 存储器操作数 |
一、数据传送指令
(一)通用数据传送指令(MOV、XCHG、PUSH、POP、PUSHA、POPA)
1、通用数据传送指令:MOV
指令格式:MOV OPD,OPS
作用:将源操作数指定的内容传送到目的操作数,即 OPD<=(OPS),当指令执行完后,目的操作数原有的内容被源操作数内容覆盖,即目的操作数和源操作数具有相同内容
注意事项:
- MOV指令可以是字节数据传送也可以是字数据传送,但是源操作数和目的操作数的长度必须一致
- 立即数只能作源操作数,且不能传送给段寄存器
- 段寄存器CS只能作源操作数,段寄存器之间不能直接传送
- 存储单元之间不能直接传送数据
- MOV指令对标志寄存器的各位无影响
(1)立即数传送到通用寄存器或存储单元
立即数只能作为源操作数,立即数不能传送给段寄存器
例:
MOV AH,10H
MOV AX, 2345H
MOV M-BYTE, 64H
MOV M-WORD,2364H
(2)寄存器之间的传送
段寄存器CS只能作源操作数,不能作目的操作数
例:
MOV AH,CH
MOV DS, AX
MOV ES, BX
MOV AX,CS
MOV CS, AX; 错误:段寄存器CS只能作源操作数,不能作目的操作数
(3)寄存器与存储单元之间传送
例:
MOV AL,[SI]
MOV [DI],AH
MOV AX, 10[BX]
MOV TABLE[BP], BX
MOV DS, [SI][BX]
MOV [BX], [BP][SI]; 错误:存储单元之间不能直接传送数据
2、交换指令:XCHG
指令格式:XCHG OPD,OPS
作用:源操作数和目的操作数两者内容相互交换,即: (DEST)<=>(SRC)
注意事项:
- 数据交换可以在寄存器之间 或 寄存器与存储器单元之间进行
- 数据交换不能在存储单元之间直接进行数据交换
- 寄存器只能使用通用寄存器
- 指令对标志寄存器各位无影响
(1)寄存器之间数据交换
例:
XCHG AX,BX
XCHG AH,CH
例:两个存储单元(DA_BYTE1和DA_BYTE2)之间的数据交换可以使用以下三条指令来实现
MOV AL,DA-BYTE1; AL <= (DA_BYTE1)
XCHG AL,DA-BYTE2 ; (AL)<=>(DA-BYTE2)
XCHG AL,DA-BYTE1 ; (AL)<=>(DA-BYTE1)
或 MOV DA-BYTE1,AL; (DA_BYTE1)<=(AL)
3、堆栈指令
(1)进栈指令:PUSH
指令格式:PUSH OPS
作用:将寄存器、段寄存器或存储器中的一个字数据压入堆栈,堆栈指针减2
即:
(SP)-1 => SP 、(OPS)15至8 => ([SP])
(SP)-1 => SP 、(OPS)7至0 => ([SP])
注意事项:
- 源操作数可以是CPU内部的16位通用寄存器、段寄存器和存储器操作数(所有寻址方式)
- 进栈操作对象必须是16位数
(2)出栈指令:POP
指令格式:POP OPD
作用:将栈顶数据弹出传送至某一寄存器、段寄存器(CS除外)或存储器,堆栈指针加2
即:
([SP]) => (OPD)7至0 、(SP)+1 => SP
([SP]) => (OPD)15至8 、(SP)+1 => SP
注意事项:
- CS段寄存器不可以存放目标操作数
(3)所有寄存器进栈指令:PUSHA
指令格式:PUSHA
作用:16位通用寄存器依次进栈,次序为AX、CX、DX、BX,
指令执行前的SP、BP、SI、DI。指令执行后(SP)-16 => (SP) 仍指向栈顶
注意事项:
- 指令不影响标志位
(4)所有寄存器出栈指令:POPA
指令格式:POPA
作用:16位通用寄存器依次出栈,次序为DI、SI、BP、SP
指令执行前的BX、DX、CX、AX。指令执行后(SP)-16 => (SP) 仍指向栈顶
注意事项:
- SP出栈只是修改了指针使其后的BX能够出栈,而堆栈中原先由PUSHA指令存入的SP的原始内容被丢弃,并未真正的送到SP寄存器中
- 指令不影响标志位
(二)累加器专用传送指令(IN、OUT、XLAT)
这组指令仅限于使用累加器AX或AL传送信息
1、输入指令:IN
长格式:(PORT为端口号)
IN AL,PORT(字节); (AL) <= (PORT)(字节)
IN AX,PORT(字) ; (AX) <= (PORT+1,PORT)(字)
短格式:
IN AL,DX(字节); (AL) <= ((DX))(字节)
IN AX,DX(字) ; (AX) <= ((DX)+1,(DX))(字)
2、输出指令:OUT
长格式:(PORT为端口号)
OUT PORT,AL(字节); (PORT) <= (AL)(字节)
OUT PORT,AX(字) ; (PORT+1,PORT) <= (AX)(字)
短格式:
OUT DX,AL(字节); ((DX)) <= (AL)(字节)
OUT DX,AX(字) ; ((DX)+1,(DX)) <= (AX)(字)
3、换码指令:XLAT
格式:XLAT OPR 或 XLAT
作用:将以(BX)为首址(AL)为位移量的字节存储单元中的数据传送至AL寄存器
即 ([BX+AL]) => AL
注意事项:
- 由于AL寄存器只有8位,所以表格的长度不能超过256
(三)地址传送指令(LEA、LDS、LES)
这类指令有3条,它们的作用是将存储单元的地址送寄存器
1、装入有效地址:LEA
格式:LEA OPD,OPS
作用:将SRC存储单元地址中的偏移量,即有效地址EA传送到一个16位通用寄存器中
注意事项:
- 源操作数SRC必须是一个字节或字存储器操作数(地址),DEST必须是一个16位通用寄存器
- 指令执行对标志寄存器各位无影响
例:
LEA AX,[BX] [SI]
源操作数使用的是基址变址寻址方式,它所形成的有效地址就是BX的内容加上SI的内容。即
AX<=(BX)+(SI)
注意:它不是将BX和SI所寻址的存储单元的内容送入AX
例:比较指令 LEA BX,DS:[23H] 与 MOV BX,DS:[23H] 的功能
LEA BX,DS:[23H]
MOV BX, DS:[23H]
2、装入地址指针指令:LDS、LES
格式:
LDS DEST,SRC
LES DEST,SRC
作用:把SRC存储单元开始的4个字节单元的内容 (32位地址指针)送入DEST通用寄存器和段寄存器DS(LDS指令)或ES(LES指令),其中低字单元内容为偏移量送通用寄存器,高字单元内容为段基值送DS或ES
注意事项:
- DEST是任意一个16位通用寄存器
- SRC必须是一个存储器操作数
例:
LDS SI,TABLE[BX]
设 TABLE的值为0A02H, (BX)=34H,(DS)=2030H
指令执行前 | 指令执行后 |
---|---|
(四)标志寄存器传送指令(LAHF、SAHF、PUSHF、POPF)
1、取标志寄存器指令:LAHF
指令格式:LAHF
作用:将标志寄存器的低8位送入AH寄存器,
即将标志 SF、ZF、AF、PF和CF分别送入AH的第7、6、4、2、0 位,而AH的第5、3、1位不确定
注意事项:
- 指令执行对标志寄存器各位无影响,即标志寄存器各位不变
2、存储标志寄存器指令:SAHF
指令格式:SAHF
作用:将寄存器AH中的第7、6、4、2、0位分别送入标志寄存器的SF、ZF、AF、PF和CF各标志位,而标志寄存器高8位中的各标志位不受影响
3、标志进栈指令:PUSHF
指令格式:PUSHF
作用:先将堆栈指针SP减2,使其指向堆栈顶部的空字单元,然后将16位标志寄存器的内容送SP指向的字单元
4、标志出栈指令:POPF
指令格式:POPF
作用:将由SP指向的堆栈顶部的一个字单元的内容送入标志寄存器,然后SP的内容加2
二、算术运算指令
(一)加法指令(ADD、ADC、INC)
1、加法指令:ADD
指令格式:ADD DEST,SRC
功能:目的操作数和源操作数相加,其和存放到目的操作数中,而源操作数内容保持不变,即 DEST<=(DEST)+(SRC)
注意事项:
- 根据相加的结果将影响到标志寄存器的CF、PF、 AF、ZF、SF 和 OF
- DEST只能是通用寄存器或存储器操作数。不能是立即数
- SRC可以是通用寄存器、存储器或立即数操作数
- DEST和SRC不能都为存储器操作数
- ADD指令可以是字节操作数相加,也可以是字操作 数相加
例 分析下列各指令功能
ADD AX,CX
功能:将寄存器AX的内容与CX的内容相加,结果传送到AX中
ADD AH,DATA_BYTE
功能:将由直接寻址方式所指示的存储单元的内容与AH内容相加,结果送回AH中
ADD CX,10H
功能:将常数10H加入到CX中。为字操作数指令
ADD AX, [BX][SI]
功能:将由基址变址寻址方式所指示的存储单元的内容加入到AX中
2、带进位加法指令:ADC
指令格式:ADC DEST,SRC
功能:该指令的功能与ADD基本相同,所不同的是其结果还要加上进位标志CF的值,即:DEST<=(DEST)+(SRC)+CF
注意事项:
- 根据相加的结果设置标志寄存器中的 CF、PF、AF、 ZF、SF 和 OF
- 参加运算的进位CF是本条指令执行之前的值
- 用ADC指令可实现数据长度大于16位的两数相加
例:计算 12349678H+377425H
MOV AX, 1234H
MOV BX, 9678H
ADD BX,7425H
ADC AX,37H
指令执行后,结果的高16位在AX,低16位在BX中
3、加1指令:INC
指令格式:INC DEST
功能:该指令为单操作数指令,其功能是将目的操作数加1,并送回到目的操作数,即: DEST<=(DEST)+1
注意事项:
- 目的操作数可以是任意的8位、16位通用寄存器或存储器操作数
- 目的操作数被视为带符号二进制数
- 根据指令执行结果设置 PF、AF、ZF、SF和OF标志,但不影响CF
- INC指令主要用于某些计数器的计数和修改地址指针
例:
INC CL
INC SI
INC COUNT
(二)减法指令(SUB、SBB、DEC、NEG、CMP)
1、减法指令:SUB
指令格式:SUB DEST,SRC
功能:目的操作数的内容减去源操作数的内容,结果送入目的操作数,源操作数中内容保持不变,即:DEST<=(DEST)-(SRC)
注意事项:
- 操作结果将影响标志位CF、PF、AF、ZF、SF和OF
- 目的操作数DEST和源操作数SRC可以是8位或16位的通用寄存器、存储器操作数,但两者不能同时为存储器操作数
- 立即数只能作源操作数
- 减法指令对借位标志的影响:若采用变减为加的运算方法,则产生的进位与CF标志结果相反
2、带借位减法:SBB
指令格式:SBB DEST,SRC
功能:该指令的功能与SUB指令基本相同,不同的是在两个操作数相减后再减去进位标志CF的值,即:DEST<=(DEST)-(SRC)-C
注意事项:
- 该CF的值是本条指令执行前的结果
- SBB指令在使用上与ADC类似,主要用于长度大于16位的数相减,即将低16位相减的结果引入高位部分的减法中
- 根据指令执行结果设置PF、AF、ZF、SF 、OF 和 CF
3、减1指令:DEC
指令格式:DEC DEST
功能:该指令为单操作数指令,将目的操作数的内容减1后,送回到目的操作数,即:DEST<=(DEST)-1
注意事项:
- DEST可以是8位或16位的通用寄存器存储器操作数,该指令将DEST看作是带符号二进制数
- 根据指令执行结果设置PF、AF、ZF、SF和OF, 但不影响CF
- DEC指令的使用类似INC指令。主要用于计数和修改地址指针,计数方向与INC指令相反
例
MOV AL,10H
LOP: DEC AL
JNC LOP
上述程序段中,是一个错误应用DEC指令的例子
4、求负数指令:NEG
指令格式:NEG DEST
功能:用零减去目的操作数的内容,并送回目的操作数,即:DEST<=0-(DEST)
注意事项:
- DEST可以是任意一个8位或16位的通用寄存器或存储器操作数,被视为带符号的操作数
- 由于机器中带符号数用补码表示,求操作数的负数就是求补操作。因此,NEG指令也叫取补指令
- NEG指令将影响标志PF、AF、ZF、SF、CF和OF
- 对进位标志CF的影响:
只有当操作数为零时,进位标志CF被置零,其它情况都被置1- 对溢出标志OF的影响:
当字节操作数为-128,或字操作数为-32768时,执行NEG指令的结果操作数将无变化,但溢出标志 OF被置1
例1:
设AL中存放一个正数(AL)=25H,
BL中存放一个 负数:(BL)=-58H,
求它们的相反数,即负数?
NEG AL
NEG BL
指令执行后
(AL)=-25H=11011011B
(BL)= 58H=01011000B
例2:
一个32位带符号数存放在 DAW 开始的四个字节存储单元中,DAW 字节单元存放最低字节
求该数的负数,并存入原存储单元中
NEG WORD PTR DAW
MOV AX,0
SBB AX,DAW+2
MOV DAW+2,AX
结果的低16位由指令NEG直接得到,而高16位还要考虑低16位产生的借位
因此使用了带借位的指令SBB
(三)乘法指令(MUL、IMUL)
(四)除法指令(DIV、IDIV)
(五)类型转换指令(CBW、CWD)
(六)十进制调整指令(DAA、DAS、AAA、AAS、AAM、AAD)
三、逻辑指令
(一)逻辑运算指令(AND、OR、NOT、XOR、TEST)
1、逻辑运算指令:AND、OR、NOT、XOR
逻辑“与”指令:
AND DEST,SRC
逻辑“或”指令:
OR DEST,SRC
逻辑“异或”指令:
XOR DEST,SRC
逻辑“非”指令:
NOT DEST
这4条指令都是执行按位逻辑运算,如下表所示
DEST|SRC|AND|OR|XOR|NOT
- | - | - | - | -| -
0 | 0 |0|0|0|1
0 | 1 |0|1|1|1
1 | 0 |0|1|1|0
1 | 1 |1|1|1|0
注意事项:
- DEST和SRC可以是8位或16位的通用寄存器或存储器操作数
- DEST和SRC不能同时为存储器操作数
- SRC 可以为立即数
- NOT指令对标志无影响
- AND、OR、XOR指令将根据结果影响SF、ZF和PF,而CF和OF总是置0,AF为不确定
- 逻辑运算指令除用来实现各种逻辑运算之外,还常用于对字节或字数据的某些位的组合、分离或位设置
例1:
AND AH,0F0H; 分离出AH中的高4位
AND AH,0FH; 分离出AH中的低4位
OR AH,01H; 将AH中最低位置1
AND AL,7FH; 将AL的最高位置0
XOR AX,0FFH; 将AX的低字节变反
XOR BX,8000H; 将BX的符号位变反
例2:下面的程序段将中断标志位IF清0,其它标志位保持不变
PUSHF; 将标志寄存器压栈
POP AX; 将栈中的标志字送AX
AND AX,0FDFFH; 将AX的第9位清0
PUSH AX; 将第9位清0后的AX内容压栈
POPF; 将堆栈中的值返回到标志寄存器
2、测试指令:TEST
指令格式:TEST DEST,SRC
功能:该指令的功能与AND指令相似,实现源操作数与目的操作数进行按位“逻辑与”运算,对标志位的影响与AND指令相同,但运算的结果不送入目的操作数,即目的操作数内容也将保持不变
注意事项:
- TEST指令主要用于测试某一操作数的一位或几位的状态
例1
TEST AL,01
JZ ZERO
.......
ZERO: ......
该程序段检查AL寄存器的最低位是否为0,如果为0,则程序转移到ZERO处执行
例2
LAHF
TEST AH,04H
JZ TARGET
该程序段检查标志寄存器的PF位(第2位)是否为0,如果为0,则执行后标志ZF为1。
因此通过测试ZF标志即可
(二)移位/循环移位指令(SHL、SHR、SAL、SAR、ROL、ROR、RCL、RCR)
1、算术移位:SAL、SAR
指令格式:
算术左移:SAL DEST,COUNT
算术右移:SAR DEST,COUNT
功能:
例1:
SAL AX,1;
将AX的内容左移1位,其中最高位移入CF中,而低位补0
例2:
MOV CL,2;
SAR AX,CL;
将AX的内容算术右移2位
例3:
MOV AL,11000000B; (AL)=-64
MOV BL,01111111B; (BL)=127
SAL AL, 1 ; (AL)=10000000B=-128,OF=0
SAL BL, 1 ; (BL)=11111110B=-2, OF=1
例4:
设AX中存放一个带符号数,若要实现 (AX) * 5 / 2,可由以下几条指令完成
MOV DX,AX
SAL AX,1
SAL AX,1
ADD AX,DX
SAR AX,1
注意事项:
- 指令SAL和SAR当移位次为n时,其作用相当于乘以2n或除以2n,因此被叫做算术移位指令
- 为了保持其算术运算结果的正确性,移位后的结果不能发生溢出
- 对于多字节或多字数据的移位,需要使用带进位循环移位指令
2、逻辑移位:SHL、SHR
指令格式:
逻辑左移:SHL DEST,COUNT
逻辑右移:SHR DEST,COUNT
功能:
逻辑左移SHL与算术左移SAL功能相同
例4:
MOV AL,10010011B;
SHL AL,1 ; 执行后CF标志为1
SAR AL,1 ; 执行后CF标志为0
3、循环移位:
指令格式:小循环
循环左移:ROL DEST,COUNT
循环右移:ROR DEST,COUNT
功能:
指令格式:大循环
带进位循环左移:RCL DEST,COUNT
带进位循环右移:RCR DEST,COUNT
功能:
注意事项:针对上述八个移位/循环移位指令
- DEST为操作对象,它可以是字节或字操作数,可以是通用寄存器或存储器操作数
- COUNT用来决定移位/循环的位数,即确定移位的次数
- 当移位次数为1时,使用常数1或寄存器CL
- 当移位次数大于1时,必须使用寄存器CL
- 在执行移位时,根据指令不同,每移位一次,最高 位(左移)或最低位(右移)都要送到进位标志CF
- 前4条移位指令根据移位结束后修改标志位CF、 PF、ZF、SF和OF,而AF不确定
- 而后4条循环移位指令根据移位结束后的结果仅修改CF和OF
- 对溢出标志位OF的影响:
- 移位次数为1时,移位前后操作数的符号位发生变化,则OF被置1,否则置0
- 移位次数大于1时, OF不确定
例6:
下面程序段对从存储单元M开始的三字数据执行左移一位
SAL M,1
RCL M+2,1
RCL M+4,1
下面的程序段实现将上述三字数据右移一位
SAR M+4,1
RCR M+2,1
RCR M,1
四、串处理指令
(一)重复指令前缀(REP、REPE/REPZ、REPNE/REPNZ)
(二)串指令(MOVS、CMPS、SCAS、STOS、LODS)
五、控制转移指令
(一)无条件转移、调用和返回指令(JMP、CALL)
(二)条件转移指令
(三)循环控制指令
六、处理器控制指令
(一)标志位操作指令(CLC、STC、CMC、CLD、STD、CLI、STI)
功能 | 指令格式 | 执行结果 |
---|---|---|
清除进位标志 | CLC | 置CF为0 |
置1进位标志 | STC | 置CF为1 |
进位标志取反 | CMC | CF的值取反 |
清除方向标志 | CLD | 置DF为0 |
置1方向标志 | STD | 置DF为1 |
清除中断标志 | CLI | 置IF为0 |
置1中断标志 | STI | 置IF为1 |
注意事项:
- 它们都是无操作数指令,操作数隐含为标志寄存器的某个标志位
- 能直接操作的标志位有CF、IF和DF
(二)与外部事件同步的指令(HLT、WAIT、ESC、LOCK)
指令格式 | 功能 |
---|---|
HLT | 暂停指令 |
WAIT | 等待指令 |
ESC | 外部协处理器指令前缀 |
LOCK | 总线锁定指令 |
(三)空操作指令(NOP)
指令格式:NOP
注意事项:
- 执行一次NOP占用CPU三个时钟周期,它不改变任何寄存器或存储单元内容,主要用于延时