8086指令系统(8086基本知识点)
8086
目录
2.1LEA(Load Effective Address)
4.2加法指令(带进位位)ADC(ADD with Carry)
4.5 减法指令(考虑借位)SBB(Substract with Borrow)
4.13 BCD码加法调整指令DAA(Decimal Adjust for Addition)
4.14 BCD码减法调整指令DAS(Decimal Adjust for Substraction)
7.1 字符串传送指令MOVSB(Move String Byte)与MOVSW
7.3 字符串检索指令SCASB(Scan String Byte)与SCASW
7.4 字符串转移指令LODSB(Load String Byte)与LODSW
8.5 循环控制指令LOOP,LOOPZ/LOOPE,LOOPNZ/LOOPNE
一.指令的寻址
1 操作数寻址
1.1 立即数寻址
MOV CL,05H
1.2 寄存器寻址
MOV AX,BX
1.3 直接寻址
MOV AX,[3100H]
1.4 寄存器间接寻址
寄存器可以为BX,BP,SI,DI,BP的默认段为SS,BP中存放的一般是要访问数据的偏移量,其余默认段为DS ,需要修改段需要加前缀说明
MOV BX,[DI]
1.5 寄存器相对寻址
有效地址EA由寄存器加偏移量产生,寄存器同上可以为BX,BP,SI,DI
例如假设表格首地址为COUNT(BX为基址寄存器,SI为变址寄存器)
MOV SI,n-1
-------------------------------------
MOV AL,[SI+COUNT]
或者
MOV BX COUNT
MOV AX,[SI][BX]
可以用来定位表格第n项元素
假设MASK为栈首地址道数组首地址的位移量,可以利用MASK+BP+SI(BP里存放栈顶值,SI中存放栈顶偏移量,栈底到栈顶地址逐渐减小)
1.6 隐含寄存器的操作数
例如乘法指令
MUL CL
隐含AL寄存器,结果存放在AX中
2 指令地址寻址
如无条件转移指令JMP
二.8086指令系统
1 数据传送指令
1.1通用传送指令MOV
两个操作数可以都是寄存器,一个寄存器一个内存地址,或者源操作数是立即数,目的操作数是寄存器或者内存地址
特殊情况:
CS:IP指向下一条将要执行的指令,二者不能作为目的操作数,只能作为源操作数
不能将立即数传给段寄存器,段寄存器之间也不能直接互相传值,中间需要某个通用寄存器过渡
内存单元不能同时作为源操作数与目的操作数
1.2堆栈操作指令PUSH与POP
两个指令后直接加操作数,压栈与弹栈都是按照字节操作,压栈与弹栈影响SP的值,压栈SP-2,弹栈SP+2
特殊情况:
CS值可以压栈,栈中除断点以外的值不能弹入CS
1.3交换指令 XCHG
XCHG OP1,OP2
特殊情况:
二者不能同时为内存单元地址,不能为段寄存器,不能为立即数
不能出现CS与IP
目的操作数与源操作数的位数相同
1.4换码指令 XLAT(Translate)
该指令在内存中有码表的情况下对AX与BX进行操作,BX存码表首地址,AX存偏移量,结果存入AX中
首先给AX与BX传入数据(DISP_TABLE为表的标号)
MOV BX,OFFSET DISP_TABLE
MOV AL,5
然后直接写出语句即可
XLAT
1.5输入输出指令IN与OUT
只能使用累加器作为传送数据的寄存器,AL供8位端口传送,AX供16位端口(可以理解为接口中的寄存器)传送,每个8位端口都有一个地址,被称为端口号,相邻两个8位端口组成16位端口,PC机仅用10位地址线(A0~A9)译码,A9为0(000H~1FFH)用作主机板IO译码,A9为1(200H~3FFH)用作扩展板IO译码,如硬盘适配器内部的寄存器编码
端口号在00H~FFH范围内的端口,采用直接输入输出指令,例如:
IN AL,44H
端口号在FFH以上的端口,采用间接输入输出指令,只用DX作为间接寻址的寄存器,可以扩大寻址范围,例如:
MOV DX,3FCH
IN AX,DX
2地址传送指令
2.1LEA(Load Effective Address)
将某一内存单元的地址送入某一寄存器,例如:
MOV BX,OFFSET DISP_TABLE
与
LEA BX,DISP_TABLE
2.2LDS(LOAD into DS)
将4B的内存单元低两个字节作为偏移量送入某一个寄存器,高两个字节作为段地址送入DS,例如:
LDS DI,[2130H]
2.3LES(LOAD into ES)
与上一条指令同理,只不过将高两位字节作为段地址送入ES,例如:
LES ES,[2130H]
3 标志传送指令
标志寄存器内部重要位的意义:
CF,PF,AF,ZF,SF,OF为状态标志,TF,IF,DF为控制标志,是人为设置的
标志寄存器总共16位,有七位没有用到,剩下9位的意义如下:
CF(Carry Flag):进位标志
PF(Parity Flag):运算结果低8位是否为偶数
AF(Auxiliary Carry Flag):辅助进位标志,表示前四位是否对后四位有进位,用于BCD码调整
ZF(Zero Flag):零标志
SF(Sign Flag):运算结果的最高位
OF(Overflow Flag):溢出标志
DF(Direction Flag):控制串操作方向的标志,DF为0自增
IF(Intrrupt Flag):可屏蔽中断标志,IF=1允许中断
TF(Trap Flag):跟踪标志,为1的话CPU以跟踪方式运行,用于程序调试
3.1 LAHF(Load AH with Flags)
3.2 SAHF(Store AH onto Flags)
3.3 PUSHF
用于子程序和标志处理子程序保护标志寄存器的过程
3.4 POPF
4 算数运算指令
4.1加法指令(不带进位位)ADD
ADD OP1,OP2
有符号数与无符号数的加减运算可以使用同一套指令系统
有符号数溢出用OF位判断,无符号数溢出用CF位判断
4.2加法指令(带进位位)ADC(ADD with Carry)
OP2+OP1+CF->OP1
例:进位加法
MOV SI,2000H
MOV AX,[SI]
MOV DI,3000H
ADD AX,[DI]
MOV [SI],AX
MOV AX,[SI+2]
ADC AX,[DI+2]
MOV [SI+2],AX
4.3 增量指令INC(Increasment)
例如:
INC BYTE PTR [BX+DI+500]
4.4 减法指令(不考虑借位)SUB(Substract)
SUB OP1,OP2
例如:
SUB WORD PTR [DI],1000H
4.5 减法指令(考虑借位)SBB(Substract with Borrow)
4.6 减量指令(DEC)
例如:
DEC AX
4.7 求补指令NEG(Negate)
0-OP->OP
除非OP为1,否则0-OP必须借位,导致CF位一般为1
4.8 比较指令CMP
本质上是减法指令,但是结果不回送,只影响标志位
例如:
CMP OP1,OP2
若OP1=OP2
ZF位为0
无符号数判定大小,相减后观察CF标志
有符号数同号数相减后观察SF位
有符号数异号数相减后观察OF位与SF位,若OF=0,没有溢出的情况下,SF=0,OP1>OP2,反之OP1<OP2,若OF=1,在溢出情况下,SF=1,说明是正数减负数向正方向溢出,OP1>OP2,反之OP1<OP2,综上SF与OF相等时,OP1>OP2,SF与OF不等时,OP1<OP2
4.9 无符号数乘法指令MUL
两个8位操作数相乘,结果存入AX中
两个16位操作数相乘,结果存入AX与DX中
4.10 有符号数乘法指令IMUL
IMUL OP(另一个操作数隐含入AL或者AX中)
4.11 无符号数除法指令DIV
除法指令使用原则:
①除数必须为被除数一半长,被除数的位数不足时进行扩展
CBW(Convert Byte to Word)
CWD(Convert Word to Double Word)
②被除数放入AX中或者AX与DX中,DX为AX的扩展
③商放入AL/AX中,余数放入AH/DX中
④8086规定余数的符号与被除数相同
⑤商超过8位产生0中断
例如:DIV OP
4.12 有符号数除法指令IDIV
4.13 BCD码加法调整指令DAA(Decimal Adjust for Addition)
调整方法:将不正确的四位加0110B
调整对象:AF=1或CF=1或出现无效码
4.14 BCD码减法调整指令DAS(Decimal Adjust for Substraction)
4.15 非组合BCD码的调整
非组合BCD码:高四位为0,低四位表示十进制数
假如两位十进制数相加结果分别存放于AH与AL中,需要根据进位标志或者无效码决定是否给AL加上0000 0110B,是否给AH加进位值,如果AL经过调整,还需要将高四位置0,即AL&0FH
指令:
AAA(ASCII Adjust for Addition)
AAS(ASCII Adjust for Substract)
AAM(ASCII Adjust for Multiplication)
AAD(ASCII Adjust for Division)
5 逻辑运算指令
除了NOT指令外,其余的逻辑指令都会让CF与OF位清零,AF的值不变,并对SF,PF,ZF产生影响
5.1 逻辑与指令AND
AND OP1,OP2
5.2 逻辑或指令OR
OR OP1,OP2
5.3 逻辑异或指令XOR
XOR OP1,OP2
5.4 逻辑非指令NOT
NOT OP
5.5 测试指令TEST
TEST指令与AND指令执行相同的操作,只不过只改变标志位,后面一般接JNZ或者JZ指令,根据ZF的值判断是否转移
6 移位指令
移位指令只有移位次数为1时OF才有意义,移位后CF与最高位不同OF=1,否则OF=0
移位次数要么为1,要么放入CL中,例如
SAL AL,3
与
SAL AL,BL
都是无效指令
6.1 非循环移位指令
SAL(Shift Arithmetic Left)
SHL(Shift Logic Left)
SAR
SAR与IDIV指令的区别是SAR对负数向上舍入,IDIV对负数向下舍入
SHR
6.2 循环移位指令
ROL(Rotate Left)
RCL(Rotate Through CF Left)
ROR
RCR
例如:将1000H内存单元中的非组合BCD码转换为组合BCD码
MOV CL,4
MOV SI,1000H
MOV AX,WORD PTR[SI]
SHL AL,CL
SHR AX,CL
7 串操作指令
串操作指令是唯一一个允许源操作数与目的操作数都在内存中的一组指令
默认以SI作为源操作数指针寄存器,默认段为DS段
默认以DI作为目的操作数指针寄存器,默认段为ES段
串操作方向与DF有关,0增1减
字符串操作SI与DI加减1,字串操作SI与DI加减2
7.1 字符串传送指令MOVSB(Move String Byte)与MOVSW
MOV SI,1000H
MOV DI,2000H
MOV CX,100
CLD
K:MOVSB
DEC CX
JNZ K
7.2 字符串比较指令CMPSB与CMPSW
用于比较两个字符串
前缀1:REPE(Repeat Equal)或者REPZ,CX≠0并且ZF=1继续比较,寻找第一个不等元素
前缀2:REPNE或者REPNZ,CX≠0并且ZF=0继续比较,寻找第一个相等元素
例:
LEA SI,STR2
LEA DI,STR1
MOV CX,3
CLD
REPZ CMPSB
JZ MATCH
AND AL,0
HLT
MATCH:MOV AL,1
HLT
7.3 字符串检索指令SCASB(Scan String Byte)与SCASW
用于检索AL中的字符在串STR中的位置
前缀1:REPE(Repeat Equal)或者REPZ,CX≠0并且ZF=1继续比较,寻找第一个不等元素
前缀2:REPNE或者REPNZ,CX≠0并且ZF=0继续比较,寻找第一个相等元素
例:
LEA DI,STR
CLD
MOV CX,4
MOV BX,4
REPNZ SCANSB
JZ FND
OR BX,FFFFH
HLT
FND:SUB BX,CX
HLT
7.4 字符串转移指令LODSB(Load String Byte)与LODSW
功能是将DS:SI所指示的内存单元存入AL或者AX中
例:
CLD
MOV CL,5
MOV SI,0700H
MOV DI,SI
LI:LODSB
PUSH CX
处理过程(处理过程可能会影响CS寄存器,所以要压栈)
POP CX
DEC CX
MOV [DI],AL
JNZ LI
7.5 存字符串指令STOSB与STOSW
功能是将AL或者AX寄存器中的内容存入ES:DI对应的存储单元中
8 控制转移指令
8.1 指令寻址方式
段内直接转移:当前IP加位移量
段内简介转移:IP=寄存器内容所对应的内存单元
段间直接转移:需要同时指出CS值与IP值
段间间接转移:寄存器对应内存单元存放着新的段地址与段内偏移量
8.2 子程序调用及返回指令CALL
可以使用上述任何一种指令寻址方式,与RET指令配合使用,将CALL的下一条指令地址压入栈中,子程序出口使用RET语句弹出
例如:
CALL DWORD PTR[DI]
涉及4B一定是段间间接转移
8.3 子程序返回指令RET
RET后可以加参数n,n为偶数,返回后SP+n,因为子程序可能用到堆栈产生无用值
8.4 无条件转移指令JMP及各种条件转移指令
JE/JZ(ZF=1)
JNE/JNZ(ZF=0)
有符号数:(Greater and Less)(前有CMP指令)
JG/JNLE
JNG/JLE
JL/JNGE
JNL/JGE
无符号数:(Above and Below)
JB/JNAE
JNB/JAE
JA/JNBE
JNA/JBE
JS(SF==1)
JNS
JO(OF==1)
JNO
JP(PF==1)
JNP
例:
GETMAX:MOV BX,2000H
MOV AL,[BX]
MOV CX,14H
P1:INC BX
CMP AL,[BX]
JAE P2
MOV AL,[BX]
P2:DEC CX
JNZ P1
MOV BX,[2000H]
MOV [BX],AL
8.5 循环控制指令LOOP,LOOPZ/LOOPE,LOOPNZ/LOOPNE
只能使用段内直接转移,位移量只能是8位
LOOP BEGIN
与
DEC CX
JNZ BEGIN
等效
LOOPZ 指令在CX≠0且ZF=1的情况下循环
JCXZ指令可以用于跳过循环
例:
MOV CX,N
FND:REPNZ SCANSB
JE OK
JCXZ ENDF
OK:.....
JMP FND
ENDF:......
8.6 中断指令与中断返回指令INT(Interrupt)
INT n
n必须为立即数,对应内存中中断向量表里的中断向量(CS/IP)
终端处理程序最后一条指令为IRET,能正确地恢复断点与标志寄存器的值
中断向量表为000H到3FEH,一个类型占4B,分别为CS值与IP值
5个内部中断为专用中断向量
① 除数为0
②单步中断(程序调试)
③非可屏蔽中断
④断点中断(程序调试)
⑤溢出中断
8.7 处理器控制指令(不影响任何标志)
(1)HLT
CS:IP指向HLT的下一条指令,直到出现硬件中断或者复位操作才退出暂停状态
(2)空操作指令NOP(No Operate)
可以用作延时操作
(3)标志位操作指令
STC(Set Carry Flag):CF=1
CLC(Clear Carry Flag):CF=0
CMC(Complete Carry Flag):CF求反
STD(字符串处理方向)
CLD
STI(中断允许位)
CLI
(4)交权指令
ESC
启动协处理器工作,交给8087处理
(5)等待指令WAIT
TEST引脚有效,CPU结束等待状态执行下一条指令
(6)总线封锁指令LOCK
可以作为任何指令的前缀使得CPU的LOCK引脚有效,从而独占总线
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)