微机原理 第三章:8086指令系统


微机原理 第三章:8086指令系统

符号说明

①. (.)表示内容:(AL)=0000 1111B
②. [.]括号内为地址:[BX]代表以BX的内容为地址的存储单元的内容
③. EA:有效(偏移)地址;PA:实际(物理)地址,20位

3.1 指令的基本格式

指令的基本格式

3.2 寻址方式

寻址方式: 根据指令基本格式、CPU给出的指令表达方法寻得操作数来源

3.2.1 固定寻址

有一个操作数地址也固定的。

PUSH  AX 
POP BX

3.2.2 立即数寻址

MOV AL,C3H    ;执行后,(AL)=C3H 
MOV AX,2050H    ;执行后,(AX)=2050H

只允许源操作数为立即数,目的操作数必须是寄存器或存储器。

3.2.3 寄存器寻址

操作数存放在CPU的内部寄存器中。寄存器可以为源操作数,也可为目的操作数。

MOV  AX,BX    ;AX←BX

不允许将立即数传送到段寄存器(CS,DS,ES,SS)。

3.2.4 存储器寻址

3.2.4.1 直接寻址

指令中直接给出操作数的16位偏移地址(也称有效地址,EA)。

默认的段寄存器为DS, 但也可以显式地指定其他段寄存器, 此时这种指定称为段超越前缀

MOV AX, [2000H]    ;AX←DS:[2000H]
MOV AX, ES:[2000H]    ;AX←ES:[2000H]

3.2.4.2 寄存器间接寻址

MOV  AX,[BX]    ;AX←DS:[BX]

3.2.4.3 寄存器相对寻址

MOV AX,[SI+06H]
MOV AX,[SI]06H
MOV AX,06H[SI]    ;AX←DS:[SI+06H]
MOV AX,10H[BP]    ;AX←SS:[BP+10H]

3.2.4.4 基址变址寻址

MOV AX,[BX][SI]
MOV AX,[BX+SI]
MOV AX,DS:[BP][DI]

3.2.4.5 相对基址变址寻址

MOV AX,[BX+DI+6]
MOV AX,6[BX+DI]
MOV AX,6[BX][DI]    ;AX←DS:[BX+DI+6]

3.2.4.6 串寻址

仅在8086的串指令中使用。

源操作数逻辑地址为DS:SI;目的操作数逻辑地址ES:DI。

当执行串指令的重复操作时,根据设定的方向标志(DF),SI和DI会自动调整。

MOV SB    ;字节串传送 
MOV SW     ;字串传送

段寄存器使用规则

注意事项——不允许使用段超越前缀的情况:

1、与栈操作有关的命令(PUSH,POP…),使用SP作为偏移地址指针,只能使用SS作为段寄存器。

2、指令只能放在代码段中

3、串操作指令规定用DS:SI来指定源数据区,用ES:DI来定目的数据区;段超越前缀只能用于源而不能用于目的

3.2.4.7 I/O端口寻址

8086CPU与外设之间通过I/O接口芯片进行联系。

①. 直接端口寻址(双字节指令)

直接端口地址不能放于任何括号中,不能理解为立即数。

IN AL, 50H    ;把50H端口的字节数输入到AL,这是字节输入指令
IN AX, 60H    ;把60H,61H两个相邻端口的16位数据输入到AX

OUT PORT,AL    ;字节输出
OUT PORT,AX    ;字输出

②. 寄存器间接端口寻址(单字节指令)

当端口地址数大于255时,即地址>FFH时,必须先将端口地址存放于寄存器DX中,而且只能使用DX

MOV DX,383H    ;将端口地址383H放入DX
OUT DX,AL    ;将(AL)输出到(DX)所指的端口中

MOV DX,380H    ;将端口地址380H放入DX\\
IN  AX,DX

3.4 8086指令系统

3.4.1 数据传送类指令

3.4.1.1 通用传送指令

①. MOV指令

MOV dst,src    ;把源操作数(src)内容送入目的操作数(dst)
  • 通用寄存器传送
MOV AH,AL    ;AH←AL,字节传送
MOV BVAR,CH    ;BVAR←CH,字节传送
MOV AX,BX    ;AX←BX,字传送
MOV DS,AX    ;DS←AX,字传送
MOV [BX],AL    ;[BX]←AL,字节传送
  • 立即数传送
MOV CL,4    ;CL←4,字节传送
MOV DX,0FFH    ;DX←00FFH,字传送
MOV BVAR,0AH    ;字节传送
  • 存储器传送
