欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

8086指令系统

程序员文章站 2024-01-30 23:35:46
...

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指令执行过程:

  1. SP=SP-2;
  2. SP+1,存入高字节
  3. 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

若:AXBXAX\geq BX,则CF=0;

若:AXBXAX\leq BX,则CF=1;

若:AX=BXAX=BX,则CF=0;ZF=1

对于两个有符号数的比较

CMP AX,BX

两个数的大小由OF和SF共同决定

若:OF和SF相同:AXBXAX\geq BX

若:OF和SF不相同:AX<BXAX< BX

求补指令: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. 对两个数取补码(对负数取反,加1)
  2. 乘法运算
  3. 将结果去补码

无符号除法指令: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

操作:两个操作数按位与,结果放到目标地址

应用:

  1. 实现两个数按位与
  2. 使目标操作数某些位不变,其余为清零

AND AL OFH,AL的高四位清零,第四位不变

  1. 在操作数不变的情况下,使CF,OF清零

AND AX ,AX,AX 不会发生变化,CF=OF=0

或运算:OR

格式:OR OPRD1,OPRD2

操作:两个操作数按位或,结果放到目标地址

应用:

  1. 实现两个数按位或
  2. 使某些位不变,某些位置1

OR CL,0FH:cl的高四位不变,低四位置1

  1. 在操作数不变的情况下,使CF,OF清零

OR AX ,AX,AX 不会发生变化,CF=OF=0

非运算:NOT

格式:NOT OPRD

操作:操作数按位去反再送回原地址

注意:

  • OPRD 不能是立即数
  • 执行的执行对标志位没有影响

如:NOT BYTE PRT[BX]

异或指令:XOR

格式:XOR OPRD1,OPRD2

操作:两个操作数按位异或,结果放到目标地址

应用:

  1. 实现异或运算:XOR AX,80H
  2. 清零: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

过程调用

调用一个子程序

  • 子程序执行结束后要返回原调用处
  • 必须保护返回地址

执行过程:

  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

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)
相关标签: 微机原理