文章目录
- 用 “ ; ” 表示注释
- EA(Effective Address) 有效地址 :课本中 指 近指针(Near)是段内的 16 位偏移量
一,寻址方式
操作数的寻址方式—立即寻址,寄存器寻址,存储器寻址和I/O端口寻址。
1.立即寻址(立即数寻址方式)
立即数只能是整数而且是常数
立即数在指令队列中,不用总线周期,执行快。
MOV AX,0102H ;AX<-0102H
2.寄存器寻址(寄存器寻址方式)
指令中指明某个寄存器的内容即为操作数。
寄存器在CPU中,不用总线周期,执行快。
MOV AX,BX ;AX-<BX
3. 存储器寻址
3.1. 直接寻址方式
指令中直接给出操作数所在的内存单元的有效地址(EA ,即偏移地址)
默认的段地址在 DS 段寄存器,若在其他段地址中可使用段超越前缀改变。
- 用方括号包含有效地址,表示存储单元的内容
- 直接地址也可用标号代表,这时可省略方括号
MOV AX,ES:[2000H]
3.2 寄存器间接寻址(寄存器间接寻址方式)
- 指令中给出的寄存器的内容包含操作数的有效地址
- 间接寻址中使用的寄存器名要用方括号括起来
(1) 基址寻址
用 BX 或 BP 作间接寻址寄存器
MOV AX,[BX] ;隐含在 DS 段
MOV AX,[BP] ;隐含在 SS 段
(2)变址寻址
用 SI 或 DI 作间接寻址寄存器
MOV CL,[SI] ;单独用 SI 或 DI 时,隐含在 DS 段中
MOV AX,[DI] ;串操作时 SI 隐含在 DS段,DI 隐含在 ES 段中
(3)相对基址寻址
指令中给出基址寄存器即位移量,二者之和为操作数的有效地址
MOV AX,[BX+6824H]
(4)相对变址寻址
指令中给出变址寄存器即位移量,二者之和为操作数的有效地址
MOV AX,[SI+6824H]
<=>
MOV AX,6824H[SI]
( 3 )(4)中,BX/SI/DI 段地址默认为 DS ,BP 段地址 默认是 SS,可用段超越前缀改变
MOV AX,ES:[DI+06H]
(5)基址变址寻址方式
有效地址 = 基址寄存器(BX或BP)的内容 + 变址寄存器(SI或DI)的内容。
MOV AX,[BX+SI]
<=>
MOV AX,[BX][SI]
(6)相对基址变址寻址方式
有效地址 = 基址寄存器(BX或BP)的内容 + 变址寄存器(SI或DI)的内容 + 8/16位位移量
MOV AX,[BX+DI+6]
<=>
MOV AX,6[BX+DI]
<=>
MOV AX,6[BX][DI]
4. 段寄存器的隐含访问
- [BX] 隐含于 DS 段
- [BP] 隐含于 SS 段
- [SI],[DI] 单独使用隐含于 DS 段
- 基址寄存器和变址寄存器同时出现,以基址寄存器隐含关系为准
- [SP]隐含于 SS 段
- [SI],[DI] 用于 串操作时,SI 隐含在 DS段,DI 隐含在 ES 段中
二,8086 指令系统
- 传送指令
- 算术运算指令
- 逻辑运算和移位指令
- 串操作指令
- 控制转移指令
- 处理器类控制指令
1. 数据传送指令
注意!
- 段寄存器只能通过 AX 改!
- 不能改 CS,IP
- 不能存储器向 存储器传送,XCHG也不能!
(1)通用数据传送指令
-
① 基本传送指令 MOV
MOV 目的操作数,源操作数注意:
- 不存在存储器向存储器的传送指令
- 对段寄存器操作 必须先传到 AX寄存器 再给段寄存器
- 两个操作数类型要一致。
- 明确 字节 还是 字 操作
- 不能改 CS,IP
- 修改 SS 和 SP 时两条指令中间不允许插入其他指令
MOV AX,06H
-
②数据交换指令 XCHG
XCHG 目的操作数,源操作数把两个地方的操作数进行互换.
注意:
- 不能存储器与存储器之间互换数据
XCHG AH,AL
-
③堆栈操作指令 PUSH , POP
-
进栈指令 PUSH —— PUSH 源操作数
先使堆栈指针 SP 减2,然后把一个字操作数存入堆栈顶部
-
出栈指令 POP —— POP 目的操作数
把栈顶的一个字传送到目的操作数,然后堆栈指针 SP 加2
-
!!!堆栈 栈底的地址最高
- 不能操作立即数!作为源操作数也不行!
- CS 可以是源操作数,但不能是目的操作数
PUSH BX ;将 BX 的内容压入堆栈,SP=SP-2
POP AX ;将 栈顶(SP所指的)一个字的内容传至 AX,SP=SP+2
(2)累加器专用传送指令
-
①输入输出指令 IN/OUT
IN AX/AL,源操作数
OUT 目的操作数,AX/AL注意:
- 操作数又称为端口
- 端口地址在00H ~ FFH 之间可以用直接寻址,大于FFH 时必须用 DX间接寻址
IN AL,20H
OUT DX,AX
-
②换码指令(查表指令) XLAT
XLAT将 BX 指定的缓冲区中,AL 指定的位移处的一个字节数据提取出赋给 AL
使用方式:
1.换码指令前,在主存建立一个字节量表格,内含要转换成的目的代码,表格首地址放于BX中,AL 存放相对表格首地址的位移量。
2.换码指令执行后,AL 寄存器的内容转换为目标代码
(3)地址传送指令
-
①取有效地址指令 LEA
LEA 寄存器,源操作数将存放源操作数的16位偏移地址送到一个16位的通用寄存器
-
②将地址指针(其实是内存单元的内容,该内容是地址)装入DS指令 LDS
LDS 寄存器,源操作数LDS将源操作数有效地址所对应的内存单元中的双字长的高字节内容(该内容一般为段地址)送至DS、低字内容(给内容一般为偏移地址)送入指令所指的寄存器
-
③将地址指针(其实是内存单元的内容,该内容是地址)装入ES指令 LES
LES 寄存器,源操作数LES将源操作数有效地址所对应的内存单元中的双字长的高字节内容(该内容一般为段地址)送至ES、低字内容(给内容一般为偏移地址)送入指令所指的寄存器
注意:
LEA,LDS,LES 指令
- 指令格式中的源操作数必须是存储器寻址方式
- 注意LEA 与 MOV 的区别,一个传地址(LEA),一个传内容(MOV)
(4)标志传送指令
-
标志读取指令 LAHF
LAHF将标志寄存器的低8位 传送到 AH 中,仅传送 SF,ZF,AF,PF,CF
-
标志设置指令 SAHF
SAHF将AH寄存器的相应位传送带哦标志寄存器的 低8位,仅传送 SF,ZF,AF,PF,CF
-
标志寄存器压入堆栈指令 PUSHF
PUSHF
将标志寄存器的值压入堆栈顶部
- 标志寄存器从堆栈弹出指令 POPF
POPF
从堆栈中弹出一个字送到标志寄存器中
注意:
- LAHF SAHF 是为兼容 8080 而设置的 ,仅传送 SF,ZF,AF,PF,CF
- 标志寄存器与通用寄存器之间没有直接传送指令
2. 算术运算类指令
(1)加法指令
- ① ADD
ADD 目的操作数,源操作数
目的操作数 = 目的操作数 + 源操作数
- ② ADC
ADC 目的操作数,源操作数
目的操作数 = 目的操作数 + 源操作数 + CF(进位标志)
- ③ INC
INC 目的操作数
目的操作数 = 目的操作数 + 1
注意:
- ADD,ADC 除是否带进位外其余都相同,目的操作数不能是立即数,CS,IP
- INC 影响标志位 AF , OF , PF , SF , ZF 但不会影响进位标志 CF
- ADD 和 ADC 影响标志位 AF , OF , PF , SF , ZF , CF
(2)减法指令
- ① SUB
SUB 目的操作数,源操作数
目的操作数 = 目的操作数 - 源操作数
- ② SBB
SBB 目的操作数,源操作数
目的操作数 = 目的操作数 - 源操作数 - CF(进/借位标志)
- ③ (自减)DEC
DEC 目的操作数
目的操作数 = 目的操作数 - 1
- ④ (取补码)NEG
NEG 目的操作数
目的操作数 = 目的操作数取补码( 0 - 目的操作数)
- ⑤ CMP
CMP 目的操作数,源操作数
目的操作数 - 源操作数 ,但不保留结果,只是影响标志位
注意:
- SUB 和 SBB 除是否带进位外其余都相同,目的操作数不能是立即数,CS,IP
- DEC 影响标志位 AF , OF , PF , SF , ZF 但不会影响进位标志 CF
- SUB,SBB,NEG,CMP 影响标志位 AF , OF , PF , SF , ZF , CF
- NEG 操作数为0 时 CF才为0,否则为1
(3)乘法指令
- ① MUL
MUL 源操作数
无符号相乘
16位:AX = AL * 源操作数
32位:DX,AX = AX * 源操作数
- ② IMUL
MUL 源操作数
有符号相乘
16位:AX = AL * 源操作数
32位:DX,AX = AX * 源操作数
注意:
- MUL 和 IMUL 都会影响标志位 CF 和 OF 其余标志位(AF , PF , SF , ZF)不确定,无意义,乘积的高半部分不为0则CF和OF为1。否则为0.
(4)除法指令
-
① DIV
DIV 源操作数无符号数除法
32位:DX 和 AX 表示的32位数除以源操作数,得到的16位商放在 AX 中,16位余数放在 DX 中
16位: AX 表示的16位数除以8位源操作数,得到的8位商放在 AL 中,16位余数放在 AH 中 -
② IDIV
IDIV 源操作数有符号数除法(其余与 DIV 一致)
32位:DX 和 AX 表示的32位数除以源操作数,得到的16位商放在 AX 中,16位余数放在 DX 中
16位: AX 表示的16位数除以8位源操作数,得到的8位商放在 AL 中,8位余数放在 AH 中 -
③ CBW
CBW将字节扩展成字的指令,即将 AL 寄存器的符号位拓展到 AH 中
-
④ CWD
CWD将 AX 中的被除数(字)拓展成双字,即把 AX 寄存器中的符号位拓展到 DX 中
注意:
- 除法运算后的6个状态标志位都是不确定,无意义的
- 除法运算的溢出:除数是8位,商范围为0~255(有符号数为-128~127) ;
除数是16位,商范围为0~65535(有符号数为-32768~32767),若超出这个范围,CPU认为除数是0,产生 0号中断。 - IDIV 认为余数的符号与被除数的符号相同,如-51/9=-5…-6
- 被除数与除数位数相同时,必须进行拓展处理,CBW 或 CWD
- CBW 与 CWD 不影响标志位。
(5)BCD 码运算调整指令
BCD 码 分为 组合式BCD码(1个字节两位) 和 分离式BCD码(1个字节一位)(分离式BCD码也称ASCLL码,高四位不用)
----------------------加减调整------------------------
- DAA
对两个组合式BCD码相加的结果进行调整 - AAA
对两个分离式BCD码相加的结果进行调整 - DAS
对两个组合式BCD码相减结果进行调整 - AAS
对两个分离式BCD码相减结果进行调整
原理:
- DAA/DAS 当结果中 AL 中低4位大于9或 AF=1 时,则对累加器AL中低4位(A3~A0)进行 加6/减6 修正;当 AL 中高4位(A7~A4)大于9或进位表示 CF=1时,对AL高4位进行 加6/减6 修正。
- AAA/AAS 当结果 AL 中低4位 大于9或 AF=1 时,对累加器AL进行 加6/减6 修正,同时使AH 加1/减1,并使AF、CF的标志置1,使 AL 的高4位 清0.
----------------------乘除调整------------------------
-
AAM
将二进制乘法运算中间结果调整成以分离式表示的BCD码乘积,积的高位存放在 AH 中,低位存放在 AL 中
-
AAD
将 AH 及 AL 中二位分离式BCD码调整为二进制数并存入 AL 中 以便进行二进制除法运算。
注意:
- 只有分离式BCD码才能进行乘法运算
- 只有分离式BCD码才能进行除法运算,与其他三类运算不同在于:在除法运算之前对AX中的两个BCD码调整成二进制,再进行除法。
- BCD 码调整运算之前的中间结果都必须放在AL中。
3.逻辑运算和移位运算
(1) 逻辑运算指令
-
按位与——AND
AND 目的操作数,源操作数. -
按位或——OR
OR 目的操作数,源操作数 -
按位非——NOT
NOT 目的操作数 -
按位异或——XOR
XOR 目的操作数,源操作数 -
测试与——TEST
TEST 目的操作数,源操作数将目的操作数和源操作数按位进行“与”运算,结果不保留,仅改变标志位(SF,ZF,PF)。
注意:
- 目的操作数不能是立即数,当有两个操作数时,不能同时都是存储器操作数
(2)移位指令
非循环移位指令
SAL 目的操作数,计数值 ;算术左移,最低位补0,最高位移入 CF
SHL 目的操作数,计数值 ;逻辑左移,和算术左移一样
SAR 目的操作数,计数值 ;算术右移,最高位保持不变并依次右移,最低位移入 CF
SHR 目的操作数,计数值 ;逻辑右移,最高位补0,向右移,最低位进入 CF
注意:
- 目的操作数可以是 字节 或 字。
- 指令的目的操作数只能是 寄存器 或 存储器操作数,计数值可是1 或 CL,最多移位255位。
- 算术移位相当于乘或除以 2的n次方。
- 移位指令会影响 PF,SF,ZF,OF,CF.AF不定。若只左移一位,如果最高位和CF不同,则OF置1,否则置0,对有符号数来说,以此来判断移位后的符号位和移位前的符号位是否不同。
循环移位指令
ROL 目的操作数,计数值 ;不带进位的循环左移指令,每移一次,最高位进入最低位和 CF 位
ROR 目的操作数,计数值 ;不带进位的循环右移指令,每移一次,最低位进入最高位和 CF 位
RCL 目的操作数,计数值 ;带进位标志的循环左移指令,最高位进入CF,原CF进入最低位
RCR 目的操作数,计数值 ;带进位标志的循环右移指令,最低位进入CF,原CF进入最高位
注意:
- 目的操作数可以是 字节 或 字。
- 指令的目的操作数只能是 寄存器 或 存储器操作数,计数值可是1 或 CL,最多移位255位。
- 循环移位指令只影响CF和OF两个标志位。仅当在移位后使操作数的最高位和次高位不等时,OF 才为1,表示移位后的数据符号与原来的符号不同了。
4. 串操作指令
- 通过加 重复前缀 来实现串操作
- 规定 CX 寄存器存放要处理的字符串的元素个数,即字节数或字数,每执行一次字符串指令,CX 的内容自动减1.当CX = 0 时停止重复执行,移向下一条指令。
所以,串操作之前一定要先给CX赋值 - 所有的串操作规定 源操作数在 DS:SI 逻辑地址单元中,目的操作数在 ES:DI 逻辑地址单元中。(串操作时8086唯一一组两个操作数都在存储器中的指令)
- 串操作时,由方向标志 DF 来规定指针 SI 和 DI 增减的。
当DF=1时,SI 和 DI 自动减少 K;
当DF=0时,SI 和 DI 自动增加 K;
(对字节串操作K=1,对字串操作 K=2) - 重复的字符串处理过程是可以被中断的
重复前缀:
-
REP
REP 串操作指令
重复串操作指令,直到 CX=0 停止
-
REPE 或 REPZ(含义相同)
重复串操作指令,直到 CX=0 或 ZF=0 停止
-
REPNE 或 REPNZ(含义相同)
重复串操作指令,直到 CX=0 或 ZF=1 停止
字符串指令:
字符串传送指令
-
MOVSB
目的操作数( ES:DI所指单元)的数据按字节传至源操作数( DS:SI 所指单元),DF决定方向
-
MOVSW
目的操作数( ES:DI所指单元)的数据按字传至源操作数( DS:SI 所指单元),DF决定方向
注意:
- MOVSB和MOVSW 常与重复指令REP配合使用
- 使用前,必须设置 DS,ES,DI,SI,CX,DF,否则程序出错
字符串比较指令
-
CMPSB
目的操作数( ES:DI所指单元)的数据按字节与源操作数( DS:SI 所指单元)的数据相比较,DF决定方向
-
CMPSW
目的操作数( ES:DI所指单元)的数据按字与源操作数( DS:SI 所指单元)的数据相比较,DF决定方向
注意:
- CMPSB和CMPSW 常与重复指令REPNZ(REPNE),REPZ(REPE)配合使用
- 使用前,必须设置 DS,ES,DI,SI,CX,DF,否则程序出错
- REPNZ 和 REPZ 的退出有两种情况,必须用JZ(ZF标志位检测指令)确定是哪一种退出
字符串检索指令
-
SCASB ;将AL中的字节与ES:DI所指的地址的字节相比较,DF决定方向
-
SCASW;将AX中的字与ES:DI所指的地址的字相比较,DF决定方向
这两条指令都是通过影响 标志位 AF,CF,OF,PF,SF,ZF 来反映结果的
取字符串指令
-
LODSB;将DS:SI所指的地址中的字节放到AL,DF决定方向
-
LODSW;将DS:SI所指的地址中的字放到AX,DF决定方向
存字符串指令
-
STOSB ;将 AL 中的数存到 ES:DI 所指的地址中,DF决定方向
-
STOSW;将 AX 中的数存到 ES:DI 所指的地址中,DF决定方向
每次存完之后由DF决定DI的地址是递增还是递减
5. 控制转移类指令
(1)无条件跳转指令 JMP
JMP 目的地址
(2)条件跳转指令
① 简单条件跳转指令
- JC 目标地址
- JNC 目标地址
- JZ 目标地址
- JNZ 目标地址
- JS 目标地址
- JNS 目标地址
- JO 目标地址
- JNO 目标地址
- JP 目标地址
- JNP 目标地址
- JCXZ 目标地址 ;CX中的值为0,则转移
② 带符号数条件跳转指令(与CMP配合使用?)
- JG/JNLE 目标地址;>
- JGE/JNL 目标地址;>=
- JL/JNGE 目标地址;<
- JLE/JNG 目标地址;<=
③ 无符号数条件跳转指令(与CMP配合使用?)
- JB/JNAE 目标地址;<
- JNB/JAE 目标地址;>=
- JA/JNBE 目标地址;>
- JNA/JBE 目标地址;<=
(3)循环控制指令
- LOOP 目标地址;将CX的内容减1,循环直到CX=0
- LOOPZ/LOOPE 目标地址;将CX的内容减1,CX≠0且ZF=1时继续循环
- LOOPNZ/LOOPNE 目标地址;将CX的内容减1,CX≠0且ZF=0时继续循环
注意:
- LOOPZ 或 LOOPNZ 等指令时,ZF不受CX的值得影响,而受其他指令的影响
(4)子程序调用和返回指令
- CALL 目标地址
- RET
- RET 参数
6. 中断指令
- INIT n
- INITO
是用来处理状态标志OF的,可以通过中断程序来处理溢出事件 - IRET
专用来中断函数返回的,不光弹出断点地址,还弹出标志寄存器
7.标志操作指令
- STC
- CLC
- CMC ;对CF标志取反
- STD
- CLD
- STI
- CLI
8.8086CPU与外部事件同步指令
- HLT
- WAIT
- ESC 外部操作码,源操作数
- LOCK 指令
9. 空操作指令
- NOP