MOV AL,[BX]    ;AL←DS:[BX]
MOV DX,[BP]    ;DX←SS:[BP]
MOV DX,[BP+4]    ;DX←SS:[BP+4]
MOV ES,[SI]    ;ES←DS:[SI]
  • 段寄存器传送
MOV [SI],DS;[SI]←DS
MOV AX,DS;AX←DS
MOV ES,AX;ES←AX

①. CS,IP不能作目的寄存器;

②. 不允许:段寄存器←段寄存器;

;解决方法:
MOV AX,DS 
MOV ES,AX

③. 不允许:段寄存器←立即数;

;解决方法:
MOV AX,DATA 
MOV DS,AX

④. 不允许:存储器←存储器;

;解决方法:
MOV AX,MEM1
MOV MEM2,AX

④. 源操作数与目的操作数类型要一致。

⑤. 目的操作数不能为立即数。

⑥. 以字母开头的常数要有前导0。

②. 堆栈操作指令

PUSH src
POP dst

①. 堆栈操作总是按进行,不允许对字节操作;

②. 不能从栈顶弹出一个字给CS;

③. 堆栈指针为SS:SP,SP永远指向栈顶;

④. 每执行一次入栈指令,(SP)自动减2。

3.4.1.2 累加器专用传送指令

①. 输入输出(I/O)指令

只限于用累加器AL或AX来传送信息。

1、输入指令IN

IN AL, 80H    ;(AL)←(80H端口)
IN AL, DX    ;(AL)←((DX))

2、输出指令OUT

OUT 68H,AX  ;(69H,68H)←(AX)
OUT DX,AL    ;((DX))←(AL)

在使用IN/OUT指令间接寻址时,要先用传送指令把I/O端口号设置到DX寄存器。

②. 换码(查表)指令

XLAT    ;(AL)←((BX)+(AL))
XLAT TABLE-NAME
;相当于:
    MOV AH,0
    ADD BX,AX
    MOV AL,[BX]

3.4.1.3 地址-目标传送指令

①. 有效地址送寄存器LEA

LEA:Load Effective Address

传送的是地址而不是内容

格式:

LEA r,src    ;r←src的EA
;将存储器操作数的有效地址传送至16位通用寄存器
LEA SP,[0502H]    ;执行后,使堆栈指针(SP)=0502H
LEA BX,[BP+SI]    ;执行后,BX中为(BP)+(SI)所指存储单元的EA

②. 指针送寄存器和DS的指令LDS

LDS: Load Pointer into DS

该指令完成一个32位地址指针的传送,通常指定SI作为寄存器r

LDS    r,src
;(r)←src的(EA),(DS)←src的(EA+2)

③. 指针送寄存器和ES的指令LES

LES: Load Pointer into ES

与LDS类似,不同在于用ES代替了DS, 且通常指定DI作为寄存器r。

LES r,src
;(r)←src的(EA),(ES)←src的(EA+2)

地址-目标传送指令要求源操作数必须是一个存储器操作数目的操作数r必须是一个16位的通用寄存器,不能是段寄存器。

3.4.2 算数运算类指令

无符号数和带符号数

有符号数的溢出(OF=1)是一种出错状态,在运算过程中应当避免

3.4.2.1 加法指令

①. 加指令ADD

格式:ADD  dst,src    ;(字或字节操作)
操作:dst <--(dst)+(src)

②. 带进位加指令ADC

格式:ADC dst,src
操作:dst<--(dst)+(src)+(CF)

ADD/ADC对状态标志位(CF/OF/ZF/SF)的影响:

ZF,SF略;

和的最高有效位有向最高位的进位时,CF=1,否则CF=0;

两个操作数符号相同,而结果符号与之相反时,OF=1,否则OF=0。

③. 加1指令INC

格式:INC src
操作:src<--(src)+1

只影响标志位OF、SF、AF、PF、ZF,不影响CF

④. 组合十进制加法调整指令DAA——压缩BCD码调整

将影响除OF外的其它状态标志位。

⑤. 非组合十进制加法调整指令AAA——非压缩BCD码调整:

只影响AF和CF状态标志位。

1、调整在AL中进行;

2、自动完成加6调整;

3、一般用于二进制加法指令ADD之后。

3.4.2.2 减法指令

①. 不考虑借位的减法指令SUB

