8086指令系统
8086指令系统
文章目录
数据传输指令
通用数据传送(对标志位没有影响)
一般数据传送指令
格式:MOV dest,src
将str(源操作数)送到dest(目的操作数)中
如:MOV AL,BL
注意:
- 两个操作数字长必须相同
- 两个操作数不能同时为存储器操作数
- 两个操作数不能同时为段寄存器( CS,DS,ES,SS)
- 如果源操作数为立即数,目标操作数不能是段寄存器
如(都是错的)
MOV AL,BX ; 两个操作数不等字长
MOV [BX][BP],Bx ;没有基址,基址寻址方式
MOV DS,1000H ;源操作数为立即数,目标操作数不能是段寄存器
MOV [1200],[SI] ; 两个操作数不能同时为段寄存器
堆栈操作指令
原则:
- 先进后出
- 以字为单位:两个字节
压栈指令:
- 格式:PUSH 16位寄存器或者存储器两个单元
出栈指令:
- 格式:POP 16位寄存器或者存储器两个单元
PUSH指令执行过程:
- SP=SP-2;
- SP+1,存入高字节
- SP,存入低字节
如:设AX=1234H,SP=1200H;执行PUSH AX
指令后堆栈取的状态:
SP=12FEH
(12FFH)=12H
(12FEH)=24H
POP指令执行过程:
SP:弹出低字节
SP+1:弹出高字节
SP=SP+2;
注意:
-
操作数必须为16位
-
操作数可以是寄存器,存储单元。不能是立即数
交换指令
XCHG REG,MEM/REG
注意:
- 两个操作数必须有一个是寄存器操作数
- 不准使用段寄存器(DS,ES,CS,SS)
如:
XCHG AX,BX
XHNG [2000],CL
查表指令
格式:XLAT
说明:用BX表示表格首地址,AL的内容表示表内偏移量。BX+AL得到要查找元素的偏移地址
操作:将BX+AL所指的单元里的内容放到AL中
字位扩展指令
将有符号数的符号位扩展到最高位
格式:CBW(扩展到一个字节)
操作:将AL的内容扩展到AX
规则:
- 若最高位为1,则AH=FFH
- 若最高位为0,则AH=00F
格式:CWD (将一个字节扩展到一个字)
操作:将AX的内容扩展到DX AX
- 若最高位为1,则DX=FFFFH
- 若最高位为0,则DX=0000F
地址传送指令
LEA指令
操作:将变量的16位偏移地址写入目标寄存器
当程序中用符号表示内存偏移地址时,必须使用该指令
格式:LEA REG,MEM
指令要求 :
- 源操作数必须是一个存储器操作数,目标操作数通常是间址寄存器(BX,BP,DI,SI)
MOV和LEA指令对比。
假设声明一个偏移地址的变量i,其里面的内容为5,则:
MOV AL i ;AL=5
MOV BX i; ;BX=i;
标志传送指令
指令;LAHF
操作:将FLAGS的低八位转入AH中
指令:SAHF
操作:将AH转入FLAGS中
输入输出指令
功能:
- 从端口地址读入到累加器或者将累加器的值输出到端口中
格式:
- 输入指令:
IN acc,PORT
- 输出指令:
OUT PORT,acc
PORT :端口地址
acc:累加器:AL或者AX
寻址方式:
直接寻址:
- 端口地址为8位,指令中直接给出端口地址 。可以寻256个端口
间接寻址:
- 端口地址为16位。指令中的端口地址必须放在DX中,可以寻址64K
IN AX,80H ;从80H端口读入16bit的数据到AX
MOV DX,2400H
IN AL,DX ;从2400H端口读入8bit的数据到AL中
OUT 35H,AX ;将16bit的数据写到35H端口
OUT AX,35H ;格式错误
算数运算指令(大多数对状态标志位产生影响)
加法运算指令
- 普通加法指令:ADD
- 带进位的加法指令:ADC
- 加1指令:INC
普通加法指令:ADD
格式:ADD OPRD1,OPRRD2
操作:将OPRD1+OPRD2的结果放到OPRD1中
ADD指令的执行对全部6个状态标志位都有影响
MOV AL,78H
ADD AL,99H
;AL=11H
;状态标志符:CF=1,AF=1,SF=0,OF=0,ZF=0,PF=1
带进位的加法指令:ADC
格式:ADD OPRD1,OPRRD2
操作:将OPRD1+OPRD2+CF的结果放到OPRD1中
ADC指令多用于多字节相加,使用前将CF清零
加1指令:INC
INC OPRD
OPRD 不能是段寄存器,不能是立即数
操作:将OPRD+1再送回OPRD
INC指令的执行不影响CF,但会影响其余5个状态标志位
常用于在程序中修改指令
应用:求内存数据段中M1为首和M2为首的2个20个字节数之和。并将结果写到以M2为首的区域中
LEA SI,M1
LEA DI,M2
MOV CX,20
CLC CF
NEXT:MOVE AL,[SI]
ADC [D1],AL
INC SI
INC DI
DEC CX
JNZ NEXT
HIL
减法指令
- 普通减法指令:SUB
- 考虑到借位的减法指令:SBB
- 减1指令:DEC
- 比较指令:CMP
- 求补指令:NEG
普通减法指令:SUB
格式:SUB OPRD1,OPRD2
操作:OPRD1-OPRD2,其结果放在OPRD1
ADD指令的执行对全部6个状态标志位都有影响
考虑到借位的减法指令:SBB
格式:SBB OPRD1,OPRD2
操作:OPRD1-OPRD2-CF,其结果放在OPRD1
减1指令:DEC
格式:DEC OPRD1
操作:OPRD1-1,其结果放在OPRD1
DEC指令的执行不影响CF,但会影响其余5个状态标志位
MOV BL,2
NEXT1:MOV CX,0FFFF ;立即数首字母为a到f时,需要加0
NEXT2:DEC CX
JNZ NEXT2 ;ZF=0转NEXT2
DEC BL
JNZ NEXT1 ;ZF=0转NEXT1
HIL
比较指令:CMP
格式:CMP OPRD1,OPRD2`
操作:OPRD1-OPRD2,其结果不放回
指令执行的结果不影响操作数,只影响标志位
用途:比较两个数的大小
对于两个无符号数的比较:
CMP AX,BX
若:,则CF=0;
若:,则CF=1;
若:,则CF=0;ZF=1
对于两个有符号数的比较:
CMP AX,BX
两个数的大小由OF和SF共同决定
若:OF和SF相同:
若:OF和SF不相同:
求补指令:NEG
格式:NEG OPRD
操作:0-OPRD,其结果放在OPPD中
对一个负数求补码,相当于用零减去这个数
说明:
- 执行NEG指令,一般情况下CF等于1,除非OPRD=0,则CF=1
- 若:OPRD=80H,或者OPRD=8000H
- 用0减去操作数,可以得到这个数的绝对值
### 乘除运算
- 无符号乘法指令:MUL
- 带符号乘法指令:IMUL
- 无符号除法指令:DIV
- 有符号除法指令:IDIV
乘法指令采用隐函数寻址,隐含了存放被乘数的累加器AL,AX;以及存放结果的AX或者AX,DX
除法要求被除数是除数的双倍字长
无符号数指令:MUL
格式:MUL OPRD
操作:
- OPRD为字节数:AL*OPRD,其结果放在AX中
- OPRD为两个字节数:AX*OPRD,其结果放在DXAX中
如:MUL BYTE PTR[BX]
AX*(BX地址里面的内容)
带符号数指令:IMUL
格式:lMUL OPRD
执行原理:
- 对两个数取补码(对负数取反,加1)
- 乘法运算
- 将结果去补码
无符号除法指令:DIV,有符号除法指令:IDIV
格式:DIV OPRD
格式:lDIV OPRD
若:OPRD为字节数
执行:AX/OPRD
结果:AL=商,AH=余数
若:OPRD为双字节数
执行:DXAX/OPRD
结果:Ax=商,DX=余数
所有单操作数:如果操作对象为存储器的话,需要声明字长(PTR)
逻辑运算
对标志位的影响
- 除“非”运算指令,其他指令都会影响AF之外的其他状态指令
- 无论结果如何,都会使标志位OF=CF=0
- 非运算指令对所有状态标志位都没有影响
与指令:AND
格式:AND OPRD1,OPRD2
操作:两个操作数按位与,结果放到目标地址
应用:
- 实现两个数按位与
- 使目标操作数某些位不变,其余为清零
AND AL OFH
,AL的高四位清零,第四位不变
- 在操作数不变的情况下,使CF,OF清零
AND AX ,AX
,AX 不会发生变化,CF=OF=0
或运算:OR
格式:OR OPRD1,OPRD2
操作:两个操作数按位或,结果放到目标地址
应用:
- 实现两个数按位或
- 使某些位不变,某些位置1
OR CL,0FH
:cl的高四位不变,低四位置1
- 在操作数不变的情况下,使CF,OF清零
OR AX ,AX
,AX 不会发生变化,CF=OF=0
非运算:NOT
格式:NOT OPRD
操作:操作数按位去反再送回原地址
注意:
- OPRD 不能是立即数
- 执行的执行对标志位没有影响
如:NOT BYTE PRT[BX]
异或指令:XOR
格式:XOR OPRD1,OPRD2
操作:两个操作数按位异或,结果放到目标地址
应用:
- 实现异或运算:
XOR AX,80H
- 清零:
XOR AX,AX
AX=0;
测试指令:TEST
格式:TEST OPRD1,OPRD2`
操作:两个操作数按位与,结果不要了
应用:
- 常用于测试某些位的状态
移位操作指令
要求:
- 操作数不能是立即数
- 移动一位时,可以直接给出;移动多位时,移动次数由CL给出
非循环移位指令
逻辑左移:SHL(无符号数)
SHL OPRD 1
SHL OPRD Cl
原理:最高位移到CF,最低位补零
算术左移:SAL(有符号数)
SAL OPRD 1
SAL OPRD CL
原理:最高位移到CF,最低位补零
逻辑右移SHR(无符号数)
SHR OPRD 1
SHR OPRD CL
原理:最低位移到CF,最高位补零
MOV AL,68H
MOV CL,2
SHR AL,CL;结果:AL=1aH,CF=0
算术右移SAR(有符号数)
SAR OPRD 1
SAR OPRD CL
原理:最低位移到CF,符号位不变,其他位,正常移动
MOV AL,E8
SAR AL,1
;结果:AL=F4,CF=0;
应用:
- 左移指令实现乘法
- 右移指令实现除法
循环移位
不带进位的循环移位:ROL,ROR
左移:最高位移到CF,同时也移到最低位
右移:最低位移到CF,同时也移到最高位
带进位的循环移位:RCL,RCR
左移:先把CF里面的值移到最低位,在把最高位移到CF
右移:先把CF里面的值移到最高位,在把最低位移到CF
作用:
- 用于某些位的状态测试
- 低位部分和高位部分的交换
- 与非循环移位指令一起组成32位或者更长位数的移位
应用:在内存数据段M1位首地址的4个单元存放了4个压缩的BCD码,将其转换为ASCII码,并将结果存在M2为首的单元。
LEA SI,M1
LEA DI,M2
MOV CH,4
NEXT:MOV AL,[M1]
MOV BL,AL
AND AL,0F
OR AL,30H
MOV [DI],AL
INC DI
MOV AL,BL
MOV CL,4
SHR AL,CL
OR AL,30
MOV [DI],AL
INC DI
INC SI
DEC CH
JNZ NEXT
HIL
串操作指令
- 针对于数据块或者字符串
- 可以实现存储器到存储器的数据传送
- 待操作的数据串叫源串,目标操作数叫目标串
指令的执行需要确定
- 串的区域
- 串的首地址(源串,目标串)
- 串的长度
- 串的操作方向
要求
- 源串一般存放在数据段偏移地址由SI指定
- 目标串必须在附加段,偏移地址由DI指定
- 串的长度由CX指定
- 串的操作方向:由DF的标准为决定:DF=0,增地址;DF=1,减地址方向
无条件重复前缀:REP
当CX不等于0,REP后的指令将继续重复执行
相等或者为零重复:REPE(REPZ)相等(为零)
CX不等于0并且ZF=1,则前缀后的指令将继续重复执行
不等或者不为零重复:REPNE(REPNZ)
CX不等于零并且ZF=0,则前缀后的指令将继续重复执行
- 若按增地址方向传送,串操作结束时
- 串传送指令:指针指向尾串+1
- 串比较指令:指针指向结束位+1
- 若按减地址方向传送,串操作结束时
- 串传送指令:指针指向尾串-1
- 串比较指令:指针指向结束位-1
串传送MOVS
格式:MOVS OPRD1,OPRD2
MOVSB
:按字节传送
MOVSW
:按字传送
只能添加无重复前缀:REP
应用:
分别使用MOV和MOVS指令完成将200个字节数据从内存数据段MEM1位首的地址传送到同意逻辑段MEM2位首地址的 区域
使用MOV
LEA SI,MEM1
LEA DI,MEM2
MOV CX,200
NEXT:MOV BL,[SI]
MOV [DS],BL
INC SI
INC DI
DEC CX
JNZ NEXT
HIL
使用MOVS
LEA SI,MEM1
LEA DI,MEM2
MOV CX,200
CLD ;清零DF,按增地址的方向传递
REP MOVSB
串比较CMPS
功能:实现两个串的比较
操作:目标串-源串,结果不用写回目标地址
常和条件条件重复前缀连用
格式:
CMPSB
:按字节比较
CMPW
:按字比较
应用:测试前面传送200个字节是否有误
LEA SI,MEM1
LEA DI,MEM2
MOV CX,200
CLD
REPE CMPSB
JZ STOP;两个串相同,结束
DEC CX ;两个字符串不相等,重新传递
MOV AL,[SI]
MOV [DI],AL
STOP:HIL
比较结束条件
- CX=0:
- cx不等于0,但是ZF=0:
串扫描SCAS
功能:常用于在指定存储区域寻找关键字。进行减操作
格式:SCAS OPRD
SCASB
SCASW
源操作数:AX或者AL
应用:
在ES段中从2000H单元开始存放10个字符,去找其中有无字符A。若有记录搜索次数,将搜索次数写到DATA1 单元,并将A存放到DATA2单元
MOV DI,2000H
MOV BX,DI
MOV CX 10
MOV AL 'A'
CLD
REPNE SCASB
JZ FOUND
MOV DI,0
JMP DONE
FOUND:DEC DI
MOV DATA2,DI
INC DI
SUB DI,BX
DONE: MOV DATA1,DI
HIL
通过状态标志位ZF表现比较的值
串装入LODS
格式:
LODs OPRD
LORSB
LODSW
操作:将数据段[DS:SI]中的内容送入AL或者AX中
用处:
- 用于将内存中的某个区域的数据串依次装入累加器,以便显示或者输出到接口
- LODS指令一般不加重复前缀
串送存STOS
格式:
STOS OPRD
STOSB
STOSW
操作:将AL或者AX的数据依次装入附加段[ES:DI]
用处:将内存某个区域设置为同一个值
此时:
- 将待存入的数据放入AL或者AX中
- 确定操作方向(DF),区域大小(CX)
- 使用串存储指令加无条件重复前缀,实现数据传送
串操作的注意:
- 需要定义附加段:目标操作数放在附加段
- 需要设置操作方向
- 源串指针由SI给出,目标串指针由DI给出,长度由 CX确定,操作方向有DF确定
控制类指令
通过修改CS,IP的值,使程序的操作顺序改变
转移指令
通过修改指令的偏移地址或者段地址和偏移地址实现程序转移
无条件转移指令:JMP
JMP OPTR
若:OPRD和JPM在同一代码段,叫做段内转移
OPRD和JPM在不同代码段,叫做段间转移
段内直接转移:指令中直接给出目标地址
JMP Label
Label :进地址标号
段内间接转移:由指令中的寄存器或者存储器(两个单元)操作数指出目标地址
MOV BX,1200H
JMP BX
;执行后IP=1200H
MOV BX,1200
JMP WORD PRT[BX]
;
无条件段间转移:目标地址为32位,包括段地址和偏移地址
段间直接转移:指令中直接给出目标地址
JMP FAR Label
FAR Label:远地址标号
段间间接转移:由四个内存单元指出目标地址
JMP DWORD PRT[BX]
地址单元:IP 高地址单元:CS
应用:
MOV SI,1122H
MOV WORD PTR[SI],0120H ;[1122H]=20H,[1123H]=01H
ADD SI,2
MOV WORD PTR[SI],0122H;[1123H]=22H;[1124H]=01H
JMP WORD PTR[SI];IP=0122H
JMP DWORD PTR[SI-1];IP=0120H;CS=0122H
有条件转移指令
条件转移都是短转移,转移范围:-128到127
-
JC/JNC:判断CF的状态。常用于两个无符号数的比较。
-
Jz/JNZ:判断ZF的状态。常用于循环体结束判断
-
JO/JNO:判断OF的状态。常用于有符号数溢出判断
-
JP/JNP:判断PF。用于判断运算结果低八位中1的个数是否为偶数
-
JS/JNS:判断SF的状态,常用于判断数的性质
-
JA或者JB:判断CF或者CF+ZF状态。常用于无符号数的比较
-
JG/JL:判断SF+OF或者SF+OF+ZF的状态,常用于有符号数的大小比较
-
JCXZ:根据指令执行后CX的结果实现转移
应用:
统计内存数据段中以TABLE为首地址的100个8位带符号数中的正数,负数,零的个数。
START:XOR AL,AL
MOV PLUS,AL
MOV MINUS,AL
MOV ZERO,AL
LEA SI,TABLE
MOV CX,100
CLD
CHECK:LODSB
OR AL,AL
JS X1
JZ X2
INC PLUS
JMP:NEXT
X1:INC MINUS
JMP:NEXT
X2:INC ZERO
JMP:NEXT
NEXT:DEC CX
JNZ:CHECK
HIL
循环指令
循环范围:以当前IP为中心的-128到+127范围内循环
循环次数:有CX指定
无条件循环指令:LOOP
格式:LOOP LABLE
循环条件:CX不等于0
相当于DEC CX + JNZ 符号地址
条件循环指令:LOOPZ,LOOPNZ
功能:先使CX-1,再根据CX中的值以及ZF的值判断是否循环
LOOPZ LABLE
:继续循环的条件:CX不等于0,并且ZF=1
LOOPNZ LABLE
:继续循环的条件:CX不等于0,并且ZF=0
应用:
在以DATA为首地址的数据段中,存放有200个16位有符号数,找出其中最大和最小值,并分别放在MAX和MIN位首的内存单元中
START:LEA SI,DATA
MOV CX,20
CLD
LODSW
MOV MAX,AX
MOV MIN,AX
DEC CX
NEXT:LODSW
CMP AX,MAX
JG LARGE
CMP AX,MIN
JG SMALL
JMP GOON
LARGE:MOV MAX,AX
JMP GOON
SMALL:MOV MIN,AX
JMP GOON
GOON:LOOP NEXT
过程调用
调用一个子程序
- 子程序执行结束后要返回原调用处
- 必须保护返回地址
执行过程:
- 将调用指令的下一条指令地址压入堆栈
- 获取子程序的入口地址:子程序的第一条指令地址
- 执行子过程
- 返回原程序,将断点地址由堆栈弹出
段内调用:CALL
需要保护的只有偏移地址
call FAR TIMRE
段间调用:
需要保护的是偏移地址+段基地址
先将断点的CS压入,再压入IP
CALL DWORD PRT[SI]
:32位操作数
返回指令:RET
子程序的最后一条指令必须是RET
中断控制
- 中断处理都是远过程调用:需要保护段基地址+偏移地址
- 还要保护FLAGS的内容
格式:INT n
n 是中断类型码
中断向量表:255*4=1K的空间,每四个地址构成一个中断类型码。说明n的范围:0到255。其中前两个地址放入口的偏移地址,后两个地址放段基地址。该单元位于数据段,段地址=DS
执行过程:
- 将FLAGS压入堆栈
- 将INT指令的下一条指令的CS,IP压入堆栈
- 由n*4得到存放中断向量的地址
- 将中断向量的地址送入CS和IP寄存器
- 转入 中断程序
返回指令:IRET
处理器控制指令
对标志位的操作:
操作指令 | 影响 |
---|---|
CLC | cf清零 |
STC | CF置1 |
CMC | CF 取反 |
CLD | 请方向标志位 |
STD | 方向标志位置一 |
CLI | 清中断标志位 |
STI | 中断标志置1 |
MAX,AX
JMP GOON
SMALL:MOV MIN,AX
JMP GOON
GOON:LOOP NEXT
#### 过程调用
**调用一个子程序**
* 子程序执行结束后要返回原调用处
* 必须保护返回地址
执行过程:
1. 将调用指令的下一条指令地址压入堆栈
2. 获取子程序的入口地址:子程序的第一条指令地址
3. 执行子过程
4. 返回原程序,将断点地址由堆栈弹出
##### 段内调用:CALL
需要保护的只有偏移地址
`call FAR TIMRE`
##### 段间调用:
需要保护的是偏移地址+段基地址
先将断点的CS压入,再压入IP
`CALL DWORD PRT[SI]`:32位操作数
##### 返回指令:RET
**子程序的最后一条指令必须是RET**
#### 中断控制
* 中断处理都是远过程调用:需要保护段基地址+偏移地址
* 还要保护FLAGS的内容
格式:`INT n`
n 是中断类型码
中断向量表:255*4=1K的空间,每四个地址构成一个中断类型码。说明n的范围:0到255。其中前两个地址放入口的偏移地址,后两个地址放段基地址。该单元位于数据段,段地址=DS
执行过程:
1. 将FLAGS压入堆栈
2. 将INT指令的下一条指令的CS,IP压入堆栈
3. 由n*4得到存放中断向量的地址
4. 将中断向量的地址送入CS和IP寄存器
5. 转入 中断程序
##### 返回指令:IRET
### 处理器控制指令
#### 对标志位的操作:
| 操作指令 | 影响 |
| -------- | -------------- |
| CLC | cf清零 |
| STC | CF置1 |
| CMC | CF 取反 |
| CLD | 请方向标志位 |
| STD | 方向标志位置一 |
| CLI | 清中断标志位 |
| STI | 中断标志置1 |
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200229151649950.jpg?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQwMjYyMzU3,size_16,color_FFFFFF,t_70)
推荐阅读
-
8086指令系统
-
纪念x86诞生40周年 万元级i7-8086K配GTX1080配置推荐
-
i7 8086k用什么主板好 适合搭配intel酷睿i7-8086K处理器的主板推荐
-
1.5万元i7-8086K搭RTX2080发烧主机配置推荐 RGB信仰情怀加持
-
i7-8086K是钎焊散热吗 i7-8086K开盖揭秘
-
Vue.js每天必学之指令系统与自定义指令
-
i7 8086k怎么样 Intel酷睿i7-8086K处理器详细评测
-
1.2万Intel i7-8086K信仰主机配置推荐 高端超频水冷电脑装机方案
-
酷睿i7 8086K配什么显卡好 适合搭配i7-8086K处理器的显卡推荐
-
AMD锐龙7 2700X和Intel Core i7-8086K哪款值得买 两款CPU对比评测