文章目录
- 一、数据传送指令
-
- [1. 通用数据传送指令](#1. 通用数据传送指令)
-
- [1.1 MOV传送指令](#1.1 MOV传送指令)
- [1.2 XCHG交换指令](#1.2 XCHG交换指令)
- [1.3 进栈指令PUSH](#1.3 进栈指令PUSH)
- [1.4 出栈指令POP](#1.4 出栈指令POP)
- [1.5 所有寄存器进出栈指令PUSHA/POPA](#1.5 所有寄存器进出栈指令PUSHA/POPA)
- [2. 累加器专用传送指令](#2. 累加器专用传送指令)
-
- [2.1 输入指令IN](#2.1 输入指令IN)
- [2.2 OUT输出指令](#2.2 OUT输出指令)
- [2.3 IO端口与8086CPU通讯关系](#2.3 IO端口与8086CPU通讯关系)
- [2.4 XLAT 换码指令](#2.4 XLAT 换码指令)
- [3. 地址传送指令](#3. 地址传送指令)
-
- [3.1 有效地址送寄存器指令LEA (Load Effective Address)](#3.1 有效地址送寄存器指令LEA (Load Effective Address))
- [3.2 指针送寄存器及相应段寄存器指令LDS和LES](#3.2 指针送寄存器及相应段寄存器指令LDS和LES)
- [3.3 标志寄存器传送指令](#3.3 标志寄存器传送指令)
- 二、算术运算指令
-
- [1. 加法指令](#1. 加法指令)
- [2. 减法指令](#2. 减法指令)
- [3. 乘法指令](#3. 乘法指令)
- [4. 除法指令](#4. 除法指令)
- [5. 类型转换指令指令](#5. 类型转换指令指令)
- [6. 十进制调整指令](#6. 十进制调整指令)
-
- [6.1 压缩的BCD码调整指令](#6.1 压缩的BCD码调整指令)
- [6.2 非压缩的BCD码调整指令](#6.2 非压缩的BCD码调整指令)
一、数据传送指令
数据传送指令负责把数据、地址或立即数传送到寄存器、存储器或端口号寄存器。它相对高级语言里的赋值语句。
-
通用数据传送:MOV、XCHG、PUSH、POP
-
累加器专用传送(输入输出):IN、OUT、XLAT
-
地址传送:LEA、LDS、LES
-
标志寄存器传送:LAHF、SAHF、PUSHF、POPF
1. 通用数据传送指令
1.1 MOV传送指令
把源操作数(第二操作数)的值传给目的操作数(第一操作数)该操作数的寻址方式可以是任意一种存储单元寻址方式
格式:MOV Reg/Mem,Reg/Mem/Imm
- Reg---Register(寄存器)
- Mem---Memory(存储器)
- Imm---Immediate(立即数)
tips:MOV指令几条特殊规定
- 两个操作数的数据类型要相同 ,如:
MOV BL,AX
、MOV AX,BL
等都是不正确的; - 两个操作数不能同时为段寄存器 ,如:
MOV ES,DS
等; - 代码段寄存器CS不能为目的操作数,但可作为源操作数 , 如:指令
MOV CS, AX
等不正确,但指令MOV AX,CS
等是正确的; - 立即数不能直接传给段寄存器 , 如:
MOV DS,100H
等; - 立即数不能作为目的操作数 ,如:
MOV 100H,AX
等; - 指令指针IP,不能作为MOV指令的操作数;
- 两个操作数不能同时为存储单元 ,如:
MOV VARA,VARB
等,其中VARA和VARB是同数据类型的内存变量
1.2 XCHG交换指令
可以将一个字节或一个字 的源操作数与目的操作数相交换。交换能在通用寄存器之间、通用寄存器与存储器之间进行。但段寄存器和立即数不能作为一个操作数。
格式:XCHG OPD,OPS
eg:
(AL)=2AH,(DS)=1000H, (1204DH)=5BH,指令XCHG AL,[204DH]
执行后,(AL)=5BH,(AL)=2AH
1.3 进栈指令PUSH
将寄存器、段寄存器或存储器中的一个字数据 压入堆栈,堆栈指针减2(栈向低地址增长,且由于小端对齐,先高8位数据进栈,然后低8位数据进栈)
格式:PUSH Reg/Mem/Seg
1.4 出栈指令POP
将栈顶元素弹出送至某一寄存器、段寄存器(除CS外)或存储器,堆栈指针加2。 (先低8位数据出栈,然后高8位数据出栈 )
格式:POP Reg/Mem/Seg
过程逆向PUSH即可
1.5 所有寄存器进出栈指令PUSHA/POPA
- PUSHA:16位通用寄存器依次进栈,次序为AX、CX、DX、BX(不是ABCD!! ),指令执行前的SP、BP、SI、DI。
指令执行后(SP)-16→(SP),SP仍指向栈顶。- POPA:16位通用寄存器依次出栈,次序为DI、SI、BP、SP,指令执行前的BX、DX、CX、AX。
指令执行后(SP)+16→(SP) ,SP仍指向栈顶
格式:PUSHA
/POPA
tips:SP特别处理
SP出栈只是修改了指针,使其后的BX能够出栈,而堆栈中原先由PUSHA指令存入的SP的原始内容被丢弃,并未真正送到SP寄存器中。
2. 累加器专用传送指令
仅限于使用累加器AX或AL传送信息
2.1 输入指令IN
输入指令用来从指定的外设寄存器取信息送入累加器
Func:从端口中读入一个字节或字 (取决于寄存器),并保存在寄存器AL或AX中。如果某输入设备的端口地址 在0~255 范围之内,那么,可在指令IN中直接给出,否则,要把该端口地址先存入寄存器DX中,然后在指令中由DX来给出其端口地址。
格式:
- 长格式 :
IN AL, PORT
(字节)/IN AX, PORT
(字) - 短格式 :
IN AL, DX
(字节)/IN AX, DX
(字)
eg:
如IN DX,2F8H
不可,需要先MOV DX,2F8H
再 进行IN指令
IN AL,DX
;从端口2F8H读入一个字节到AL中IN AX,DX
;把端口2F8H、2F9H按"高高低低"组成
的字读入AX
2.2 OUT输出指令
把累加器的内容送往指定的外设存储器
将寄存器AL或AX的内容输出到指定端口。如果某输出设备的端口地址在0~255范围之内,那么,可在指令OUT中直接给出,否则,要把该端口地址先存入寄存器DX中,然后在指令中由DX来给出其端口地址。
类似IN指令
2.3 IO端口与8086CPU通讯关系
所有I/O端口与CPU之间的通信都由IN和OUT指令来完成。外部设备最多有65536个I/O端口,端口号为0000~0FFFFH。
- 前256个端口(00~0FFH)可以直接在指令中指定,这就是所谓的长格式。
- 当端口号≥256时,只能使用短格式 ,此时必须先将端口号放到DX寄存器中(端口号为0000~0FFFFH),然后再用IN和OUT指令来传送信
息。 - 注意:这里的端口号或DX的内容均为地址,而传送的是端口中的信息,在使用短格式时,DX内容才是端口号本身。
2.4 XLAT 换码指令
XLAT指令有两个隐含操作数BX和AL
Function:把BX的值作为内存字节数组首地址、下标为AL的数组元素的值传送给AL。
格式:XLAT OPR
或 XLAT
eg:
若(BX)=0040H
MOV AL,3
XLAT
则指令执行后AL的值为33H
tips:可用来查表或访问数组,但表和数组的长度不能超过256.
3. 地址传送指令
3.1 有效地址送寄存器指令LEA (Load Effective Address)
Function: 将源操作数的有效地址送到指定的寄存器中。
格式:LEA REG,OPS
tips:
- 源操作数必须是一个内存操作数;
- 目的操作数必须是一个16位的通用寄存器。这条指令通常用来建立串操作指令所须的寄存器指针。
- OPS不允许是直接地址 。如lea bx,[2000h]。但可以使用符号地址,如 lea bx,varx 。
3.2 指针送寄存器及相应段寄存器指令LDS和LES
LDS_Function:
- 完成一个地址指针的传送。地址指针包括段地址部分和偏移量部分。指令将段地址(EA+2)送入DS,偏移量部分(EA)送入一个16位的基址寄存器或变址寄存器。
LES_Function:
- 将地址指针的段地址部分送入ES外,与LDS类似
格式为: LDS/LES REG,OPS
tips:
- 源操作数是一个内存操作数。
- 目的操作数是一般 为基址寄存器或变址寄存器 。(其它16位寄存器也可以,但不能是段寄存器)例如:LDS SI,[BX] ;将把BX所指的32位地址指针的段地址部分送入DS,偏移量部分送入SI。
- 本组指令不影响标志位。
3.3 标志寄存器传送指令
- 标志送AH指令:
LAHF
;操作:(AH)<---(FLAGS的低字节) - AH送标志寄存器指令:
SAHF
;操作: (FLAGS的低字节)<---(AH) - 标志进栈指令:
PUSHF
;操作: (SP)<---(SP) - 2、((SP)+1, (SP))<---(FLAGS) - 标志出栈指令:
POPF
;操作: (FLAGS)<---((SP)+1,(SP))、(SP)<---(SP)+ 2
二、算术运算指令
该组指令的操作数可以是8位、16位。当存储单元是该类指令的操作数时,该操作数的寻址方式可以是任意一种存储单元寻址方式。
- 加法指令 ADD、ADC、INC
- 减法指令 SUB、SBB、DEC、NEG、CMP
- 乘法指令 MUL、IMUL
- 除法指令 DIV、IDIV
- 类型转换指令: CBW CWD
- 十进制调整指令 DAA、DAS、 AAA、AAS、AAM、AAD
1. 加法指令
ADD_Function: 将目的操作数与源操作数相加,结果存入目的地址中,源地址的内容不改变
ADC_Function:将目的操作数加源操作数再加低位进位,结果送目的地址
INC_Function:将目的操作数加1,结果送目的地址(INC指令不影响CF标志)
格式:
ADD DST,SRC
- 带进位加法指令
ADC DST,SRC
- 加1指令:
INC OPR
2. 减法指令
SUB_Function:目的操作数减去源操作数,结果存于目的地址,源地址的内容不变
SBB_Function:目的操作数减源操作数再减低位借位CF,结果送目的地址
DEC_Function:将目的操作数减1,结果送目的地址(不影响CF标志)
NEG_Function:将目的操作数的每一位取反(包括符号位)后加1,结果送目的地址。(允许存储器或寄存器操作数,不允许段寄存器)
CMP_Function:目的操作数减源操作数,结果只影响标志位,不送入目的地址。
格式:
SUB DST,SRC
- 带借位减法指令
SBB DST,SRC
- 减1指令
DEC OPR
- 求补指令:
NEG OPR
- 比较指令:
CMP OPR1, OPR2
tips :
对于字节操作时,数据-128和字操作时数据-32768的情况,求补后不变,OF=1
3. 乘法指令
Function: 若是字节 数据相乘,(AL寄存器)与SRC相乘得到字数据 存入AX中;若是字 数据相乘,则(AX)与SRC相乘得到双字数据 ,高字存入DX、低字存入AX中 。SRC不允许是立即数
格式:
- 无符号数乘法指令:
MUL SRC
- 带符号数乘法指令:
IMUL SRC
tip:对OF和CF标志的影响:
- MUL指令------若乘积的高一半(AH或DX)为0,则OF=CF=0;否则OF=CF=1。(用来检查字节相乘的结果是字节还是字,或字相乘的结果是字还是双字)
- IMUL指令------若乘积的高一半是低一半的符号扩展,则OF=CF=0;否则均为1。
4. 除法指令
寄存器使用与乘法相同
格式:
- 无符号数除法指令:
DIV SRC
- 带符号数除法指令:
IDIV SRC
tips:
- 对DIV指令,在除数为0,或者在字节除时商超过8位,或者在字除时商超过16位时发生除法溢出。
- 对IDIV指令,除数为0,或者在字节除时商不在-128~127范围内,或者在字除时商不在-32768~32767范围内,发生除法溢出。
- SRC不允许是立即数
5. 类型转换指令指令
- 字节扩展为字指令
CBW
AL -> AX
执行操作: 若(AL)的最高有效位为0,则(AH)= 00H若(AL)的最高有效位为1,则(AH)= FFH - 字扩展成双字指令
CWD
AX -> (DX,AX)
执行操作:若(AX)的最高有效位为0,则(DX)= 0000H若(AX)的最高有效位为1,则(DX)= FFFFH
6. 十进制调整指令
6.1 压缩的BCD码调整指令
- 加法的十进制调整指令DAA
格式:DAA
- 如果AL寄存器中低4位大于9或辅助进位AF=1,则AL=AL+6且AF=1;
- 如果AL>=0A0H或CF=1,则AL=AL+60H且CF=1。
- 该指令对SF、ZF、PF均有影响。
- 减法的十进制调整指令DAS
格式:DAS
- 如果AF=1或AL寄存器中低4位大于9,则AL=AL-6且AF=1;
- 如果AL>=0A0H或CF=1,则AL=AL-60H且CF=1。
- SF、ZF、PF均受影响。
6.2 非压缩的BCD码调整指令
-
加法的非压缩的BCD调整指令AAA
格式:
AAA
- 如果AL的低4位大于9或AF=1,则AL=AL+6,AH=AH+1,AF=CF=1, 且AL高4位清零。
否则CF=AF=0,AL高4位清零。
- 如果AL的低4位大于9或AF=1,则AL=AL+6,AH=AH+1,AF=CF=1, 且AL高4位清零。
-
减法的非压缩的BCD调整指令AAS
格式:
AAS
- 如果AL的低4位大于9或AF=1,则AL=AL-6,AH=AH-1,AF=CF=1,AL高4位清零。
否则CF=AF=0, AL高4位清零。 - 其他标志位OF、PF、SF、ZF不确定。
- 如果AL的低4位大于9或AF=1,则AL=AL-6,AH=AH-1,AF=CF=1,AL高4位清零。