格式:SUB dst,src
操作:dst ← (dst)-(src)
  1. 源和目的操作数不能同时为存储器操作数;
  2. 立即数不能为目的操作数。

②. 考虑借位的减法指令SBB

格式:SBB dst,src
操作:dst ← (dst)-(src)-(CF)

SUB/SBB对标志位(CF/OF/ZF/SF)的影响:

ZF,SF略

被减数的最高有效位有向高位的借位:CF=1,否则CF=0;

两个操作数符号相反,而结果的符号与减数相同:OF=1,否则OF=0。

③. DEC减1指令

格式:DEC src
操作:src<--(src)-1

DEC指令和INC指令一样,不影响CF标志位

④. NEG求补指令

表示操作数按位求反后末位加1,执行时,用零减去操作数。

格式:NEG  src
操作:src<--0-(src)

NEG指令对CF/OF的影响:

CF:操作数为0时,求补的结果使CF=0,否则CF=1;

OF:字节运算对-128求补或字运算对-32768求补时OF=1,否则OF=0。

⑤. 比较指令CMP

格式: CMP  dst,src
操作: (dst)-(src)

根据标志位状态来判断比较的结果:

1). 根据ZF判断两个数是否相等。若ZF=1,则两数相等,否则ZF=0;

2). 若两个数不相等(ZF=0),则分两种情况考虑:

  1. 比较的是两个无符号数(dst-src):若CF=0,则dst>src;若CF=1,则dst<src。
  2. 比较的是两个有符号数(dst-src):若OF$\bigoplus$SF=0,则dst>src;若OF$\bigoplus$SF=1,则dst<src。

3.4.2.3 乘法指令

乘法指令的两个操作数中,其中一个隐藏在AL或AX中

字节相乘,被乘数放在AL中,乘积在AX中。

字相乘,被乘数放在AX中,乘积放在DX(高16位),AX(低16位)。

①. 无符号数的乘法指令MUL(MEM/REG)

格式:MUL src

②. 有符号数乘法指令IMUL

只是要求两操作数均是有符号数,其余和MUL相同。

注:MUL/IMUL指令中

①.src不能为立即数,只能寄存器或存储单元的8位或16位数;

②. 只对状态标志位CF和OF有影响。

乘法指令对CF/OF的影响:

MUL指令:

IMUL指令:

3.4.2.4 除法指令

规定被除数必为除数的双倍字长

被除数 余数
字节除法 AX AL AH
字除法 DX,AX AX DX

①. 无符号数除法指令DIV

格式:DIV src

②. 带符号数除法指令IDIV

格式:IDIV src

商及余数均为有符号数,且余数符号总是与被除数符号相同

除法运算后,对所有状态标志位均无定义

src不能为立即数。

④. 符号扩展指令——字节扩展成字CBW

格式:CBW
操作:扩展AL中的符号位至AH中,将8位扩至16位

⑤. 符号扩展指令——字扩展成双字

格式:CWD
操作:扩展AX中的符号位至DX中,16位扩至32位

3.4.3 逻辑运算与移位指令

3.4.3.1 逻辑运算指令

①. NOT 逻辑非

不能直接跟立即数。

②. AND 逻辑与

③. OR 逻辑或

④. XOR 异或

⑤. TEST测试

TEST AL,01H
JNZ  NEXT    ;ZF=0转,测试AL最低位是否为1,是1则转移

NOT不影响标志位,其它4条指令将使CF和OF置0,AF无意义,ZF、SF、PF根据运算结果进行设置。

3.4.3.2 移位类指令

非循环移位指令

①. 算术左移指令SAL

SAL reg/mem,1/CL
;reg/mem左移1或CL位

算术左移

带符号数左移会出现溢出情况:

若最高位和CF不同,OF=1溢出,移位前后符号位不同;

若最高位和CF相同,OF=0无溢出,移位前后符号位没有改变。

②. 算术右移指令SAR

SAR reg/mem,1/CL
;reg/mem右移1/CL位

算术右移指令

③. 逻辑左移指令SHL

SHL reg/mem,1/CL

逻辑左移指令

④. 逻辑右移指令SHR

SHR reg/mem,1/CL

逻辑右移指令

影响CF,PF,SF,ZF,OF标志位,不影响AF。

循环移位指令
ROL reg/mem,1/CL    ;不带进位循环左移
ROR reg/mem,1/CL    ;不带进位循环右移
RCL reg/mem,1/CL    ;带进位循环左移
RCR reg/mem,1/CL    ;带进位循环右移

