微机原理与接口技术(五)
寻址方式与指令系统(续)
-
指令寻址方式
指令寻址方式是指确定下一条将要执行指令地址的方法,有顺序寻址和跳转寻址方式两种。
程序的执行,一般是从存储器MEM中代码段顺序取指令执行,指令地址是由指令指针寄存器IP自动增量形成。在某些条件下,程序的执行要跳转到另外一段程序开始顺序执行。这种运行方式称为转移。转移指令中应给出转移地址操作数。根据跳转的距离远近,转移又分为:段内转移和段间转移。无论是段间转移还是段内转移,都有两种寻址方式:直接寻址和间接寻址。
-
-
段内直接寻址
指令名 SHORT 目标地址标号 指令名 NEAR PTR 目标地址标号
指令名 目标地址标号
-
当执行这种寻址方式的转移指令时,机器取出位移量,与当前(IP)相加,将其和送入IP寄存器中,CS寄存器内容保存不变,从而实现指令的转移。位移量为 8 位时,称段内直接短转移;位移量为 16 位时,称段内直接近转移。SHORT表示位移量被强制为8位,NEAR PTR表示位移量被强制为 16 位,默认为 16 位偏移量。
-
-
段间直接寻址
指令名 FAR PTR 目标地址标号 指令名 段地址:段偏移地址
在转移指令中给出一个存储单元的地址,用该地址所指的两个相邻字单元的内容(32位)来取代(CS)和(IP)中的内容,从而达到段间转移的目的。
-
段内间接寻址
指令名 16位寄存器名 指令名 WORD PTR 存储器寻址方式 指令名 存储器寻址方式
由转移指令中指定一个16位寄存器或存储器字单元的内容做为转移的有效地址,直接取代(IP)的内容。
-
段间间接寻址
指令名 DWORD PTR 存储器寻址方式
在转移指令中给出一个存储单元的地址,用该地址所指的两个相邻字单元的内容(32位)来取代(CS)和(IP)中的内容,从而达到段间转移的目的。
-
-
8086指令系统
8086 CPU 提供 133 条基本指令,可分为 7 类:数据传送指令、算术运算指令、逻辑运算指令、移位指令、串操作指令、程序控制指令和处理器控制指令。下面将列出这些指令及它们的注意事项。
-
-
数据传送指令
-
指令类别 | 汇编格式 | 功能说明 |
通用数据传送指令 | MOV DST, SRC | DST ← SRC |
堆栈操作指令 |
PUSH SRC POP DST |
SP ← SP-2,(SP+1: SP) ← SRC DST ← (SP+1: SP), SP ← SP+2 |
地址传送指令 |
LEA REG, SRC LDS REG, SRC LES REG, SRC |
REG ← SRC 的有效地址 REG ← SRC, DS ← SRC+2 REG ← SRC, ES ← SRC+2 |
标志寄存器传送指令 |
LAHF SAHF PUSHF POPF |
AH ← FLAGS 低八位 FLAGS 低八位 ← AH SP ← SP-2,(SP+1: SP) ← FLAGS DST ← (SP+1: SP), SP ← SP+2 |
数据交换指令 | XCHG DST, SRC | DST ↔ SRC |
换码指令 | XLAT | AL ← (BX+AL) |
输入/输出指令 |
IN DST, SRC OUT DST, SRC |
- 通用数据传送指令
-
-
- SRC和DST必须类型一致(都是8位或者是16位)
- DST不能是立即数
- 两个操作数不能都是存储器操作数
- 两个操作数不能都是段寄存器操作数
- SRC是立即数时,DST不能是段寄存器,必须通过通用寄存器作中介
- CS和IP不能作为目的操作数,CS可以作为源操作数
- 段寄存器CS的值,只在MOV、PUSH中可作源操作数
- MOV指令不影响标志位
-
2. 堆栈操作指令
-
-
- PUSH 和 POP 指令不能使用立即寻址方式,POP 指令不能使用 CS 寄存器
- 用 PUSH 指令和 POP 指令时只能按字访问堆栈,不能按字节访问堆栈。
- PUSH 和 POP 指令都不影响标志位
-
3. 地址传送指令
-
-
- 有效地址 EA 传送指令 LEA:源操作数必须是存储器操作数,而目的操作数必须是16位通用寄存器;这条指令不影响标志位
-
-
-
- 数据段寄存器传送指令 LDS:变量的16位地址偏移量必须传送至一个16位的通用寄存器,典型为 SI;这条指令不影响标志位
-
-
-
- 附加段寄存器传送指令 LES:变量的16位地址偏移量必须传送至一个16位的通用寄存器,典型为 SI;这条指令不影响标志位
-
4. 标志寄存器传送指令
-
-
- LAHF, SAHF, PUSHF, POPF 均是无操作数指令,其中 LAHF 和 SAHF 隐含的操作数为 AH
-
5. 数据交换指令
-
-
- 转换表长度最大为256个表项(字节)
-
6. 输入/输出指令
-
-
- 指令中使用的数据寄存器必须是 AL 或 AX;间接寻址的寄存器必须是 DX
-
算术运算指令
-
1. 加法与减法指令
指令类别 | 汇编格式 | 功能说明 |
不带进位加法指令 带进位加法指令 自增指令 不带借位减法指令 带借位减法指令 自减指令 取负指令 比较指令 |
ADD DST, SRC ADC DST, SRC INC DST SUB DST, SRC SBB DST, SRC DEC DST NEG DST CMP DST, SRC |
DST ← SRC+DST DST ← SRC+DST+CF DST ← DST+1 DST ← DST-SRC DST ← DST-SRC-CF DST ← DST-1 DST ← 0-DST DST-SRC 并设置标志位 |
-
-
- 带进位加法/减法指令主要用来实现多字节、多精度的加/减法运算。
- 比较指令 CMP:当标志位 OF、SF 相同时,AX > BX;当标志位 OF、SF 相反时,AX < BX
-
2. 乘法指令与除法指令
指令类型 | 汇编格式 | 功能说明 |
带符号乘法运算指令 | IMUL SRC |
字节运算:AX ← AL×SRC 字运算:DX:AX ← AX×SRC |
无符号乘法运算指令 | MUL SRC | 同IMUL,但不带符号 |
带符号除法运算指令 | IDIV SRC |
字节运算: AL ← AX/SRC 的商 AH ← AX/SRC 的余数 字运算: AX ← DX:AX/SRC 的商 DX ← DX:AX/SRC 的余数 |
无符号除法运算指令 | DIV SRC | 同IDIV,但不带符号 |
-
-
- MUL 指令和 IMUL 指令只提供一个源操作数,可以是除立即数外的任何寻址方式,另一操作数隐含为累加器 AL 或 AX。十六位运算时,结果储存于 DX、AX 中,DX 存放高 16 位,AX 放低 16 位。对除 CF 和 OF 以外的标志位无定义
- DIV 指令和 IDIV 指令的源操作数可以说寄存器或存储器操作数,对所有标志位均无定义。IDIV 指令规定余数符号与被除数符号相同。执行除法指令后。若商超出了表示范围,就会引起 0 类型中断
-
3. 符号扩展指令
-
-
- 字节扩展指令 CBW:将 AL 中的符号位扩展到 AH 中,将一个字节扩展为一个字
- 字扩展指令 CWD:将 AX 中的符号位扩展到 DX 中,将一个字扩展成双字
-
4. 十进制算术运算指令
汇编格式 | 影响的标志位 | 功能说明 | 汇编格式 | 影响的标志位 | 功能说明 |
DAA | AF、CF、PF、SF、ZF | 压缩 BCD 码加法调整指令 | AAS | AF、CF | 非压缩 BCD 码减法调整指令 |
DAS | AF、CF、PF、SF、ZF | 压缩 BCD 码减法调整指令 | AAM | SF、ZF、PF | 非压缩 BCD 码乘法调整指令 |
AAA | AF、CF | 非压缩 BCD 码加法调整指令 | AAD | SF、ZF、PF | 非压缩 BCD 码除法调整指令 |
-
-
- 除 ADD 指令外,其他调整指令要紧跟在对应的算术运算指令后,且需调整的数据要存入寄存器 AL 中,调整结果存于 AL 中,而乘法调整指令则是将调整后的结果储存于 AX 中
- 除法调整指令 ADD 调整工作在除法指令执行前进行,进行调整的寄存器为 AX
-
逻辑运算指令
-
汇编格式 | 功能说明 |
AND DST, SRC OR DST, SRC XOR DST, SRC TEST DST, SRC NOT DST |
逻辑与,DST ← DST∧SRC 逻辑或,DST ← DST∨SRC 逻辑异或,DST ← DST⊕SRC 逻辑测试,DST∧SRC 置各标志位 逻辑非,DST 中各位取反 |
-
-
- TEST 指令可以用来判断某位是否为 0 或 1
-
移位指令
-
指令类型 | 指令功能 | 汇编格式 |
移位指令 | 算术左移/逻辑左移 | SAL/SHL DST, COUNT |
算术右移 | SAR DST, COUNT | |
逻辑右移 | SHR DST, COUNT | |
循环移位指令 | 循环左移 | ROL DST, COUNT |
循环右移 | ROR DST, COUNT | |
带进位的循环左移 | RCL DST, COUNT | |
带进位的循环右移 | RCR DST, COUNT |
-
-
- COUNT 为移位次数,如果移位次数是一次,则可以直接出现在指令中;如果移位次数大于一,则由 CL 寄存器给出
-
串操作指令
-
指令类型 | 汇编格式 | 功能说明 |
串传送指令 | MOVSB | 字节传送 [ES: DI] ← [DS: SI], SI ← SI±1, DI ← DI±1 |
MOVSW | 字传送 [ES: DI] ← [DS: SI], SI ← SI±2, DI ← DI±2 | |
串比较指令 | CMPSB | 字节比较 [DS: DI] ← [ES: SI], SI ← SI±1, DI ← DI±1 |
CMPSW | 字比较 [DS: DI] ← [ES: SI], SI ← SI±2, DI ← DI±2 | |
串搜索指令 | SCASB | 字节搜索 AL-[ES: DI],设置标志位,DI ← DI±1 |
SCASW | 字搜索 AX-[ES: DI],设置标志位,DI ← DI±2 | |
取串指令 | LODSB | 字节操作 AL ← [DS: SI], SI ← SI±1 |
LODSW | 字操作 AX ← [DS: SI], SI ← SI±2 | |
存串指令 | STOSB | 字节操作 [ES: DI] ← AL, DI ← DI±1 |
STOSW | 字操作 [ES: DI] ← AX, DI ← DI±2 |
汇编格式 | 功能说明 |
REP REPE/REPZ REPNE/REPNZ |
当 CX≠0 时,重复执行 MOVS、STOS 和 LODS 指令,CX-1 → CX 当 CX≠0 且 ZF=1 时,重复执行 CMPS、SCAS 指令,CX-1 → CX 当 CX≠0 且 ZF=0 时,重复执行 CMPS、SCAS 指令,CX-1 → CX |
执行串操作指令时应做的准备工作
-
-
- 把源串的首地址/末地址送入 SI 寄存器
- 把附加段中目的串的首地址/末地址送入 DI 寄存器
- 将重复次数(串长度)送入 CX 寄存器
- 设置方向标志 DF。无操作数指令 CLD 可使 DF=0,STD 可使 DF=1
- 对于 STOS 类和 SCAS 类指令,还应给 AX/AL 预置初值
-
程序控制指令
-
寻址方式 | 汇编格式 | 功能说明 |
段内直接转移 | JMP SHORT OPR | (IP) ← (IP)+8 位位移量,段内直接短转移 |
JMP NEAR PTR OPR | (IP) ← (IP)+16 位位移量,段内直接近转移 | |
段内间接转移 | JMP OPR1 |
(IP) ← (EA) OPR1 为 16 位寄存器名或存储器寻址方式 EA 为由 OPR1 指定的有效地址 |
段间直接转移 | JMP FAR PTR OPR |
(IP) ← 目标地址的偏移地址 (CS) ← 目标地址的段地址 |
段间间接转移 | JMP DWORD PTR OPR |
(IP) ← (EA),EA 为由 OPR 指定的有效地址 (CS) ← (EA+2) |
分类 | 汇编格式 | 条件说明 |
简单条件转移指令 |
JC OPR JNC OPR |
CF=1,有进位/有借位转移 CF=0,无进位/无借位转移 |
JS OPR JNS OPR |
SF=1,是负数转移 SF=0,是正数转移 |
|
JO OPR JNO OPR |
OF=1,有溢出转移 OF=0,无溢出转移 |
|
JZ/JE OPR JNZ/JNE OPR |
ZF=1,相等/为 0 转移 ZF=0,不相等/不为 0 转移 |
|
JP/JPE OPR JNP/JPO OPR |
PF=1,有偶数个 1 转移 PF=0,有奇数个 1 转移 |
|
无符号数条件转移指令 | JA/JNBE OPR | CF=0 且 ZF=0,高于/不低于或等于转移 |
JAE/JNB OPR | CF=0 或 ZF=1,高于等于/不低于转移 | |
JB/JNAE OPR | CF=1 且 ZF=0,低于/不高于或等于转移 | |
JBE/JNA OPR | CF=1 或 ZF=1,低于等于/不高于转移 | |
带符号数条件转移指令 | JG/JNLE OPR | SF=OF 且 ZF=0,大于/不小于或等于转移 |
JGE/JNL OPR | SF=OF 或 ZF=1,大于或等于/不小于转移 | |
JL/JNGE OPR | SF≠OF 且 ZF=0,小于/不大于或等于转移 | |
JLE/JNG OPR | SF≠OF 或 ZF=1,小于或等于/不大于转移 |
汇编格式 | 功能说明 |
LOOP OPR LOOPZ/LOOPE OPR LOOPNZ/LOOPNE OPR JCXZ OPR |
(CX) ← (CX)-1,(CX)≠0时,转到 OPR (CX) ← (CX)-1,(CX)≠0 且ZF=1 时,转到 OPR (CX) ← (CX)-1,(CX)≠0 且ZF=0 时,转到 OPR (CX)=0时转到 OPR |
汇编格式 | 功能说明 | 操作 |
CALL NEAR PTR OPR CALL OPR |
段内直接调用 |
(SP) ← (SP)-2 ;修改栈顶指针 ((SP)+1: (SP)) ← (IP) ;保护断点(IP) (IP) ← (IP)+16位位移量 ;CS 不变 |
CALL OPR CALL WORD PTR OPR |
段内间接调用 |
(SP) ← (SP)-2 ;修改栈顶指针 ((SP)+1: (SP)) ← (IP) ;保护断点(IP) (IP) ← (EA) ;CS 不变 |
CALL FAR PTR OPR | 段间直接调用 |
(SP) ← (SP)-2 ;修改栈顶指针 ((SP)+1: (SP)) ← (CS) ;保护断点(CS) (SP) ← (SP)-2 ;修改栈顶指针 ((SP)+1: (SP)) ← (IP) ;保护断点(IP) (IP) ← OPR 偏移地址 ;修改 IP (IP) ← OPR 段地址 ;修改 CS |
CALL DWORD PTR OPR | 段间间接调用 |
(SP) ← (SP)-2 ;修改栈顶指针 ((SP)+1: (SP)) ← (CS) ;保护断点(CS) (SP) ← (SP)-2 ;修改栈顶指针 ((SP)+1: (SP)) ← (IP) ;保护返回地址的 IP (IP) ← ((EA)) ;修改 IP (IP) ← ((EA+2)) ;修改 CS |
RET RETF |
段内/段间子程序返回 | |
RET n RETF n |
带偏移量 n 的段内/段间子程序返回 |
-
-
处理器控制指令
-
汇编格式 | 功能说明 | 汇编格式 | 功能说明 |
CLC STC CMC CLD STD CLI STI |
进位位清 0 指令,(CF) ← 0 进位位置 1 指令,(CF) ← 1 进位位取反指令,(CF) ← (CF)取反 方向标志清 0 指令,(DF) ← 0 中断标志清 0 指令,(IF) ← 0 中断标志置 1 指令,(IF) ← 1 |
HLT WAIT LOCK NOP ESC DATA, SRC |
暂停 等待 总线锁定前置 空操作 外部设备换码 |