Click here to load reader
Upload
adele
View
265
Download
10
Embed Size (px)
DESCRIPTION
第 8 章 寻址方式与指令系统. 8.1 8086/8088 的寻址方式与指令系统. 8.1.1 8086/8088 的寻址方式 1. 寻址方式概述. 寻址方式. 定义 : 指令中如何提供操作数或操作数地址的方式称为寻址方式。 [ 规定如何对地址字段作出解释以找到操作数 ] * 程序转移时需提供转移地址,这跟提供操作数地址在方法上没有本质区别,因此也归入寻址方式的范畴。. 一个指令系统能够提供哪些寻址方式,能否为编制程序提供方便,这是指令系统设计的关键。 - PowerPoint PPT Presentation
Citation preview
第 8 章 寻址方式与指令系统
8.1 8086/8088 的寻址方式与指令系统8.1.1 8086/8088 的寻址方式1. 寻址方式概述
寻址方式 定义 :指令中如何提供操作数或操作数地址的方式称为寻址方式。 [ 规定如何对地址字段作出解释以找到操作数 ]
* 程序转移时需提供转移地址,这跟提供操作数地址在方法上没有本质区别,因此也归入寻址方式的范畴。
一个指令系统能够提供哪些寻址方式,能否为编制程序提供方便,这是指令系统设计的关键。 需要说明的是,在不同的计算机系统中,寻址方式的名称和分类并不统一,但基本可以归结为以下几种方式或它们的变型或组合:
寻址方式的名称和分类 立即寻址(立即数寻址) 寄存器寻址 直接寻址 间接寻址 变址寻址
例如, Z80 系统: 立即寻址 ;直接寻址 立即扩展寻址;零页寻址 隐含寻址;相对寻址 寄存器寻址;变址寻址 寄存器间接寻址;位寻址
两类寻址方式 数据的寻址方式 转移地址的寻址方式 (我们重点讨论数据的寻址方式) 2. 数据的寻址方式
(1) 立即寻址 (Immediate addressing)
指令中直接给出操作数,操作数紧跟在操作码之后,作为指令的一部分存放在代码段里,在取出指令的同时也就取出了操作数,立即有操作数可用,所以称之为立即寻址。
目的 源 example
MOV AL, 80H ; 低地址 存储器 AX
MOV AX, 3064H ; 代 码 ADD AL, 20H ; 段 ADD AX, 1090H; 高地址
OP 6 4
3 0
立即数可以为 8 位,也可以为 16 位。如果是 16 位数,则“高位字节存放在高地址中,低位字节存放在低地址中。” 立即寻址方式常用于给寄存器赋值,并且只能用于源操作数,而不能用于目的操作数。
下述各条指令源操作数的寻址方式也都是立即寻址,但这些指令都是错误的: MOV AL, 256 ; 256=100H ,超过了 AL 能存放的数的范围 MOV AX, -32769 ; -32769 超过了 AX 能存放的带符号数 ( 补码 )范围 MOV 100H, AL ; 立即数不能作为目的操作数 DEC 20 ; 单操作数指令不能使用立即数 MOV DS, 1234H ; 源操作数是立即数,则目的操作数就不能是段寄存器
( 2 ) 寄存器寻址( Register addressing)
操作数在寄存器中,指令中指明寄存器号,这种寻址方式叫寄存器寻址。 对于 8 位操作数,寄存器可以是 AH, AL,BH,BL, CH,
CL, DH, DL .
对于 16 位操作数,寄存器可以是 AX, BX,CX, DX, SI, DI, SP ,BP,CS,DS,ES,SS ( 但 CS 不能作目的寄存器)
EXAMPLE
INC AX ; MOV AX, BX ; DEC AX ; ROL AH , 1 ; 将 AH 中的内容循环左移一位
CF D7 D0
练习: MOV AX , BX ; 正确。指令执行后, AX←BX ,但 BX 不变 MOV AX, BL ; 错误。源和目的的位数不相同 MOV CS, AX ; 错误。 CS 不能作为目的操作数 MOV ES, DS ; 错误。两个操作数不能都是段寄存器
寄存器寻址的特点 ( 1 ) 操作数就在寄存器中 , 不需要访问存储器来取得操作数(指令执行时,操作就在 CPU 的内部进行),因而执行速度快。 ( 2 )寄存器号比内存地址短 * 在编程中,如有可能,尽量使用这种寻址方式的指令。 * 寄存器寻址方式既可用于源操作数,也可用于目的操作数,还可以两者都用于寄存器寻址方式(如 MOV BX , AX )
除以上两种寻址方式外,下面各种寻址方式的操作数均在存储器中,通过采用不同的寻址方式取得操作数地址,从而取得操作数。
( 3 )直接寻址( Direct Addressing)
说明:在讨论寻址方式时,通常把操作数的偏移地址称为有效地址 EA ( Effective Address) , EA 可通过不同的寻址方式来得到。 在直接寻址方式中,指令中直接给出操作数的有效地址,或者说,有效地址 EA 就在指令中。它 ( 操作数的有效地址,而不是操作数本身 ) 存放在代码段中指令的操作码之后,但操作数一般存放在数据段中。
例 1. MOV AX , DS:[2000H] ; 如 (DS)= 3000H, 则指令的执行情况如下图所示:
代 存储器 采用直接寻址方式,如果没 码 有用“段跨越前缀”标明操作 段 数在哪一段,就默认段寄存 为 DS. 30000H 数 AX 据 段 32000H 执行结果: (AX)=3050H
OP 00 20
50 30
当然 , 也允许数据存放在数据段以外的其它段(如附加段 ) 。此时应在指令中给出 “跨越段前缀”。 例 2: 如数据在附加段中,则应指明“段跨越缀” 。 MOV AX , ES : [3000H] 或 ES: MOV AX , [3000H]
* 为了使指令字不要过长,规定双操作数指令不能两个操作数都用直接寻址方式。 如 MOV DS: [2000H] , DS:[3000H]
(4) 寄存器间接寻址 (Register indirect Addressing) 采用寄存器间接寻址方式时,指令中给 出寄存器号
( 寄存器为 BX,BP,SI 和 DI 之一 ), 被指定的寄存器中存放着操作数的有效地址,操作数在存储器中 ( 以寄存器的内容为操作数的有效地址)。 [BX]…….. 对应段寄存器为 DS EA= [BP]…….. ………………… SS [SI]……… …………………..DS [DI]……… ………………….DS
Example
MOV AX , [BX] ; 设 ( DS) = 2000H ,(BX) = 1000H 物理地址= 20000H + 1000H =21000H * 指令中也可以通过 AX ………. “ 段跨越前缀”取得 数 其他段中的数据, 据 例如: 段 MOV AX,ES: [BX] 21000H 指令的执行结果为: (AX) = 50A0H
A0
50
( 5 ) 寄存器相对寻址( Register relative addressing) 操作数的有效地址是一个基址或变址寄存器的内容与指令中指定的 8 位或 16 位位移量( Dis
placement) 之和。 如下图所示:
[BX] 8 位位移量EA = [BP] + [SI] 16 位位移量 [DI] 若没有段跨越前缀,则对于寄存器 BX,SI, DI 的情况,段寄存器为 DS ; 对于寄存器为 BP 的情况,则段寄存器为 SS.
ExampleMOV AX, [SI+3000H] 操设 (DS) = 4000H,(SI)=2000H 作物理地址 码= 40000H+2000H+3000H
位 = 45000H 移指令的执行情况如 量右图 AX 40000H 43000H SI 数 45000H 据 段
OP OP
00
30
…… …… 34 12
这种寻址方式可用于表格的处理,通过位移量来设置表格的首地址; 利用修改基址寄存器或变址寄存器的内容来获得表项的值。
( 6 )基址变址寻址( Based indexed addressing) 操作数的有效地址是一个基址寄存器和一个变址寄存器内容之和,两个寄存器均由指令指定。 [BX] [SI] 若基址寄存器为 BX, 则段寄存器为 D
S
EA = + [BP] [DI] 若基址寄存器为 BP, 则段寄存器为 SS
Example 例: MOV AX,[BX+DI] 设 (DS)=2100H, (BX)=0158H, [DI]=10A5H. 则 EA= 0158H+10A5H=11FDH 物理地址= 21000H+11FDH=221FDH
[BX] 21000H
21158H AX 221FDH
… …
34 12
• 这种寻址方式同样适用于表格 ( 或数组 ) 的处理 , 表的首地址可存放在基址寄存器中,而用变址寄存器来访问表格中的各项。• 由于两个寄存器都可以修改,使 用起来更灵活。
(7 ) 相对基址加变址寻址 (Relative based indexed address~)
也称“带位移量的基址加变址寻址方式” . 操作数的有效地址是一个基址寄存器和一个变址寄存器内容与 8 位或 16 位位移量之和。 [BX] [SI] 用 BX, 则段寄存器为 DS EA= + + 位移量 [BP] [DI] 用 BP, 则段寄存器为 SS
例: MOV AX,[BX+SI+0250H]
设 (DS)=3000H,(BX)=2000H,(SI)=1000H, 则 代 EA = 2000H+1000H+0250H=3250H 码物理地址= 30000H+3250H=33250H 段 30000H 位移量 AX 30250H 数 (BX) 32250H 据 (SI) 33250H 段
OP OP 50 02
… … … 34 12
这种寻址方式可用于访问二维数组。 设数组元素在内存中按行顺序存放(首先放第一行所有元素,再放第二行所有元素,……)。通过改变基址寄存器(如 BX )和变址寄存器(如 SI) 的值可以访问数组中不同行和列上的元素。 如,若保持 BX 不变而 SI 改变,则可以访问同一行的所有元素。 若保持 SI 不变而 BX 改变,则可以访问同一列的所有元素。
数据的寻址方式的寻址过程 ( 图示).
指令数据 寄存器
( 1 )立即寻址
数据指令 寄存器
( 2 )寄存器寻址图 8.1 数据的寻址方式的寻址过程 (1)
EA 数据指令 存储器
( 3 )直接寻址
寄存器 EA
指令 寄存器
( 4 )寄存器间接寻址数据
存储器
图 8.1 数据的寻址方式的寻址过程( 2 )
数据存储器
地址寄存器
寄存器指令
位移量
+EA
( 5 )寄存器相对寻址图 8.1 数据的寻址方式的寻址过程( 3 )
图 8.1 数据的寻址方式的寻址过程( 4 )
数据存储器
基地址寄存器
基址寄存器指令
变址寄存器+
EA
( 6 )基址变址寻址
变址值寄存器
图 8.1 数据的寻址方式的寻址过程( 5 )
数据存储器
基地址寄存器
基址寄存器
指令变址寄存器
+EA
( 7 )基址变址相对寻址
变址值寄存器位移量
端口号 数据指令 端口
( 8 )直接寻址
DX 端口号指令 DX
( 9 )间接寻址
数据端口
图 8.1 数据的寻址方式的寻址过程( 6 )
端口操作数
3. 转移地址的寻址方式( * ) 有关术语和概念 : 段内转移—如果转移地址与该转移类指令在同一个代码段,这样的转移称为段内转移,也称近转移; 近转移时的转移地址只包含偏移地址部分,找到转移地址后,将转移地址送入 IP 即可实现转移 (CS 的内容不必改变 ) 。
段间转移—如果转移地址与该转移类指令位于不同的代码段,这样的转移称为段间转移,也称远转移; 远转移时的转移地址既包含偏移地址部分又包含段基值部分,找到转移地址后,将转移地址的段基值部分送入 CS ,将转移地址的偏移地址部分送入 IP 即可实现转移。
直接转移—如果转移地址直接放在指令中,则这样的转移称为直接转移,视转移地址是绝对地址还是相对地址 ( 即地址位移量 )又可分别称为绝对转移和相对转移。 间接转移—如果转移地址间接放在其他地方,则这样的转移称为间接转移,视转移地址是在寄存器中还是在存储器中又可分别称为寄存器操作数 ( 寄存器寻址 )和存储器操作数 ( 存储器寻址 ) 。
以 JMP 指令为例,可将转移地址的各种寻址方式列出,如表 8-2 所示。
表 8- 2 转移地址的寻址方式 段内转移例 段间转移例
直接转移( L 为标号) 转移地址在指令中(近标号) 转移地址在指令中(远标号)JMP L (近) JMP FAR PTR L (远 )
寄存器操作数 转移地址在通用字寄存器中 无JMP AX
间接转移
存储器操作数
直接寻址JMP WORD PRT DS : [20] JMP DWORD PTR DS: [20]
间接寻址
寄存器间接寻址 转移地址在“ BX, BP, SI, DI 之一”中JMP [BX] JMP DWORD PTR [BX]
寄存器相对寻址 转移地址在“ BX, BP, SI, DI 之一 + 位移量”中JMP [BX+20] JMP DWORD PTR [BX+20]
基址变址寻址 转移地址在“ BX, BP 之一+ SI, DI 之一”中JMP [BX+SI] JMP DWORD PTR [BX+SI]
基址变址相对寻址 转移地址在“ BX, BP 之一+ SI, DI 之一+位移量”中JMP [BX+SI+20] JMP DWORD PTR
[BX+SI+20]
(1) 段内直接转移 ( 直接近转移 )
特点: 转移地址 ( 通常就是近标号 ) 直接包含在汇编形式的转移指令中,转移指令的机器代码中存放的是该标号与当前 IP 值的差 ( 标号 -IP) ,此差称为位移量,该位移量与转移指令一起存于代码段: 位移量被放在转移指令的操作码之后,也是“高字节放在高地址单元,低字节放在低地址单元”。 在取转移指令时,此位移量即作为转移指令的一部分被取入 CPU 中。
执行转移指令时,将这个位移量加到 IP 上即可得到转移地址 ( 标号的值 ) ,即 IP+( 标号 -IP)= 标号 = 转移地址 而不必为找这个转移地址再去访问寄存器或存储器。 例如,如果 L 是本段中的标号,则下述指令采用的是段内直接转移方式: JMP L; 机器指令中的位移量为 L-IP ,转移地址为 L
(2) 段内间接转移 ( 间接近转移 )
① 寄存器操作数 ( 也称寄存器寻址 ) 例: JMP BX ; BX 的内容为转移地址② 存储器操作数 ( 也称存储器寻址 ) (i) 直接寻址 其特征是: 转移地址 ( 偏移地址部分 ) 在数据存储单元中,数据存储单元的地址在指令中直接给出。 例如, JMP WORD PTR DS:[ 20] ; 数据存储单元 (DS:2
0) 的一个字为转移地址
(ii) 寄存器间接寻址 其特征是: 转移地址 ( 偏移地址部分 ) 在数据存储单元中,数据存储单元的偏移地址在 BX、 BP、 SI、
DI 之一中。 例如,下述指令采用的就是段内间接转移、寄存器间接寻址方式: JMP[ BX] ; 数据存储单元 (DS:BX) 的一个字为转移地址 JMP[ BP] ; 数据存储单元 (SS:BP) 的一个字为转移地址 JMP DS:[ BP] ; 数据存储单元 (DS:BP) 的一个字为转移地址
(iii) 寄存器相对寻址 其特征是: 转移地址 ( 偏移地址部分 ) 在数据存储单元中,数据存单元的偏移地址是寄存器 (BX、 BP、 SI、
DI 之一 ) 的内容与位移量的和。 例如,下述指令采用的就是段内间接转移、寄存器相对寻址方式: JMP[ BX+20] ; 数据存储单元 (DS:BX+20) 的一个字为转移地址 JMP[ BP+20] ; 数据存储单元 (SS:BP+20) 的一个字为转移地址 JMP DS:[ BP+20 ] ; 数据存储单元 (DS:BP+20) 的一个字为转移地址
(iv) 基址变址寻址 其特征是: 转移地址 ( 偏移地址部分 ) 在数据存储单元中,数据存储单元的偏移地址是基址寄存器 (BX、 BP 之一 ) 的内容和变址寄存器 (SI、 DI 之一 ) 的内容之和。 例如,下述指令采用的就是段内间接转移、基址变址寻址方式: JMP[ BX+SI] ; 数据存储单元 (DS:BX+SI) 的一个字为转移地址 JMP[ BP+SI] ; 数据存储单元 (SS:BP+SI) 的一个字为转移地址 JMP DS:[ BP+SI ] ; 数据存储单元 (DS:BP+SI) 的一个字为转移地址
(v) 基址变址相对寻址 其特征是: 转移地址 ( 偏移地址部分 ) 在数据存储单元中,数据存储单元的偏移地址是基址寄存器 (BX、 BP之一 ) 的内容、变址寄存器 (SI、 DI 之一 ) 的内容及位移量的和。 例如,下述指令采用的就是段内间接转移、寄存器间接寻址方式: JMP[ BX+SI+20] ; 数据存储单元 (DS:BX+SI+20) 的一个字为转移地址 JMP[ BP+SI+20] ; 数据存储单元 (SS:BP+SI+20) 的一个字为转移地址 JMP DS:[ BP+SI+20 ] ; 数据存储单元 (DS:BP+SI+20) 的一个字为转移地址
(3) 段间直接转移 ( 直接远转移 )
转移地址 ( 通常就是远标号 ) 直接包含在汇编形式的转移类指令中,也直接存放在转移类指令的机器代码中,它是转移类指令不可分割的一部分,位于转移类指令的操作码之后: 高字存放转移地址的段基值部分,低字存放转移地址的偏移地址部分。在取转移类指令时,此段基值和偏移地址作为转移类指令的一部分被取入 CPU 中,执行转移类指令时,不必为找转移地址再去访问寄存器或存储器。
例如,如果 L 是其他代码段中的标号,则下述指令采用的就是段间直接转移方式: JMP FAR PTR L ; 在 L 左边通常要加上类型说明 FAR PTR
(4) 段间间接转移 ( 间接远转移 )
段间间接转移时的转移地址既包含偏移地址部分,又包含段基值部分,在数据存储器中占两个字:低字单元存放偏移地址,高字单元存放段基值。 要在转移类指令中的地址表达式左边加上类型说明 D
WORD PTR 。例如, JMP DWORD PTR B ;〈 1〉 直接寻址 JMP DWORD PTR DS:[ 20] ;〈 2〉 直接寻址 JMP DWORD PTR [ BX] ;〈 3〉 寄存器间接寻址 JMP DWORD PTR [ BX+B] ;〈 4〉 寄存器相对寻址 JMP DWORD PTR [ BX+20] ;〈 5〉 寄存器相对寻址 JMP DWORD PTR [ BX+SI] ;〈 6〉 基址变址寻址 JMP DWORD PTR [ BX+SI+B] ;〈 7〉 基址变址相对寻址 JMP DWORD PTR [ BX+SI+20] ;〈 8〉 基址变址相对寻址
指令转移地址 寄存器
( 1 )直接转移
转移地址指令 寄存器
( 2 )寄存器间接转移图 8.2 转移地址的寻址方式的寻址过程 (1)
EA 转移地址指令 存储器
( 3 )直接寻址
寄存器 EA
指令 寄存器
( 4 )寄存器间接寻址转移地址存储器
图 8.2 转移地址的寻址方式的寻址过程( 2 )
转移地址存储器
地址寄存器
寄存器指令
位移量
+
EA
( 5 )寄存器相对寻址图 8.2 转移地址的寻址方式的寻址过程( 3 )
图 8.2 转移地址的寻址方式的寻址过程( 4 )
转移地址存储器
基地址寄存器
基址寄存器指令
变址寄存器+
EA
( 6 )基址变址寻址
变址值寄存器
图 8.2 转移地址的寻址方式的寻址过程( 5 )
转移地址存储器
基地址寄存器
基址寄存器指令变址寄存器
+
EA
( 7 )基址变址相对寻址
变址值寄存器位移量
8.1.2 8086/8088 指令系统 可以分为以下六类(四类): 传送指令 算术运算指令 逻辑运算和移位指令 运算类 串操作指令 转移指令 处理器控制指令
一、传送指令 包括 : 通用传送指令和专用传送指令两类1. 通用传送指令:
名称 格式 类型 操作传送交换入栈出栈
MOV 目的,源XCHG 操作数 1 ,操作数2PUSH 源字 POP 目的字
B/WB/WWW
( 目的 )←( 源 )( 操作数 1) ←→ ( 操作数 2)SP ←SP-2, (SS:SP) ←( 源 )字( 目的 )字 ← (SS:SP), SP ←SP+2
(1) MOV 指令 立即数
存储器直接寻址寄存器间接寻址寄存器相对寻址基址变址寻址基址变址相对寻址
通用寄存器AX BX CX DXSI DI SP BPAL BL CL DLAH BH CH DH段寄存器
DSESSS
CS
例 : MOV AL, BL MOV [DI], AX MOV CX, DS:[1000H] MOV BL, 40 MOV WORD PTR[SI] , 01H BYTE PTR 字节长度标记WORD PTR 字长度标记DWORD PTR 双字长度标记 标志:所有通用传送指令都不影响标志位。
练习 1
用 MOV 指令实现两内存字节单元内容的交换 2035H
2045H
01H ….
02H
用直接寻址方式实现 MOV BL, DS:[2035H]
MOV CL, DS:[2045H]
MOV DS:[2045H], BL
MOV DS:[2035H], CL
HLT
用寄存器间接寻址方式实现 MOV SI , 2035H
MOV DI, 2045H
MOV AH, [SI]
MOV AL, [DI]
MOV DS:[2035H] ,AL
MOV DS:[2045H] ,AH
练习 2
把数据块 BLOCK1 移到 BLOCK2 2040H 2060H
把 2040H 地址开始的 10 个字节数据移到 2060 地址开始的 10 个字节单元处。
BLOCK1 BLOCK2
ANSWER
MOV SI, 2040H ; MOV DI, 2060H ; MOV CX, 0AH; LOOP1: MOV BL, [SI+09H]; MOV [DI+09H],BL ; DEC SI ; DEC DI ; DEC CX ; JNZ LOOP1; HLT
练习 3
把 2040H 地址开始的 10 个字节单元的内容与2060H 地址开始的 10 个字节单元内容互换。
…… MOV BL,[SI+09H] MOV AL,[DI+09H] MOV [SI+09H],AL MOV [DI+09H],BL ……
(2)PUSH 指令和 POP 指令 堆栈的图示: 压入:格式 PUSH SRC (SS) 先修改指针 : SP SP-2 后压入 : (SP+1,SP) SRC
(SP) 弹出:格式 POP DST 栈顶 先弹出: DST (SP+1,SP) 压 弹 后修改指针: SP SP+2 入 出高地址 栈底
…
最后一项
( 3 ) XCHG 指令(交换指令) 格式: XCHG OPR1, OPR2 操作: OPTR1 OPTR2 标志: O D I T S Z A P C - - - - - - - - -例: XCHG AL,BL; XCHG BX,CX; XCHG DS:[2530H], CX;
XCHG 指令允许的操作数及数据传送方向 存储器
直接寻址寄存器间接寻址寄存器相对寻址基址变址寻址基址变址相对寻址
通用寄存器AX BX CX DXSI DI SP BPAL BL CL DLAH BH CH DH
练习 1
用 XCHG 指令改进前面的数据块交换程序:
MOV BL , [SI +09H] XCHG BL , [DI+09H] MOV [SI+09H] , BL
练习 2
设 BX=1234H , DS=2000H ,字单元 (21234H)=5678H ,指令 “ XCHG BX, [ BX ]” 执行后, BX= ,字单元 (21234H)= 。 由于交换后 BX 的内容被改变,所以 (DS:BX) 成为存储单元 25678H 的内容 ( 不再是存储单元 21234H 的内容 ) ,是未知的。
2. 专用传送指令 专用传送指令有 15条,可分为标志传送、查表、地址传送、符号扩展、输入 /输出和串传送类共六种,它们的名称、书写格式、完成的操作及操作类型如下表所示。
专用传送指令 ( 1 )名称 格式 类型 操作
标志传送
标志入栈 PUSHF W SP ←SP-2, (SS : SP) ←Flag
出栈到标志 POPF W Flag←(SS : SP), SP ←SP+2
标志送 AH LAHF B AH←Flag低 8 位AH送标志 SAHF B Flag低 8 位← AH
查表 查表 XLAT 或 XLATBXLAT 段寄存器:变量名 B
BAL ←(DS : BX+AL)AL ←( 段寄存器: BX+AL)
地址传送
传送有效地址 LEA 16 位 Reg, Mem W 16 位 Reg←Mem 的有效地址地址指针送寄存器及 DS
LDS 16 位 Reg, 双字 Mem
W 16 位 Reg←(Mem)低字DS ←(Mem)高字
地址指针送寄存器及 ESLES 16 位 Reg, 双字 Mem
W 16 位 Reg ←(Mem)低字ES ←(Mem)高字
专用传送指令 ( 2 ) 续表名称 格式 类型 操作
符号扩展 字节扩展位字字扩展为双字 CBWCWD
B W
AH 的各位← AL 的最高位DX 的各位← AX 的最高位
输入输出 输入 IN Ac, 端口号 B/W Ac ←(端口 ), 端口号: 0~0FFH
IN Ac, DX B/W Ac ←(DX), DX : 0~0FFFFH
输出 OUT 端口号 , Ac
B/W (端口 ) ← Ac , 端口号: 0~0FFH
OUT DX, Ac B/W (DX)←Ac, DX : 0~0FFFFH
专用传送指令 ( 3 ) 续表名称 格式 类型 操作
串传送类
串传送 MOVSB B (ES : DI)字节 ← (DS : SI)字节DF=0 时 SI←SI+1, DI←DI+1DF=1 时 SI←SI- 1, DI←DI -1
MOVSW W (ES : DI)字 ← (DS : SI)字DF=0 时 SI←SI+2, DI←DI+2DF=1 时 SI←SI- 2, DI←DI -2
*MOVS 目的,源 B/W 略串存储( 存入串)
STOSB B (ES : DI)←AL若 DF=0, 则 DI←DI+1若 DF=1, 则 DI←DI- 1
STOSW W (ES : DI)←AX若 DF=0, 则 DI←DI+2若 DF=1, 则 DI←DI- 2
*STOS 目的 B/W 略
专用传送指令 ( 4 ) 续表名称 格式 类型 操作
串传送类 串装入( 从串取)
LODSB B AL ←(DS:DI)若 DF=0, 则 SI←SI+1若 DF=1, 则 SI←SI- 1
LODSW W AX ←(DS:DI)若 DF=0, 则 SI←SI+2若 DF=1, 则 SI←SI- 2
*LODS 源 B/W 略
(1) 标志传送指令标志传送指令共 4条: PUSHF POPF LAHF ;AH Flag 的低 8 位 SAHF ;Flag 的低 8 位 AH
例:将 8086 标志寄存器的 TF 位置 “ 1”
(2)查表指令 查表指令 XLAT 将以 BX+AL 为偏移地址的内存单元中的一个字节送到 AL 中。 在使用 XLAT 指令前,应先在内存中建立一个字节数据表,表的首字节的偏移地址要事先存入 BX ,表中待查的数据相对于表开始处的位移量也要事先存入 AL 。 指令执行时,会将 BX 的内容与 AL 的内容相加,用得到的数作为偏移地址,以 DS 为段地址,将该地址处存储单元中的内容 (字节 ) 取到 AL 中。
例如,如果 B 为数据段中一组字节变量的开始地址,则执行下列程序段后, AL=66H 。 B DB 3FH , 06H , 5BH , 4FH , 66H ; 数据段中的数据表 DB 6DH, 7DH, 07H, 7FH, 6FH MOV BX , OFFSET B ; 使 BX 中存放数据表首字节的偏移地址 MOVAL , 4 ; 使 AL 中存放欲查单元的地址位移量 4
XLAT ; 查表得到的内容 (字节 ) 在 AL 中 在此例中,数据表中存放的数据恰好是共阴极数码管的输入信号
(参见表 4-1) ,所以,只要事先在 AL 中放好一个十进制数码 (0~9) ,就能通过上述程序段得到数码管的相应输入信号。
(3) 地址传送指令 地址传送指令有 LEA、 LDS 和 LES共 3条 :
LEA (Load Effective Address) LDS (Load pointer into register and DS)
LES (Load pointer into register and ES)
( i )取有效地址指令 格式: LEA REG , SRC; 操作: REG SRC;
* 指令功能: 将源操作数的有效地址 EA传送到目的操作数,目的操作数为一个 16 位的通用寄存器。
例: LEA BX , [BX+DI+6H]
若指令执行之前 (BX)=1000H, (DI)=0200H, 则指令执行之后 , (BX)=1206H
注意与指令 MOV BX,[BX+DI+6H]功能上的区别 从变量的角度,“ LEA AX,VAR” 指令传送的是变量的地址,而“ MOV AX,VAR” 指令传送的是变量的值。
练习 如果 TABLE 为数据段中 0032H 单元的符号名,其中存放的内容为 1234H, 当执行指令 “ MOV AX , TABLE” 后 ,(AX)=
; 而执行指令 “ LEA AX , TABLE” 后 ,(AX) =
.
( ii ) LDS REG , SRC
操作: REG (SRC) DS (SRC+2) 标志: - - - - - - - - -
指令 功 能:将地址指针 (共 4 个字节)装入 DS 和另一个非段寄存器。其中: 前两个字节 ( 偏移量) 非段寄存器 后两个字节 ( 段基址 ) DS
Example
例 1. LDS DI , DS:[2130H] 设 (DS)=3000H
32130H DI DS
偏移量 段基址
(iii) LES REG , SRC
操作: REG (SRC) ES (SRC+2)
* LDS 和 LES 指令为切换数据段提供了方便。
(4) 符号扩展指令 符号扩展指令有 CBW 和 CWD共两条。 其中, CBW 指令将 AL 中的 8 位带符号数扩展为 16位并送入 AX 中。 实际上就是将 AL 的最高位送入 AH 的所有各位。 CWD 指令将 AX 中的 16 位带符号数扩展为 32 位并送入 DX 和 AX 中 ( 其中 DX 存放高 16 位, AX 存放低 1
6 位 ) 。 实际上就是将 AX 的最高位送入 DX 的所有各位。
CBW 和 CWD 两条指令通常只对带符号数使用。 CBW 指令只能对 AL 的内容进行扩展,扩展后 AL 的内容不变但占用 AH ; CWD 指令只能对 AX 的内容进行扩展,扩展后 AX 的内容不变但占用 DX 。
例如: 若 AX=379AH, 则执行完 CBW 指令后, AX=FF9AH ,若执行的是 CWD 指令,则 DX=0000H , AX=379A H ; 若 AX=977AH, 则执行完指令 CBW 后, AX=007AH ,若执行的是 CWD 指令,则 DX=FFFFH , AX=977AH 。
(5) 输入输出指令 <1> 直接输入输出指令格式: IN AL, PORT ; 操作 :AL (PORT)
IN AX, PORT; AX (PORT+1,PORT)
OUT PORT,AL; (PORT) AL
OUT PORT,AX; (PORT+1,PORT) AX注: PORT 为输入输出端口号,范围为 0~ 255(00~FFH)
<2> 间接输入输出指令格式: IN AL, DX; 操作: AL (DX)
IN AX, DX; AX (DX+1,DX)
OUT DX,AL; (DX) AL
OUT DX,AX; (DX+1,DX) AX
在间接输入输出指令之前,需将端口号 DX. MOV DX,XXXXH;
输入输出指令格式(机器码) 输入指令: 0:8 位传送 只出现于直接输入 1:16 位传送 输出指令
0-直接输入指令(长形) 1-间接输入指令 (短形)
1 1 1 0 1 0 W PORT
输出指令 只出现于长形…
0 (长形 ) 1(短形)
1110 11 W PORT
输入输出指令的使用IIN 指令:用于从数据端口输入数据或从状态端口输入状 态字 . 例: IN AL , 28H; LOP : IN AL, 27H;
MOV DS:[2000H] ,AL; TEST AL,01H;
JNZ LOP ………
OOUT 指令:用于输出数据或命令给指定的 I/O端口例 例 1 MOV AL , [SI] OUT 80H , AL ; 设 80H 为数据口的口地址
例 2 MOV DX , 280H ;设 280H 为控制口的口地址 MOV AL , 01H OUT DX , AL
(6) 串传送类指令 串传送类指令有 MOVS、 STOS 和 LODS共 3条,每一条又有 3 种形式。 第一条指令: 串传送指令 (MOVS) 串传送指令 MOVS完成两个存储单元之间的传送,传送后会自动修改有关的变址寄存器。
MOVS 指令有 3 种形式: “MOVSB” 、“ MOVSW” 和 “ MOVS 目的,源”。 “MOVSB” 指令将源存储单元 (DS:SI) 的一个字节传送到目的存储单元 (ES:DI) 的一个字节中。 若 DF=0 ,则传送后 SI←SI+1 , DI←DI+1 ;若 DF=1 ,则传送后 SI←SI-1 , DI←DI-1 。 “MOVSW” 指令将源存储单元 (DS:SI) 的一个字传送到目的存储单元 (ES:DI) 的一个字中。 若 DF=0 ,则传送后 SI←SI+2 , DI←DI+2 ;若 DF=1 ,则传送后 SI←SI-2 , DI←DI-2 。
串传送指令的应用例 将内存 1000H 地址开始的 100 个字节数据向高地址方向移动一个字节的位置。
参考答案 MOV AX , DS MOV ES , AX MOV SI , 1063H MOV DI , 1064H MOV CX , 64H STD REP MOVSB HLT
思考:向低地址方向移动两个字节位置。
第二条指令:串存储指令 STOS( 写串) 串存储指令 STOS 将累加器 AL 或 AX 的内容传送至目的存储单元 (ES:DI) 中。传送后自动修改 DI 寄存器的值。 该指令前面加上重复前缀 REP 后,可以使一段内存单元中填满相同的值。
第三条指令:串装入指令 LODS(读串) 串装入指令 LODS 将源存储单元 ( DS:SI) 的内容传送至累加器 AL 或 AX 中。传送后会自动修改变址寄存器
SI 的内容。 因为累加器在每次重复时都被重写,只有最后一个元素被保存下来,故这条指令前一般不加重复前缀,而常用在循环程序段中,和其他指令结合起来完成复杂的串操作功能。
二、运算类指令 二进制算术运算指令 BCD 数运算指令 逻辑运算和移位指令
1. 算术运算指令 (1) 二进制加法和减法指令 名称 格式 操作 加法 ADD DST,SRC DST SRC+DST
带进位加法 ADC DST,SRC DST SRC+DST+CF
减法 SUB DST, SRC DST DST- SRC
带借位减法 SBB DST,SRC DST DST-SRC-CF 标志: O D I T S Z A P C 所有状态标志都受影响 ×--- ×××××
Example 1 编写实现下列二进制运算的程序段 W X+Y+24- Z(X,Y,Z 均为字变量) MOV AX, X ; ADD AX, Y ; ADD AX, 24 ; SUB AX, Z; MOV W, AX;
Example 2 双倍精度运算 ( 操作数的长度为双字-- 两个 16 位 ) 2000H 3000H 低 16 位 低 16 位 高 16 位 高 16 位 把 2000H 地址开始的两个字 (低字在前 ) 和 3000H 地址开始的两个字相加,和存放在 2000H开始处。
程序段 MOV SI , 2000H ; 取第一个数的首地址 MOV AX, [SI] ; 将第一个数的低 16 位送 AX MOV DI ,3000H ; 取第二个数的首地址 ADD AX, [DI] ; 第一个数的低 16 位和第 2 个数 的低 16 位相加 .
( 不加 CF, 但此条指令的执行影响 CF) MOV [SI],AX ; 存低 16 位相加结果 MOV AX, [SI+2] ADC AX,[DI+2] ; 两个高 16 位连同 CF(低 16 位相加形成的 ) 相加 .
MOV [SI+2],AX ; 存高 16 位相加结果 .
思考: 以上是双字 ( 双倍精度)相加,如果更多字 ( 多倍精度 ) 相加,这个程序将如何设计?
例 3 : 假设数的长度 ( 以字计 ) 存放 于 2500H字节单元,两个无符号二进制数分别 从 2000H 和 3000H开始存放
(低字在前 ),求两数之和并存放于 2000H开始处,试编程实现。
参考答案 MOV CL , DS:[2500H] MOV SI , 2000H MOV DI , 3000H CLC ; 清 CF LOOP1: MOV AX , [SI] ADC AX , [DI] MOV [SI] , AX INC SI INC SI INC DI INC DI DEC CL JNZ LOOP1 MOV AX , 0H ; ADC AX , 0H ; 处理最高位产生的进位 MOV [SI] , AX ; HLT
(2) 加 1 减 1 和比较指令名称 格式 操作加 1 INC OPR OPR OPR+1减 1 DEC OPR OPR OPR-1求补 (Negate) NEG OPR OPR -OPR比较 CMP OPR1,OPR2 OPR1-OPR2
标志: INC 和 DEC: O D I T S Z A P C × - - - ×××× - NEG 和 CMP: × - - - ×××××
NEG 指令 NEG 指令把操作数当成一个带符号数,如果原操作数是正数, NEG 指令则将其变成负数 ( 用补码表示);如果原操作数是负数 ( 用补码表示), NEG 指令则将其变成正数。 方法:“各位 (包括符号位 )求反,末位加 1”.
Example
* 若 AL=00010001B=+17, 执行 NEG AL 后, AL=11101111B=[- 17] 补
* 若 AL=11010001B=[- 47] 补,执行 NEG AL 后, AL=00101111B=+47
比较指令 比较指令实际上是做减法,但不回送相减的结果,只是根据结果置标志。通常,把 CMP 指令安排在条件转移指令 ( 如 JZ , JG , JO 等)之前。 例:如果 X>50, 转移到 TOO-HIGH; 如果带符号减法 X- Y引起溢出,则转移到 OVERFLOW; 否则,计算 X-Y , 并将结果存放在 RESULT 中。 (其中, X、 Y、 RESULT 均为字变量)。
程序段 下述程序段使用了前面介绍的几条指令,也用到了后面即将介绍的条件转移指令 . MOV AX , X ; 将 (X) 移入 AX CMP AX , 50 ; 比较 JG TOO-HIGH ; 如果 (X)大于 50, 则转向 TOO-HIGH SUB AX, Y ; 否则减去 (Y) JO OVERFLOW ;溢出则转移 JNS NONNEG NEG AX NONNEG: MOV RESULT , AX ; 无溢出,取绝对值,并将结果存入 RESULT … TOO-HIGH: … OVERFLOW: …
(3) 乘法指令(i) 带符号乘法 格式: IMUL SRC 所执行的操作: 字节操作数 : AX (Al)*(SRC) 字操作数: DX:AX (AX)*(SRC) (乘积带符号,并符合一般代数符号规则) (ii) 无符号乘法 格式: MUL SRC 所执行的操作: 同 IMUL, 但操作数和乘积均不带符号。
(4) 除法指令 带符号除法 格式: IDIV SRC 所执行的操作: 字节除数: AL (AX)/(SRC) 之商 AH (AX)/(SRC) 之余数 字除数: AX (DX:AX)/(SRC) 之商 DX (DX:AX)/(SRC) 之余数 商和余数是带符号的:商的符号符合一般代数符号规则,余数的符号与被除数相同 . 无符号除法 格式: DIV SRC 所执行的操作: 与 IDIV 相同,但操作数,商和余数均是无符号的。
例:二进制四则混合算术运算程序段 试计算: AX (V-(X*Y+Z-540))/X 之商 DX 余数(其中, X , Y , Z , V 均为字变量)
PROGRAM MOV AX, X ; IMUL Y ; X*Y, 结果在 DX:AX 中 MOV CX, AX; MOV BX, DX; 将乘积存在 BX:CX 中 MOV AX, Z; CWD ADD CX, AX ; 将符号扩展后的 Z 加到 BX:CX 中的乘积上去 ADC BX, DX; SUB CX, 540; SBB BX, 0; 从 BX:CX 中减去 540 MOV AX, V; CWD; SUB AX, CX; 从符号扩展后的 V 中减去 (BX:CX) 并 SBB DX, BX; 除以 X,商在 AX 中,余数在 DX 中。 IDIV X;
2. BCD 数运算指令 所谓 BCD 数,就是二进制编码的十进制数 (Binary Cod
ed Decimal), 它是用 4 位二进制码表示一位十进制数 (0000~ 1001 是合法 BCD 码; 1010~ 1111 是非法 BCD 码 ).
组合 BCD 数:用一个字节表示 2 位 BCD 数 例: 37 分离 BCD 数:用一个字节的低 4 位表示一位 BCD 数,高 4 位为 0. 例: 37
0011 0111
0000 0011 0000 0111
(1) 组合 BCD 数十进制调整原理 例 1 : 18 + 7 = 25 0 0 0 1 1 0 0 0 - - - - - - - - 18 + 0 0 0 0 0 1 1 1 - - - - - - - - 7 0 0 0 1 1 1 1 1 - - - - - - - - ? (1111 是非法 BCD 码) 需要对结果进行变换 (调整 ), 方法:“加 6调整” 0 0 0 1 1 1 1 1 + 0 0 0 0 0 1 1 0 0 0 1 0 0 1 0 1 - - - - - - - - 25( 正确结果 ) 第 3 位向第 4 位 (低半字节向高半字节 ) 有进位, AF=1
在非法 BCD 码上“加 6” ,产生向高一位数字的进位: 加法器实际上是按二进制运算 “满 16 进一” 但进到了 BCD 数的高位 “ 进 1 当 10” (少 6) 可见,在 BCD 码结果中,只要一位 BCD 数字所对应的二进制码超过 9(1010~1111), 就应“加上 6” ,产生进位,进行调整。 这可由软件 (调整指令 ) 来完成。
例 2 : 19 + 8 = 27 0 0 0 1 1 0 0 1 --------- 19 + 0 0 0 0 1 0 0 0 --------- 8 0 0 1 0 0 0 0 1----------21( 结果不对 ) 运算时,低位数字向高位数字产生了进位 (AF=1 或 CF=1),实际上是“满 16 进一”,但进到高位,当成了 10, “少 6” ,需“加 6调整”。 0 0 1 0 0 0 0 1 + 0 0 0 0 0 1 1 0 0 0 1 0 0 1 1 1-----------27( 结果正确) 可见,在 BCD 数运算时,若 AF=1( 或 CF = 1) 就需在低 4 位 ( 或高 4 位 ) 上进行“加 6调整”。
BCD 数十进制调整规则 BCD 数加法十进制调整规则: 如果两个 BCD 数字相加的结果是一个在 1010~ 1111之间的二进制数,或者有向高一位数字的进位 (AF=1或 CF=1), 则应在现行数字上加 6(0110B)调整。• BCD 数减法十进制调整规则: (1) AF=1, 或运算结果的低位是一个在 1010~ 1111 之间的二进制数,则在低位上要进行- 6调整。 (2) CF=1, 或运算结果的高位是一个在 1010~ 1111 之间的二进制数,则在高位上要进行- 6调整。
(2) 组合 BCD 数十进制调整指令 加法的十进制调整指令 : 格式: DAA 操作: AL AL 中的和数调整到组合 BCD 格式 减法的十进制调整指令: 格式: DAS 操作: AL AL 中的差数调整到组合 BCD 格式 DAA-- Decimal Adjust for Addition DAS-- Decimal Adjust for Subtraction 标志: O D I T S Z A P C U --- ×××××
例:计算 BCD3 BCD1+BCD2
其中, BCD1 , BCD2, BCD3 定义为字变量,可分别存放 4 位数字的组合 BCD 数。 假定字变量 BCD1 的值为 1834 ,字变量 BCD2 的值为 2
789, 指出执行每条指令的操作及执行指令后 AL, AF, CF 的内容。
3 4 1 8
8 9 2 7
2 3 4 6
BCD1
BCD1+1
BCD2
BCD2+1
程序段 指令 操作 AL CF AFMOV AL, BCD1; AL 34 34 - - 不受影响ADD AL, BCD2 ; AL 34+89 BDH 0 0DAA ; 调整 23 BCD 1 * 无关紧要MOV BCD3,AL; (BCD3) 23 23 1 *MOV AL, BCD1+1; AL 18 18 1 *ADC AL, BCD2+1; AL 18+27+CF 40H 0 1DAA ; 调整 46 BCD 0 *MOV BCD3+1,AL; (BCD3+1) 46 46 0 *
即 1834 + 2789 = 4623
组合 BCD 数 8086 没有组合 BCD 数的乘法和除法调整指令,主要原因是相应的调整算法比较复杂,所以, 8086 不支持组合 BCD 数的乘除法运算。 如果要处理组合 BCD 数的乘除法问题,可以把操作数
( 组合 BCD 数 )变换成相等的二进制数,然后用二进制算法进行运算,运算完成后再将结果转换成 BCD 数。
(3) 分离 BCD 数调整指令 加法调整指令 (AAA) 减法调整指令 (AAS) 乘法调整指令 (AAM) 除法调整指令 (AAD)
* 直接由 8086 指令实现的算术运算一览 加法 减法 带符号 乘法 除法 二进制 加法 减法 无符号 乘法8086 算术指令 除法 组合 BCD 加法 减法 分离 BCD 加法 * BCD 数均作无符号看待 , 减法 符号位单独处理 。 乘法 除法
3. 逻辑运算和移位指令 (1) 逻辑运算指令名称 格式 操作非 NOT OPR OPR OPR或 OR DST,DST DST DST V SRC 与 AND DST,SRC DST DST SRC异或 XOR DST,SRC DST DST SRC测试 TEST OPR1,OPR2 OPR1 OPR2
(2) 移位指令 名称 格式 操作 逻辑左移 SHL OPR,CNT 0 ( 其中, OPR 是除立即数以外的任何一种寻址方式,
CNT 可以是 1 或 CL)
算术左移 SAL OPR,CNT 0 左移 1 位时,若最高位 ( 即符号位 )发生改变( 0 1 或
1 0) ,则 OF=1,未发生改变时, OF = 0 ; 逻辑右移 SHR OPR,CNT 0 算术右移 SAR OPR,CNT
CF
CF
CF
CF
逻辑移位: 把操作数作为无符号数进行移位。 右移时,最高位补 0 ;左移时,最低位补 0 。 算术移位: 把操作数作为有符号数进行移位。 右移时,最高位保持不变;左移时,最低位补 0 。
(3) 循环移位指令 不带进位的循环左移 ROL OPR ,CNT
不带进位的循环右移 ROR OPR , CNT
CF
CF
带进位的循环左移 RCL OPR , CNT
带进位的循环右移 RCR OPR , CNT
CF
CF
移位指令的应用 用来改变数据格式,有时用来提供程序 控制功能 ( 例如根据移位后的 CF状态作 JC 或 JNC 转移,或一些专门的运算功能。 注意:左移 n 位与乘以 2 (n)等效,例如: 6×2 (2) = 00000110×100 = 00011000 同样,右移 n 位与除以 2(n)等效,如果是逻辑右移,除法是无符号的;如果是算术右移,则除法是带符号的。 (保持最高位不变,并做符号的扩展)
例 1 :编程实现将 AL 中的数乘以 10(求 10x)
SAL AL, 1 ; 将 AL 中数左移 1 位,得 2x
MOV BL, AL ; 2x保存在 BL 中 . MOV CL, 2 ; 移位次数送入 CL SAL AL, CL ; 2x 左移 2 位,得 8x
ADD AL, BL ; 2x 加上 8x,AL 中为 10x
例 2 :把从 UNPACKED 开始的 16 位分离 BCD 数转换成组合 BCD 数,并把结果存在从 PACKED 开始的单元里。 UNPACKED PACKED 0000 4
0000 5 0000 6 0000 7 …
5 4 7 6 …
程序段 MOV DX, 8 ; 将循环次数计数初值置为 8 MOV CL, 4 ; 移位次数置为 4 MOV SI, 0 MOV DI, SICONVERT:MOV AX, [SI+UNPACKED] SHL AL, CL SHR AX, CL MOV PACKED[DI], AL ; 存储结果 ADD SI, 2 INC DI DEC DX ; 循环计数值减 1 JNZ CONVERT
三、转移指令 无条件转移指令 条件转移指令 循环控制指令 中断及中断返回指令
无条件转移指令示例 段内直接转移: JMP L ; 段内间接转移: JMP AX; ( 转移地址的偏移量在寄存器或内存单元中) 段间直接转移: JMP 2500H:3600H 段间间接转移: JMP DWORD PTR[DI] (转移地址在 DI,DI+1,DI+2,DI+3四个字节单元中)
1. 段内直接转移 段内直接短转移:格式 : JMP SHORT OPR ( 符号地址) 操作 : IP IP+8 位位移量 (-127~+128) 段内直接近转移 : 格式 : JMP NEAR PTR OPR( 符号地址 ) 操作 : IP IP+16 位位移量 2. 段内间接转移 : 格式 : JMP WORD PTR OPR( 可使用除立即数之外 的任何一种寻址方式 ) 操作 : IP (EA)
3. 段间直接 ( 远 ) 转移 格式 : JMP FAR PTR OPR ( 标号 ) 操作 : IP OPR 的段内偏移量 CS OPR 所在段的段基值4. 段间间接转移 格式 : JMP DWORD PTR OPR 操作 : IP (EA) CS (EA+2)例 : JMP DWORD PTR [BX+DI+6]
循环控制指令 通常的循环控制 MOV CX , N BEGIN: …. …. 循环体 …. DEC CX JNZ BEGIN LOOP BEGIN 有了 LOOP 指令,程序得到简化
从技术上讲,循环控制指令是条件转移指令,只不过它是专门为实现循环控制而设计的。 名称 格式 / 其它格式 测试条件 循环 LOOP OPR CX = 0
为零或相等循环 LOOPZ OPR/LOOPE OPR ZF=1 且 CX
=0
非零或不相等循环 LOOPNZ OPR/LOOPNE OPR ZF=0 且 CX=0
1. 执行每条指令时, CX CX- 12. OPR 为一个标号3. 标志--------- 意味着 ZF 并不受 CX- 1 的影响,即 ZF=1 时, CX未必为 0 ; ZF 是前面指令决定的,与 loop 指令执行时 CX 是否为 0无关。
例 1 :执行下述程序段后, AX= MOV CX , 5 MOV AX , 50 LP1: SUB AX , CX LOOP LP1 HLT
例 2 :在 100 个字符构成的字符串中寻找第一个$字符。 (在循环出口处可以根据 ZF 标志和 CX 寄存器的值来确定是否找到以及该字符的位置)
MOV CX , 100 MOV SI , 0FFFH ;假设字符串从偏移地址1000 H 处开始存放 NEXT : INC SI CMP BYTE PTR[ SI] , ’$’ LOOPNZ NEXT
注意,上面程序段中 ZF 标志是由 CMP 指令设置的,而与 CX减 1动作无关。
几种情况: ZF CX =0 =0 =0 =0 =1 =0 =1 =0
几种情况: ZF CX =0 =0 ( 还未找到,循环,继续找) =0 =0 =1 =0 =1 =0
几种情况: ZF CX =0 =0 ( 还未找到,循环,继续找) =0 =0 (未找到,退出循环) =1 =0 =1 =0
几种情况: ZF CX =0 =0 ( 还未找到,循环,继续找) =0 =0 (未找到,退出循环) =1 =0 (找到,且知位置) =1 =0
几种情况: ZF CX =0 =0 ( 还未找到,循环,继续找) =0 =0 (未找到,退出循环) =1 =0 (找到,且知位置) =1 =0 (找到,在第 100 个字符)
子程序调用和返回指令(1) 调用指令名称 格式 操作 段内直接调用 Call DST SP SP-2 (SP+1,SP) IP(保存返回地址) IP IP+ 位移量 (形成转移地址 )段内间接调用 Call DST SP SP-2 (SP+1,SP) IP IP (EA) (EA: 由 DST 的寻址方式 计算出的有效地址 )
例: Call Display ( 段内直接调用); Call WORD PTR [BX] ( 段内间接调用)
名称 格式 操作 段间直接调用 Call DST SP SP-2 (SP+1,SP) CS SP SP-2 保存返回地址 (SP+1,SP) IP IP 偏移量 CS 段基值 形成转移地址
例:C all FAR PTR Display
名称 格式 操作 段间间接调用 Call DST SP SP-2 (SP+1,SP) CS SP SP-2 保存返回地址 (SP+1,SP) IP IP (EA) CS (EA+2) 形成转移地址 EA: 由 DST 的寻址方式计算出的有效地址 例: Call DWORD PTR [BX+SI]
(2) 返回指令名称 格式 操作段内返回 RET (C3H) IP (SP+1,SP) SP SP+2段内带参数返回 RET n IP (SP+1,SP) SP SP+2 SP SP+n(n 为偶数 )
名称 格式 操作段间返回 RET (CBH) IP (SP+1,SP) SP SP+2 CS (SP+1,SP) SP SP+2段间带参数返回 RET n IP (SP+1,SP) SP SP+2 CS (SP+1,SP) SP SP+2 SP SP+n(n 为偶数 )
过程 (子程序 ) 的基本结构 Proc-A PROC NEAR( 或 FAR) ____________过程名 ____________ . . . ____________ RET Proc-A ENDP
堆栈操作及 RET n 指令使用举例 例 . 在进入子程序 FFIT 之前,主程序将字符串的首地址放于堆栈顶部,执行子程序 FFIT 时,将字符串首址取到 ES 和 DI 中,并取出要显示的字符 , 然后调用
DISPLAY 子程序进行显示。 主程序 : FFIT: DISPLAY:
call FFIT call DISPLAY ret ? ret 2
FFIT 子程序段 FFIT: PUSH BP MOV BP, SP PUSH ES PUSH DI LES DI , [BP+04]; 将字符串首址送 ES 和 DI AAA: ES:MOV AL, [DI]; 从 ES 和 DI 所指单元取字符 CMP AL,00 ; 判取出的字符是否为结束符 JZ EEE PUSH AX ; 通过堆栈为 DISPLAY子程序传递参数 ( 要显示的字符 ) CALL DISPLAY INC DI JMP AAA EEE: POP DI POP ES POP BP RET ?
堆栈操作及 RET n 指令使用举例 DISPLAY 子程序返回地址 AX DI ES sp BP FFIT 子程序的返回地址 字符串首址偏移量 字符串首址段基值
8.1.3 指令的机器码格式及指令的执行时间 1. 指令前缀和段超越前缀的编码 前缀并不是一条独立的指令,而是对其后的指令或对指令中
操作数的一种限制。 8086/8088 提供的前缀有三种: 串操作的重复前缀 (REP 、 REPE/REPZ、 REPNE/REPNZ) 总线封锁前缀 (LOCK) 段超越前缀 (ES:、 CS:、 SS:、 DS:) 这些前缀共有 7 种不同的编码,长度都是一个字节,如表 8-20 所示。
指令前缀及段超越前缀的编码
指令前缀 指令前缀的编码 段超越前缀 段超越前缀的编码LOCK 11110000(F0H)REPNE/REPNZ 11110010(F2H)REPE/REPZ 11110011(F3H)REP 11110011(F3H)
ES: 00100110(26H)CS: 00101110(2EH)SS: 00110110(36H)DS: 00111110(3EH)
2. 指令的机器码格式 8086/8088 的机器指令长度 ( 不包括前缀 )随指令的不同而不同,最短的为 1 个字节,最长的为 6 个字节。 指令代码中各字节的排列顺序依次为: 1 个字节的操作码,可能存在的 1 个寻址方式字节,可能存在的
1~ 2 个字节的地址位移量 ( 或地址 ) 和可能存在的1~ 2 个字节的立即数。
指令中的地址位移量 ( 或地址 ) 和立即数如果是 16 位的话,都是低字节放在存储器的低地址单元,高字节放在存储器的高地址单元。指令的一般格式如下图所示 :
8086/8088 指令编码的一般格式图
操作码字节 寻址方式字节 低字节 高字节 低字节 高字节位移量(或地址) 立即数
(1) 操作码字节 操作码字节用来表示该指令执行的操作,每条指令都有操作码字节。大多数指令都使用 8 位的操作码,但有些指令的操作码少于 8 位或多于 8 位。 各种情况下的操作码字节共有 10 种格式 , 如图 8.8 所示。
XXXXXXXX XXXXXX DW XXXXXX SW XXXXXX VW XXXXXXX W
XXXXXXX Z XXXXX reg XXXX W reg XXX sr XXX XXXXX UUU
图 8.8 操作码字节的各种编码格式
D 位用于需要指明两个寄存器 / 存储器操作数的双操作数指令中。这种指令的两个操作数必须有一个是寄存器, D 位则用来指出寻址方式字节中用 reg域标识的那个寄存器是源操作数还是目的操作数: 若 D=0 ,则该寄存器是源操作数; 若 D=1 ,则该寄存器是目的操作数。 W 位用于指明是字节操作还是字操作: 若 W=0 ,则是字节操作; 若 W=1 ,则是字操作。
(2) 寻址方式字节
大多数指令的寻址方式字节分为三个域,即 mod域、reg域和 r/m域。
mod域占两位,代表“方式”; reg域占 3 位,是通用寄存器的 3 位代码; r/m域占 3 位,代表存储器的某个地址或某个通用寄存器。 各种情况下的寻址方式字节共有 5 种格式 , 如图 8.9 所示。
mod reg r/m mod 0 sr r/m mod XXX r/m XXXXXXXX mod UUU r/m
图 8.9 寻址方式字节的各种编码格式
表 8- 21 reg域和 sr域所代表的寄存器
reg域 sr域000 001 010 011 100 101 110 111 00 01 10 11
W=1 AX CX DX BX SP BP SI DIES CS SS DS
W=0 AL CL DL BL AH CH DH BH
表 8- 22 mod域和 r/m域的编码及解释00 01 10 11
存储器寻址不带位移量 存储器寻址带 8位位移量 存储器寻址带 16位位移量 寄存器寻址W=1 W=0
000 [BX+SI] [BX+SI+disp8] [BX+SI+disp16] AX AL
001 [BX+DI] [BX+DI+disp8] [BX+DI+disp16] CX CL
010 [BP+SI] [BP+SI+disp8] [BP+SI+disp16] DX DL
011 [BP+DI] [BP+DI+disp8] [BP+DI+disp16] BX BL
100 [SI] [SI+disp8] [SI+disp16] SP AH
101 [DI] [DI+disp8] [DI+disp16] BP CH
110 16 位直接地址 [BP+disp8] [BP+disp16] SI DH
111 [BX] [BX+disp8] [BX+disp16] DI BH
mod
r/m
例 1: 将指令“ MOV [ BX+DI-6 ], CL” 写成机器码格式。 解 : 这是一条寄存器送存储器的指令。由附录二可知该指令的格式如下,是一条 3字节指令: 10 00 10 DW mod reg r/m disp8 因为 (reg域指出的 ) 寄存器是源操作数,所以 D = 0 ;由 CL 寄存器的编码知 reg = 001 。 因为是字节操作,所以 W = 0 。 因为目的操作数是存储器且带有 8 位位移量,所以 mo
d = 01 。 寻址方式[ BX+DI+disp8]的 r/m=001 。 位移量为 (-6) ,其补码是 11111010 。 因此,该指令的机器码是“ 10001000 01 001 001 11111010” 。
例例 2: 2: 将指令“将指令“ ADD AXADD AX ,, BX”BX” 写成机器码格式写成机器码格式。 解 : 这是一条将两个寄存器的内容相加,将结果送入其中一个寄存器的指令。由附录二可知该指令的格式如下,是一条两字节指令: 00 00 00 DW mod reg r/m 因为 (reg域指出的 ) 寄存器是目的操作数,所以 D=1 ;由 AX 寄存器的编码知 reg=000 。 因为是字操作,所以 W=1 。因为目的操作数是寄存器,所以 mod=11 ,另一个寄存器 BX 的编码为 011 。 因此,该指令的机器码是“ 00000011 11 000 011” 。
3. 指令的执行时间 一条指令的完整执行包括取指令、计算操作数的地址、取操作数、执行指令、存放操作结果等步骤。因此,一条指令的执行时间也就是上述各步骤所需时间的总和。 详细地讨论一条指令的执行时间是很复杂的,即使不考虑人机交互等外在因素,仅从机器的因素来考虑,也有很多因素的影响 . 在后面计算指令的执行时间时,都承认一些假定,如:指令已预取在指令队列中,没有外部事件的影响,没有其他处理器竞争占用总线,等等。
(1) 有效地址的计算
在存 / 取存储器操作数以前,需要先计算出它的有效地址 EA 。 EA 的计算时间取决于指令的寻址方式,具体情况如表 8-24 所示。
表 8- 24 有效地址的计算时间(时钟周期数)
直接寻址 寄存器间接寻址
寄存器相对寻址
基址变址寻址 基址变址相对寻址[BX+SI] [BP+DI]
[BX+DI] [BP+SI]
[BX+SI+disp] [BP+DI+disp]
[BX+DI+disp] [BP+SI+disp]
6 5 9 7 8 11 12
(2) 指令执行时间的计算 假定每条指令在执行前已经预取在指令队列中,因此,取指令的时间不用考虑。 指令在 CPU 中的执行时间又叫基本执行时间,这个时间对确定的指令可认为是固定的。这样就有下面的等式: 指令的执行时间 =计算有效地址的时间+基本执行时间+访问内存的时间 8086 系统中存取一个字操作数时,访问存储器的次数与字操作数的存放地址 (奇、偶 ) 有关。 当该字操作数的地址是偶数时只需访问一次存储器;当该字操作数的地址是奇数时需要访问两次存储器。 另外还假定访问一次存储器都需要 4 个时钟周期。
表 8- 25 8086 指令的执行时间举例 (1)
指 令 所需时钟周期数
ADD 或 SUB
寄存器到寄存器 3
内存到寄存器 9+EA
寄存器到内存 16+EA
立即数到寄存器 4
立即数到内存 17+EA
表 8- 25 8086 指令的执行时间举例 (2) 续表 指 令 所需时钟周期数
MOV
累加器到内存 10内存到累加器 10寄存器到寄存器 2内存到寄存器 8+ EA寄存器到内存 9+EA立即数到寄存器 4立即数到内存 10+EA寄存器到段寄存器 2内存到段寄存器 8+EA 段寄存器到寄存器 2段寄存器到内存 9+EA
表 8- 25 8086 指令的执行时间举例 (3) 续表 指 令 所需时钟周期数
IDIV
除数在 8 位寄存器中 101~112
除数在 16 位寄存器中 165~184
除数为 8 位内存字节 (107~118)+EA
除数为 16 位内存字节 (171~190)+EA
移位 / 循环移位
在寄存器中移 1 位 2
在寄存器中移多位 8+4×( 移位位数 )
内存数据移 1 位 15 + EA
内存数据移多位 20+4×( 移位位数 )+EA
条件转移 JCXZ 6( 不转移时 ) , 18( 转移时 )
其他条件转移指令 4 ( 不转移时 ) , 16( 转移时 )
从表 8-25 可以看出,寄存器之间的操作比使用任何其他寻址方式的操作都要快。寄存器至存储器的操作比存储器至寄存器的操作慢,因为前者要两次访问存储器。 在表 8-26 中,以 5MHz 时钟 ( 时钟周期为 0.2μs) 的 8
086系统为例 ,列出了 ADD 指令在几种情况下的执行时间。
表 8- 26 5MHz 时钟的 8086 中 ADD 指令的执行时间源操作数 目的操作数 时钟周期数 执行时间 寄存器中 内存偶地址字 ( [BP+SI+disp] )
内存奇地址字 ( [BP+SI+disp] )
寄存器中 寄存器中
寄存器中 寄存器中
寄存器中
内存偶地址字 ( [BP+SI] )内存奇地址字 ( [BP+SI] )
3 9+12=21
9+12+4=25
16+8=24
16+8 + 4 + 4 =32
0.64.2
5.0
4.8
6.4
ss
s
s
s
第 8章作业1. 分别说明下列指令中的源操作数和目的操作数各采用 什么寻址方式? (1) AND AX , 00FF H;
(2) ADD AL , [BX+100];
(3) MOV BX , [SI+BX];
(4) MOV [BX+DI+10H], AH ;
(5) MOV [BP+1054H], AX ;
(6) ADD AX, [SI];
(7) MOV SI, 100 ;
2. 若 (DS)=4000H,(BX)=3000H,(SI)=2000H,(DI)=1000H,试画出 1题( 3 )( 4 )的指令执行情况图示。
3. (CS)=2500H,(DS)=2400H,(SS)=2430H,(ES)=2530H,(BP)=0200H,(SI)=0010H,(DI)=0206H,则指令“ MOV AX,[BP+SI+4]” 源操作数 的 有效地址为 ______________, 物理地址为 __________; 指令“ MOV AX, [DI+100]” 源操作数的有效地址为
_____________, 物理地址为 _____________.
4. 若寄存器 AX,BX,CX,DX 的内容分别为 40H , 30H , 20H , 10H 时,依次执行 PUSH AX, PUSH BX,POP CX, POP DX, PUSH CX, PUSH DX, POP AX,POP BX 后,寄存器 AX和 BX 的内容分别为—————————。
5. 将内存 1000H 地址开始的 100 个字节数据向低地址方向移动一个字节的位置。 6. 假设数的长度 ( 以字计 ) 存放 于 2500H字节单元,两个无符号二进制数分别 从 2000H 和 3000H开始存放 (低字在前 ),求两数之和并存放于 2000H开始处,试编程实现。
7. 在数据段中从偏移地址 BUF开始连续存放着 100 个字符 , 编写一 段 程 序 , 将该字符串中 所 有 的字母′ A′ 都改成字母′ B′ 。 8. 编写一段程序把从 PACKED开始的 16 位压缩的 B
CD 数变成非压缩的 BCD 数,并把结果存放在从 UNPACKED开始的单元里。
9. 阅读下列程序段,指出其功能: MOV CX , 0 MOV AX , DS:[2000H]CONT: TEST AX , 0FFFFH JZ EXIT JNS SKIP INC CX SKIP: SHL AX , 1 JMP CONT EXIT:
10. 在所给程序段的划线处填入适当指令或指令的一部分,使其完成如下功能: 在内存 2000H 地址开始处存放着 100 个字节无符号数据,找出其中最大的一个,并存放到 3000H字节单元中。 MOV BX , MOV CX , MOV AL , [BX] P1: INC BX CMP AL , [BX] JNC P2 P2: DEC CX JNZ MOV , 3000H MOV [BX] , AL HLT
11. 给出下述指令的机器语言表示形式: ( 1 ) MOV WORD PTR[BX+SI+20H] , 3000H (2) ADD [BX+DI+1000H] , DX (3) IN AL , 20H (4) OUT DX , AX