循环移位指令

按指令功能设置进位标志CF,但不影响SF,ZF,PF.AF标志。

3.4.4 串操作指令

串操作可以完成两个存储单元之间的传送和比较操作(仅是串指令可以)。

串指令使用的一般方法

3.4.4.1 重复前缀

REP ;CX≠0时重复执行
REPE/REPZ  ;CX≠0且ZF=1时重复执行
REPNE/REPNZ  ;CX≠0且ZF=0时重复执行

REP MOVSB    ;若(CX)=0030H,则重复传送30H次

3.4.4.2 取串

(不能加重复前缀)

LODS  SRC    ;(SI)→(AL) (SI+1)(SI)→(AX)
LODSB    ;等价于:MOV AL,[SI]
                INC SI
LODSW    ;等价于:MOV AX,[SI]
                INC SI
                INC SI

3.4.4.3 存串

(可以加重复前缀)

STOS DST    ;(AL)→(DI) (AX)→(DI+1)(DI)
STOSB/STOSW

3.4.4.4 串传送

MOVS  dst,src
;((DS):(SI))→((ES):(DI)) ((DS):(SI+1)(SI))→((ES):(DI+1)(DI))
MOVSB/MOVSW

3.4.4.5 串比较

CMPS dst,src
CMPSB/CMPSW
;比较的结果只反映在标志位上,串本身无变化

影响CF,AF,OF,PF,ZF,SF所有标志位。

3.4.4.6 串搜索

SCAS DST
SCASB/SCASW
;搜索指令执行的仍是比较操作,结果只影响标志位
;要搜索的关键字放在AL(AX)里

影响CF,AF,OF,PF,ZF,SF所有标志位。

3.4.5 控制转移类指令

3.4.5.1 转移指令

无条件转移指令JMP

①. 段内直接转移

JMP 0120H    ;直接转向0120H
JMP SHORT LP    ;段内直接短转移,转向LP
JMP NEAR PTR BBB    ;段内直接近转移,转向BBB

②. 段内间接转移

JMP SI    
;若(SI)=1200H,指令执行后,(IP)=1200H

JMP WORD PTR[BX+DI]
;若(DS)=3000,(BX)=1300H,(DI)=1200H,(32500H)=2350H
;则指令执行后,(IP)=2350H

③. 段间直接转移

JMP FAR PTR LABEL    ;段间直接转移,转向LABEL
JMP 2000H:1000H    ;(IP)←1000H,(CS)←2000H

④. 段间间接转移

JMP DWORD PRT[BX][SI]    
;用(BX)+(SI)所指的存储器字单元的内容取代(IP)
;用(BX)+(SI)+2所指的存储器字单元的内容取代(CS)
过程调用和返回指令

①. 调用指令CALL

;段内直接调用
CALL sub ;sub为子程序的入口    
CALL 1000H 

;段内间接调用
CALL AX    
CALL WORD PTR[SI]

;段间直接调用
CALL 2500H:1000H

;段间间接调用
CALL DWORD PTR[DI]

类似于段内无条件转移指令,不同的是CALL需要将返回地址IP入栈保存

②. 返回指令RET

RET 
RET n ;返回后再丢弃栈顶的n个字节

条件转移指令JXX

JXX    label    ;XX为条件名称缩写

①. 根据单个标志位设置的条件转移指令

单个标志位

②. 根据组合条件设置的条件转移指令

CMP dist,src    ;比较
JXX label    ;根据比较结果转移

组合条件

循环控制指令
LOOP label    ;(CX)-1→(CX),若(CX)≠0,则再次执行label
              等价:DEC CX
                     JNZ label

LOOPZ(LOOPE) label    
;(CX)-1→(CX),若(CX)≠0∧ZF=1,则再次执行label

LOOPNZ(LOOPNE) label
;(CX)-1→(CX),若(CX)≠0∧ZF=0,则再次执行label

所有转移指令均不会影响标志位

3.5 中断类指令及PC DOS功能调用

中断服务程序:专门的例行程序;

中断向量:中断服务程序的入口地址;

中断向量表:存放中断向量的存储区域。

3.5.1 DOS输入输出功能调用

常用的系统功能调用

功能调用的基本方法:

  1. 子功能号送AH寄存器;
  2. 按要求设置所有入口参数;
  3. 发送INT n软中断指令。

文章作者: Mat Jenin
文章链接: http://matjenin.xyz
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Mat Jenin !
  目录