微机原理 第三章: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)
- 源和目的操作数不能同时为存储器操作数;
- 立即数不能为目的操作数。
②. 考虑借位的减法指令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),则分两种情况考虑:
- 比较的是两个无符号数(dst-src):若CF=0,则dst>src;若CF=1,则dst<src。
- 比较的是两个有符号数(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输入输出功能调用
功能调用的基本方法:
- 子功能号送AH寄存器;
- 按要求设置所有入口参数;
- 发送INT n软中断指令。