Download presentation
Presentation is loading. Please wait.
1
第8章 寻址方式与指令系统
2
8.1 8086/8088的寻址方式与指令系统 8.1.1 8086/8088 的寻址方式 1. 寻址方式概述 (1) 做什么操作
/8088的寻址方式与指令系统 /8088 的寻址方式 1. 寻址方式概述 指令通常应提供的信息: (1) 做什么操作 (2) 操作数从哪里来 (3) 操作结果放在哪里 (4) 对于调用和转移指令,还要涉及转移或调用地址的提供方式
3
指令的组成 --标明计算机要执行什么操作 操作码字段(field) 操作数字段
--指出指令在执行过程中所需要的操作数(值为多少 或者放在什么地方),以及操作结果送到哪里
4
指令的一般格式 操作数字段可以有一个,二个或三个操作数,通常称为“一地址”,“二地址”或“三地址”指令 操作码 操作数 。。。
5
示例 只需要指出加1的操作数,它是“一地址”指令。
加1指令 INC AX 只需要指出加1的操作数,它是“一地址”指令。 双操作数指令 ADD AX, BX 大多数运算型指令都是双操作数指令,对这种指令,有的机器(大中型)使用“三地址”指令:除给出参加运算的两个操作数外,还要指出运算结果的存放地址。
6
现代微型计算机中多采用二地址指令,两个操作数分别称为“源操作数”和“目的操作数”,指令执行后,把运算结果放到目的操作数的地址之中。
指令的操作码在机器中的表示比较简单,只要对每一种操作指定相应的二进制代码即可;而指令的操作数字段的情形就比较复杂。
7
寻址方式 [规定如何对地址字段作出解释以找到操作数]
定义 :指令中如何提供操作数或操作数地址的方式称为寻址方式。 [规定如何对地址字段作出解释以找到操作数] *程序转移时需提供转移地址,这跟提供操作数地址在方法上没有本质区别,因此也归入寻址方式的范畴。
8
指令系统设计 一个指令系统能够提供哪些寻址方式,能否为编制程序提供方便,这是指令系统设计的关键。
需要说明的是,在不同的计算机系统中,寻址方式的名称和分类并不统一,但基本可以归结为以下几种方式或它们的变型或组合:
9
寻址方式的名称和分类 立即寻址(立即数寻址) 寄存器寻址 直接寻址 间接寻址 变址寻址 例如,Z80系统: 立即寻址 ;直接寻址
立即扩展寻址;零页寻址 隐含寻址;相对寻址 寄存器寻址;变址寻址 寄存器间接寻址;位寻址
10
两类寻址方式 数据的寻址方式 转移地址的寻址方式 (我们重点讨论数据的寻址方式) 2. 数据的寻址方式
11
表8-1 数据的寻址方式 源操作数的寻址方式例 源操作数的允许形式 直接操作数(立即数) MOV AX, 20 指令中的直接常数 间接操作数
表8-1 数据的寻址方式 源操作数的寻址方式例 源操作数的允许形式 直接操作数(立即数) MOV AX, 20 指令中的直接常数 间接操作数 寄存器操作数 MOV AX, BX 通用寄存器或段寄存器 存 储 器 操 作 数 直接寻址 MOV AX, DS:[20] MOV AX, B(字) “段:[常数]”或“段:常数” “[变量]”或“变量” 间 接 寻 址 寄存器间接寻址 MOV AX, [BX] [BX, BP, SI, DI 之一] 寄存器相对寻址 MOV AX, [BX+20] MOV AX, [BX+B(字)] [BX, BP, SI, DI 之一+位移量] 基址变址寻址 MOV AX, [BX+SI] [BX, BP之一+SI, DI 之一] 基址变址相对寻址 MOV AX, [BX+SI+20] MOV AX, [BX+SI+B(字)] [BX, BP之一+SI, DI 之一+位移量] 端口操作数 IN AL, 20 指令中有端口号(0 ~ 0FFH) 间接寻址 IN AL, DX DX 中有端口号(0 ~ 0FFFFH)
12
(1) 立即寻址(Immediate addressing)
指令中直接给出操作数,操作数紧跟在操作码之后,作为指令的一部分存放在代码段里,在取出指令的同时也就取出了操作数,立即有操作数可用,所以称之为立即寻址。
13
目的 源 example MOV AL, 80H ; 低地址 存储器 AX MOV AX, 3064H ; 代 码 ADD AL, 20H ; 段 ADD AX, 1090H; 高地址 OP 6 4 3 0
14
立即数可以为8位,也可以为16位。如果是16位数,则“高位字节存放在高地址中,低位字节存放在低地址中。”
立即寻址方式常用于给寄存器赋值,并且只能用于源操作数,而不能用于目的操作数。
15
例如,设B为变量,下述4条指令都是正确的,源操作数的寻址方式都是立即寻址:
A EQU 86H ; 这是定义常量的伪指令语句,它将A定义为常数86H MOV AL, ; 该指令执行后,AL=05H MOV BL, A ; A是常量,其值为86H,该指令执行后,BL=86H MOV AX, 364H ;该指令执行后,AH=03H,AL=64H,AX=0364H MOV BX, OFFSET B ;该指令执行后,BX中存放的是变量B的偏移地址
16
MOV AL, 256 ; 256=100H,超过了AL能存放的数的范围 MOV 100H, AL ; 立即数不能作为目的操作数
下述各条指令源操作数的寻址方式也都是立即寻址,但这些指令都是错误的: MOV AL, ; 256=100H,超过了AL能存放的数的范围 MOV AX, ; 超过了AX能存放的带符号数(补码)范围 MOV 100H, AL ; 立即数不能作为目的操作数 DEC ; 单操作数指令不能使用立即数 MOV DS, 1234H ; 源操作数是立即数,则目的操作数就不能是段寄存器
17
(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 不能作目的寄存器)
18
EXAMPLE INC AX ; MOV AX, BX ; CF D7 D0 DEC AX ; ROL AH , 1 ;
19
MOV AX, BL ;错误。源和目的的位数不相同 MOV CS, AX ;错误。CS不能作为目的操作数
练习: MOV AX , BX ;正确。指令执行后,AX←BX,但BX不变 MOV AX, BL ;错误。源和目的的位数不相同 MOV CS, AX ;错误。CS不能作为目的操作数 MOV ES, DS ;错误。两个操作数不能都是段寄存器
20
寄存器寻址的特点 (1) 操作数就在寄存器中,不需要访问存储器来取得操作数(指令执行时,操作就在CPU的内部进行),因而执行速度快。
(2)寄存器号比内存地址短 * 在编程中,如有可能,尽量使用这种寻址方式的指令。 * 寄存器寻址方式既可用于源操作数,也可用于目的操作数,还可以两者都用于寄存器寻址方式(如 MOV BX , AX )
21
除以上两种寻址方式外,下面各种寻址方式的操作数均在存储器中,通过采用不同的寻址方式取得操作数地址,从而取得操作数。
22
(3)直接寻址(Direct Addressing)
说明:在讨论寻址方式时,通常把操作数的偏移地址称为有效地址EA (Effective Address) ,EA可通过不同的寻址方式来得到。 在直接寻址方式中,指令中直接给出操作数的有效地址,或者说,有效地址EA就在指令中。它(操作数的有效地址,而不是操作数本身)存放在代码段中指令的操作码之后,但操作数一般存放在数据段中。
23
例 1. MOV AX , DS:[2000H]; 如(DS)= 3000H, 则指令的执行情况如下图所示:
24
OP 00 代 存储器 采用直接寻址方式,如果没 码 有用“段跨越前缀”标明操作 段 数在哪一段,就默认段寄存 20 50
代 存储器 采用直接寻址方式,如果没 码 有用“段跨越前缀”标明操作 段 数在哪一段,就默认段寄存 为DS. 30000H AX 数 据 段 H 执行结果:(AX)=3050H OP 00 20 50 30
25
当然, 也允许数据存放在数据段以外的其它段(如附加段)。此时应在指令中给出 “跨越段前缀”。
例 2: 如数据在附加段(扩展段)中,则应指明“段跨越缀” 。 MOV AX , ES : [3000H] 或 ES: MOV AX , [3000H] * 为了使指令字不要过长,规定双操作数指令不能两个操作数都用直接寻址方式。 如( MOV [2000H] , [3000H] )
26
(4) 寄存器间接寻址(Register indirect Addressing)
采用寄存器间接寻址方式时,指令中给 出寄存器号(寄存器为BX,BP,SI和DI之一), 被指定的寄存器中存放着操作数的有效地址,操作数在存储器中(以寄存器的内容为操作数的有效地址)。 [BX]……..对应段寄存器为 DS EA= [BP]…….. ………………… SS [SI]……… …………………..DS [DI]……… ………………….DS
27
Example 设 ( DS) = 2000H ,(BX) = 1000H *指令中也可以通过 AX ………. “段跨越前缀”取得 A0H
MOV AX , [BX] ; 设 ( DS) = 2000H ,(BX) = 1000H 物理地址=20000H + 1000H =21000H *指令中也可以通过 AX ……… “段跨越前缀”取得 数 其他段中的数据, 据 例如: 段 MOV AX,ES: [BX] 指令的执行结果为: (AX) = 50A0H A0H 50 H
28
(5) 寄存器相对寻址(Register relative addressing)
操作数的有效地址是一个基址或变址寄存器的内容与指令中指定的8位或16位位移量之和。 如下图所示:
29
[BX] 位位移量 EA = [BP] + [SI] 位位移量 [DI] 若没有段跨越前缀,则对于寄存器BX,SI, DI的情况,段寄存器为DS;而对于寄存器为BP的情况,则段寄存器为SS.
30
Example OP MOV AX, [SI+3000H] 操 设(DS)=4000H,(SI)=2000H 作
物理地址 码=40000H+2000H+3000H 位 = 45000H 移 指令的执行情况如 量 右图 AX H 43000H SI 数 45000H 据 段 OP 00 30 …… 34 12
31
这种寻址方式可用于表格的处理,通过位移量来设置表格的首地址;
利用修改基址寄存器或变址寄存器的内容来获得表项的值。
32
(6)基址变址寻址(Based indexed addressing)
操作数的有效地址是一个基址寄存器和一个变址寄存器内容之和,两个寄存器均由指令指定。 [BX] [SI] 若基址寄存器为BX,则段寄存器为DS EA= [BP] [DI] 若基址寄存器为BP,则段寄存器为SS
33
Example … [BX] 21000H AX 34 12 设(DS)=2100H,(BX)=0158H,[DI]=10A5H.
例:MOV AX,[BX+DI] 设(DS)=2100H,(BX)=0158H,[DI]=10A5H. 则 EA= 0158H+10A5H=11FDH 物理地址=21000H+11FDH=221FDH [BX] H 21158H AX 221FDH … 34 12
34
这种寻址方式同样适用于表格(或数组)的处理,首地址可存放在基址寄存器中,而用变址寄存器来访问表格中的各项。
由于两个寄存器都可以修改,使 用起来更灵活。
35
(7 )相对基址加变址寻址(Relative based indexed address~)
也称“带位移量的基址加变址寻址方式”. 操作数的有效地址是一个基址寄存器和一个变址寄存器内容与8位或16位位移量之和。 [BX] [SI] 用BX,则段寄存器为 DS EA= 位移量 [BP] [DI] 用BP,则段寄存器为 SS
36
例:MOV AX,[BX+SI+0250H] OP 50 02 设(DS)=3000H,(BX)=2000H,(SI)=1000H,则 代 EA= 2000H+1000H+0250H=3250H 码 物理地址=30000H+3250H=33250H 段 [BX] H AX 位移量 H 数 32250H 据 [SI] H 段 … 34 12
37
数据的寻址方式的寻址过程(图示) . 指令 指令 寄存器 数据 寄存器 数据 (2)寄存器寻址 (1)立即寻址 图8.1 数据的寻址方式的寻址过程(1)
38
存储器 指令 EA 数据 (3)直接寻址 指令 寄存器 存储器 寄存器 EA 数据 (4)寄存器间接寻址 图8.1 数据的寻址方式的寻址过程(2)
39
指令 寄存器 位移量 EA 存储器 + 数据 寄存器 地址 (5)寄存器相对寻址 图8.1 数据的寻址方式的寻址过程(3)
40
寄存器 指令 基址 寄存器 变址 寄存器 变址值 EA 存储器 数据 + 寄存器 基地址 (6)基址变址寻址 图8.1 数据的寻址方式的寻址过程(4)
41
指令 基址 寄存器 变址 寄存器 位移量 EA 存储器 寄存器 + 数据 变址值 寄存器 基址值 (7)基址变址相对寻址 图8.1 数据的寻址方式的寻址过程(5)
42
端 口 操 作 数 指令 端口 端口号 数据 (8)直接寻址 指令 DX 端口 DX 端口号 数据 (9)间接寻址 图8.1 数据的寻址方式的寻址过程(6)
43
3. 转移地址的寻址方式(*) 有关术语和概念: 段内转移—如果转移地址与该转移类指令在同一个代码段,这样的转移称为段内转移,也称近转移;
近转移时的转移地址只包含偏移地址部分,找到转移地址后,将转移地址送入IP即可实现转移(CS的内容不必改变);
44
段间转移—如果转移地址与该转移类指令位于不同的代码段,这样的转移称为段间转移,也称远转移;远转移时的转移地址既包含偏移地址部分又包含段基值部分,找到转移地址后,将转移地址的段基值部分送入CS,将转移地址的偏移地址部分送入IP即可实现转移。
45
直接转移—如果转移地址直接放在指令中,则这样的转移称为直接转移,视转移地址是绝对地址还是相对地址(即地址位移量)又可分别称为绝对转移和相对转移
46
间接转移—如果转移地址间接放在其他地方,则这样的转移称为间接转移,视转移地址是在寄存器中还是在存储器中又可分别称为寄存器操作数(寄存器寻址)和存储器操作数(存储器寻址)。
以JMP指令为例,可将转移地址的各种寻址方式列出,如表8-2所示。
47
表8-2 转移地址的寻址方式 段内转移例 段间转移例 直接转移(L为标号) 转移地址在指令中(近标号) 转移地址在指令中(远标号)
表8-2 转移地址的寻址方式 段内转移例 段间转移例 直接转移(L为标号) 转移地址在指令中(近标号) 转移地址在指令中(远标号) JMP L(近) JMP FAR PTR L (远) 寄存器操作数 转移地址在通用字寄存器中 无 JMP AX 间接转移 存储器 操作数 直接寻址 (B为变量) 转移地址在字变量中 转移地址在双字变量中 JMP B(字) JMP WORD PRT DS:[20] JMP B(双字) JMP DWORD PTR DS: [20] 间接寻址 寄存器间接寻址 转移地址在“BX, BP, SI, DI 之一”中 JMP [BX] JMP DWORD PTR [BX] 寄存器相对寻址 转移地址在“BX, BP, SI, DI 之一+ 位移量”中 JMP [BX+20] JMP [BX+B(字)] JMP DWORD PTR [BX+20] JMP [BX+B(双字)] 基址变址寻址 转移地址在“BX, BP之一+SI, DI 之一”中 JMP [BX+SI] JMP DWORD PTR [BX+SI] 基址变址相对寻址 转移地址在“BX, BP之一+SI, DI 之一+位移量”中 JMP [BX+SI+20] JMP [BX+SI+B(字)] JMP DWORD PTR [BX+SI+20] JMP [BX+SI+B(双字)]
48
(1) 段内直接转移(直接近转移) 特点:转移地址(通常就是近标号)直接包含在汇编形式的转移指令中,转移指令的机器代码中存放的是该标号与当前IP值的差(标号-IP),此差称为位移量,该位移量与转移指令一起存于代码段: 位移量被放在转移指令的操作码之后,也是“高字节放在高地址单元,低字节放在低地址单元”。在取转移指令时,此位移量即作为转移指令的一部分被取入CPU中。
49
IP+(标号-IP)=标号=转移地址 执行转移指令时,将这个位移量加到IP上即可得到转移地址(标号的值),即
而不必为找这个转移地址再去访问寄存器或存储器。 例如,如果L是本段中的标号,则下述指令采用的是段内直接转移方式: JMP L; 机器指令中的位移量为L-IP,转移地址为L
50
(2) 段内间接转移(间接近转移) 例: JMP BX ; BX的内容为转移地址
① 寄存器操作数(也称寄存器寻址) 例: JMP BX ; BX的内容为转移地址 ② 存储器操作数(也称存储器寻址) (i) 直接寻址 其特征是: 转移地址(偏移地址部分)在数据存储单元中,数据存储单元的地址在指令中直接给出。例如,如果B为存储器数据段中的字变量,则下述两条指令采用的都是段内间接转移、存储器直接寻址方式:
51
JMP B ;数据存储单元(DS:B)的一个字为转移地址
JMP WORD PTR DS:[20];数据存储单元(DS:20)的一个字为转移地址
52
JMP[BX] ;数据存储单元(DS:BX)的一个字为转移地址
(ii) 寄存器间接寻址 其特征是: 转移地址(偏移地址部分)在数据存储单元中,数据存储单元的偏移地址在BX、BP、SI、DI之一中。例如,下述指令采用的就是段内间接转移、寄存器间接寻址方式: JMP[BX] ;数据存储单元(DS:BX)的一个字为转移地址 JMP[BP] ;数据存储单元(SS:BP)的一个字为转移址 JMP DS:[BP] ;数据存储单元(DS:BP)的一个字为转移地址
53
(iii) 寄存器相对寻址 其特征是: 转移地址(偏移地址部分)在数据存储单元中,数据存单元的偏移地址是寄存器(BX、BP、SI、DI之一)的内容与位移量的和。 例如,下述指令采用的就是段内间接转移、寄存器相对寻址方式: JMP[BX+20] ;数据存储单元(DS:BX+20)的一个字为转移地址 JMP[BP+20] ;数据存储单元(SS:BP+20)的一个字为转移地址 JMP DS:[BP+20 ] ;数据存储单元(DS:BP+20)的一个字为转移地址
54
(iv) 基址变址寻址 其特征是: 转移地址(偏移地址部分)在数据存储单元中,数据存储单元的偏移地址是基址寄存器(BX、BP之一)的内容和变址寄存器(SI、DI之一)的内容之和。 例如,下述指令采用的就是段内间接转移、基址变址寻址方式: JMP[BX+SI] ;数据存储单元(DS:BX+SI)的一个字为转移地址 JMP[BP+SI] ;数据存储单元(SS:BP+SI)的一个字为转移地址 JMP DS:[BP+SI ] ;数据存储单元(DS:BP+SI)的一个字为转移地址
55
(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)的一个字为转移地址
56
(3) 段间直接转移(直接远转移) 转移地址(通常就是远标号)直接包含在汇编形式的转移类指令中,也直接存放在转移类指令的机器代码中,它是转移类指令不可分割的一部分,位于转移类指令的操作码之后: 高字存放转移地址的段基值部分,低字存放转移地址的偏移地址部分。在取转移类指令时,此段基值和偏移地址作为转移类指令的一部分被取入CPU中,执行转移类指令时,不必为找转移地址再去访问寄存器或存储器。
57
例如,如果L是其他代码段中的标号,则下述指令采用的就是段间直接转移方式:
JMP FAR PTR L ;在L左边通常要加上类型说明FAR PTR
58
(4) 段间间接转移(间接远转移) 段间间接转移时的转移地址既包含偏移地址部分,又包含段基值部分,在数据存储器中占两个字: 低字单元存放偏移地址,高字单元存放段基值。 要在转移类指令中的地址表达式左边加上类型说明DWORD 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〉 基址变址相对寻址
59
第〈1〉条指令中的B是变量,不是标号,因此是段间间接转移、存储器操作数的直接寻址方式,不是段间直接转移方式。
在上述各种“相对”寻址方式中,“+B”加的都是B的偏移地址部分而非其内容。
60
例: 设W为数据段中的字变量,给出如下的指令序列:
W DW L MOV SI, OFFSET W MOV AX, W JMP L ; 或JMP AX ;或 JMP W ;或JMP[SI] …… L: ……
61
则变量W的内容是标号L,即转移类指令的转移地址。参考表8-2可知:
JMP L是段内直接转移(L为标号); JMP AX是段内间接转移、寄存器寻址(寄存器AX的内容是转移地址); JMP W是段内间接转移、存储器直接寻址(变量W的内容是转移地址); JMP[SI]是段内间接转移、寄存器间接寻址(SI的内容是数据存储单元的偏移地址,数据存储单元的内容才是转移地址)。 4条转移指令分别执行后,都会转移到相同的地址L处。
62
寄存器 指令 指令 转移地址 寄存器 转移地址 (2)寄存器间接转移 (1)直接转移 图8.2 转移地址的寻址方式的寻址过程(1)
63
存储器 指令 EA 转移地址 (3)直接寻址 指令 寄存器 存储器 寄存器 EA 转移地址 (4)寄存器间接寻址 图8.2 转移地址的寻址方式的寻址过程(2)
64
指令 寄存器 位移量 存储器 EA + 转移地址 寄存器 地址 (5)寄存器相对寻址 图8.2 转移地址的寻址方式的寻址过程(3)
65
指令 寄存器 基址 寄存器 变址 寄存器 变址值 存储器 EA 转移地址 + 寄存器 基地址 (6)基址变址寻址 图8.2 转移地址的寻址方式的寻址过程(4)
66
指令 基址 寄存器 变址 寄存器 位移量 存储器 EA 寄存器 + 转移地址 变址值 寄存器 基地址 (7)基址变址相对寻址 图8.2 转移地址的寻址方式的寻址过程(5)
67
8.1.2 8086/8088 指令系统 可以分为以下六类(四类): 传送指令 算术运算指令 逻辑运算和移位指令 运算类 串操作指令
/8088 指令系统 可以分为以下六类(四类): 传送指令 算术运算指令 逻辑运算和移位指令 运算类 串操作指令 转移指令 处理器控制指令
68
(一)传送指令 包括:通用传送指令和专用传送指令两类 通用传送指令: 名称 格式 类型 操作 传送 交换 入栈 出栈 MOV 目的,源
XCHG 操作数1,操作数2 PUSH 源字 POP 目的字 B/W W (目的)←(源) (操作数1) ←→ (操作数2) SP ←SP-2, (SS:SP) ←(源)字 (目的)字 ←(SS:SP), SP ←SP+2
69
(1) MOV 指令 立即数 存储器 通用寄存器 段寄存器 直接寻址 AX BX CX DX 寄存器间接寻址 SI DI SP BP
寄存器相对寻址 基址变址寻址 基址变址相对寻址 AX BX CX DX SI DI SP BP AL BL CL DL AH BH CH DH 段寄存器 DS ES SS CS
70
例: MOV AL, BL ; MOV [DI], AX ; MOV CX, DS:[1000H] ; MOV BL, 40 ;
MOV WORD PTR[SI],01H; WORD PTR 字长度标记;BYTE PTR 字节长度标记 DWORD PTR 双字长度标记 (伪指令) 标志:所有通用传送指令都不影响标志位。
71
例(错):下述各条指令都是错误的,其中,W1为数据段中的变量:
MOV ES, 1234H ; 立即数不能直接送入段寄存器 MOV 1AH, CL ; 立即数不能作为目的操作数。不要将1AH错看成AH MOV CS,BX ; CS不能作为目的操作数 MOV W1,[BX] ; 两个内存操作数之间不能传送 MOV ES, DS ; 两个段寄存器之间不能传送 MOV AX, BL ; 两个操作数的位数(类型)不相同
72
练习1 用MOV指令实现两内存字节单元内容的交换 2035H 2045H 01H …. 02H
73
MOV BL, DS:[2035] ; 用直接寻址方式实现 MOV CL, DS:[2045H] ;
MOV DS:[2045H], BL ; MOV DS:[2035H],CL ; HLT
74
用寄存器间接寻址方式实现 MOV SI , 2035H; MOV DI, 2045H; MOV AH, [SI];
MOV AL, [DI]; MOV DS:[2035H],AL; MOV DS:[2045H],AH;
75
练习2 把数据块BLOCK1移到BLOCK2 BLOCK1 2040H 2060H BLOCK2
76
ANSWER START: 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 ;
77
练习3 把2040H地址开始的10个字节单元的内容与2060H地址开始的10个字节单元内容互换。
78
(2)PUSH指令和POP指令 堆栈的图示: 压入:格式 PUSH SRC … (SS) 先修改指针: SP SP-2
后压入:(SP+1,SP) SRC (SP) 弹出:格式 POP DST 栈顶 先弹出:DST (SP+1,SP) 压 弹 后修改指针:SP SP+2 入 出 高地址 栈底 … 最后一项
79
练习: 设SS=1000H,SP=2000H,BX=1234H,则依次执行完 PUSH AX、PUSH BX 和 POP CX 三条指令后,SS不变,SP= ,栈顶单元的物理地址为 ,BX=CX= 。
80
(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;
81
XCHG指令允许的操作数及数据传送方向 通用寄存器 存储器 直接寻址 AX BX CX DX 寄存器间接寻址 SI DI SP BP
AL BL CL DL AH BH CH DH 直接寻址 寄存器间接寻址 寄存器相对寻址 基址变址寻址 基址变址相对寻址
82
练习1 MOV BL , [SI +09H] 用XCHG指令改进前面的数据块交换程序: XCHG BL , [DI+09H]
MOV [SI+09H] , BL
83
练习2 设BX=1234H,DS=2000H,字单元(21234H)=5678H,指令 “XCHG BX, [BX]” 执行后,BX=5678H,字单元 (21234H)=1234H。由于交换后BX的内容被改变,所以 (DS:BX) 成为存储单元25678H的内容(不再是存储单元 21234H 的内容),是未知的。
84
2. 专用传送指令 专用传送指令有15条,可分为标志传送、查表、地址传送、符号扩展、输入/输出和串传送类共六种,它们的名称、书写格式、完成的操作及操作类型如下表所示。
85
专用传送指令 (1) 名称 格式 类型 操作 标志传送 标志入栈 PUSHF W SP ←SP-2, (SS:SP) ←Flag 出栈到标志
专用传送指令 (1) 名称 格式 类型 操作 标志传送 标志入栈 PUSHF W SP ←SP-2, (SS:SP) ←Flag 出栈到标志 POPF Flag←(SS:SP), SP ←SP+2 标志送AH LAHF B AH←Flag低8位 AH送标志 SAHF Flag低8位← AH 查表 XLAT或XLATB XLAT 段寄存器:变量名 AL ←(DS:BX+AL) AL ←(段寄存器:BX+AL) 地址传送 传送有效地址 LEA 16位Reg, Mem 16位 Reg←Mem的有效地址 地址指针送寄存器及DS LDS 16位Reg, 双字 Mem 16位 Reg←(Mem)低字 DS ←(Mem)高字 地址指针送寄存器及ES LES 16位Reg, 双字 Mem 16位Reg ←(Mem)低字 ES ←(Mem)高字
86
专用传送指令 (2) 续表 名称 格式 类型 操作 符号扩展 字节扩展位字 字扩展为双字 CBW CWD B W AH的各位←AL的最高位
专用传送指令 (2) 续表 名称 格式 类型 操作 符号扩展 字节扩展位字 字扩展为双字 CBW CWD B W AH的各位←AL的最高位 DX的各位←AX的最高位 输入输出 输入 IN Ac, 端口号 B/W Ac ←(端口), 端口号:0~0FFH IN Ac, DX Ac ←(DX), DX:0~0FFFFH 输出 OUT 端口号, Ac (端口) ← Ac , 端口号:0~0FFH OUT DX, Ac (DX)←Ac, DX:0~0FFFFH
87
专用传送指令 (3) 续表 名称 格式 类型 操作 串传送类 串传送 MOVSB B (ES:DI)字节 ←(DS:SI)字节
专用传送指令 (3) 续表 名称 格式 类型 操作 串传送类 串传送 MOVSB B (ES:DI)字节 ←(DS:SI)字节 DF=0时 SI←SI+1, DI←DI+1 DF=1时 SI←SI- 1, DI←DI -1 MOVSW W (ES:DI)字 ←(DS:SI)字 DF=0时 SI←SI+2, DI←DI+2 DF=1时 SI←SI- 2, DI←DI -2 *MOVS 目的,源 B/W 略 串存储 (存入串) STOSB (ES:DI)←AL 若DF=0, 则DI←DI+1 若DF=1, 则DI←DI- 1 STOSW (ES:DI)←AX 若DF=0, 则DI←DI+2 若DF=1, 则DI←DI- 2 *STOS 目的
88
专用传送指令 (4) 续表 名称 格式 类型 操作 串传送类 串装入 (从串取) LODSB B AL ←(DS:DI)
专用传送指令 (4) 续表 名称 格式 类型 操作 串传送类 串装入 (从串取) LODSB B AL ←(DS:DI) 若DF=0, 则SI←SI+1 若DF=1, 则SI←SI- 1 LODSW W 若DF=0, 则SI←SI+2 若DF=1, 则SI←SI- 2 *LODS 源 B/W 略
89
(1)标志传送指令 标志传送指令共4条: PUSHF POPF LAHF ;AH Flag的低8位 SAHF ;Flag的低8位 AH
例:将8086 标志寄存器的TF位置 “1”
90
查表指令XLAT将以BX+AL为偏移地址的内存单元中的一个字节送到AL中。
(2)查表指令 查表指令XLAT将以BX+AL为偏移地址的内存单元中的一个字节送到AL中。 在使用XLAT指令前,应先在内存中建立一个字节数据表,表的首字节的偏移地址要事先存入BX,表中待查的数据相对于表开始处的位移量也要事先存入AL。 指令执行时,会将BX的内容与AL的内容相加,用得到的数作为偏移地址,以DS为段地址,将该地址处存储单元中的内容(字节)取到AL中。
91
例如,如果B为数据段中一组字节变量的开始地址,则执行下列程序段后,AL=66H。
B DB 3FH, 06H, 5BH, 4FH, 66H ;数据段中的数据表 DB 6DH, 7DH, 07H, 7FH, 6FH MOV BX,OFFSET B ;使BX中存放数据表首字节的偏移地址 MOVAL, ;使AL中存放欲查单元的地址位移量4 XLAT ;查表得到的内容(字节)在AL中 在此例中,数据表中存放的数据恰好是共阴极数码管的输入信号(参见表4-1),所以,只要事先在AL中放好一个十进制数码(0~9),就能通过上述程序段得到数码管的相应输入信号。
92
(3) 地址传送指令 地址传送指令有LEA、LDS和LES共3条: LEA (Load Effective Address)
LDS (Load pointer into register and DS) LES (Load pointer into register and ES)
93
*指令功能:将源操作数的有效地址EA传送到目的操作数,目的操作数为一个16位的通用寄存器。
(i)取有效地址指令 格式:LEA REG , SRC; 操作:REG SRC; *指令功能:将源操作数的有效地址EA传送到目的操作数,目的操作数为一个16位的通用寄存器。
94
例:LEA BX,[BX+DI+6H] 若指令执行之前(BX)=1000H,(DI)=0200H, 则指令执行之后,(BX)=1206H
注意与指令MOV BX,[BX+DI+6H]功能上的区别 从变量的角度,“LEA AX,VAR”指令传送的是变量的地址,而“MOV AX,VAR”指令传送的是变量的值。
95
(ii) LDS REG , SRC 操作:REG (SRC) DS (SRC+2) 标志:---------
前两个字节(偏移量) 非段寄存器 后两个字节(段基址) DS
96
Example 例1. LDS DI,DS:[2130H] 设(DS)=3000H 32130H DI DS 偏移量 段基址
97
(iii) LES REG , SRC 操作: REG (SRC) ES (SRC+2) * LDS和LES指令为切换数据段提供了方便。
98
(4) 符号扩展指令 符号扩展指令有CBW和CWD共两条。
其中,CBW指令将AL中的8位带符号数扩展为16位并送入AX中,实际上就是将AL的最高位送入AH的所有各位; CWD指令将AX中的16位带符号数扩展为32位并送入DX和AX中(其中DX存放高16位,AX存放低16位),实际上就是将AX的最高位送入DX的所有各位。
99
例如,若AX=379AH, 则执行完CBW指令后,AX=0FF9AH,若执行的是CWD指令,则DX=0000H,AX=379A H;
若AX=977AH, 则执行完指令CBW后,AX=007AH,若执行的是CWD指令,则DX=0FFFFH,AX=977AH。 CBW和CWD两条指令通常只对带符号数使用。CBW指令只能对AL的内容进行扩展,扩展后AL的内容不变但占用AH;CWD指令只能对AX的内容进行扩展,扩展后AX的内容不变但占用DX。
100
(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)
101
<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;
102
输入输出指令格式(机器码) 0:8位传送 只出现于直接输入 0-直接输入指令(长形) 输入指令: 1:16位传送 输出指令
0:8位传送 只出现于直接输入 1:16位传送 输出指令 0-直接输入指令(长形) 1-间接输入指令 (短形) 1 0 W PORT
103
输出指令 只出现于长形… 0 (长形) 1(短形) 1110 11 W PORT
104
例: IN AL , 28H; IN AL, 27H; 输入输出指令的使用 IN指令:用于从数据端口输入数据或从状态端口输入状态字.
MOV DS:[2000H] ,AL; TEST AL, B; JNZ ERROR
105
OUT指令:用于输出数据或命令给指定的I/O端口
例:如果26H端口(命令寄存器)第7位启动成组传送操作,则可用下述程序启动之: COM- REG EQU 26H ;为名字赋值 BEGIN- BIT EQU B ;伪指令 … MOV AL, OTRCNBITS; OR AL, BEGIN-BIT; OUT COM-REG, AL;
106
串传送类指令有MOVS、STOS和LODS共3条,每一条又有3种形式。
(6) 串传送指令 串传送类指令有MOVS、STOS和LODS共3条,每一条又有3种形式。 第一条指令: 串传送指令(MOVS) 串传送指令MOVS完成两个存储单元之间的传送,传送后会自动修改有关的变址寄存器。
107
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。
108
* “MOVS目的, 源”指令将源存储单元(段寄存器:SI)的一个字节(或一个字)传送到目的存储单元(ES:DI)的一个字节(或一个字)中。
对于字节操作,若DF=0,则传送后SI←SI+1,DI←DI+1;若DF=1,则传送后SI←SI-1,DI←DI-1。 对于字操作,若DF=0,则传送后SI←SI+2,DI←DI+2;若DF=1,则传送后SI←SI-2,DI←DI-2。
109
例如, MOVSB可写成 MOVS BYTE PTR ES:[DI], DS:[SI] MOVSW可写成 MOVS WORD PTR ES:[DI], WORD PTR DS:[SI]
110
串传送指令的应用例 将内存1000H地址开始的100个字节数据向高地址方向移动一个字节的位置。
111
参考答案 MOV AX , DS MOV ES , AX MOV SI , 1063H MOV DI , 1064H
MOV CX , 64H STD REP MOVSB HLT 思考:向低地址方向移动两个字节位置。
112
第二条指令:串存储指令STOS(写串) 串存储指令STOS将累加器AL或AX的内容传送至目的存储单元(ES:DI)中。传送后自动修改DI寄存器的值。 该指令前面加上重复前缀REP后,可以使一段内存单元中填满相同的值。
113
串装入指令LODS将源存储单元( DS:SI)的内容传送至累加器AL或AX中。传送后会自动修改变址寄存器SI的内容。
因为累加器在每次重复时都被重写,只有最后一个元素被保存下来,故这条指令前一般不加重复前缀,而常用在循环程序段中,和其他指令结合起来完成复杂的串操作功能。 例如,下面的程序段将由100个字组成的字串中的负数相加,其和存放到紧接着该串的下一顺序地址中。
114
CLD MOV SI,1000H;首元素地址为1000H MOV BX,0 MOV DX,0 MOV CX,101 LOD:DEC CX JZ STO LODSW ;从源串中取一个字存入AX MOV BX,AX AND AX,8000H;判断该元素是否是负数 JZ LOD ADD DX,BX JMP LOD STO:MOV[SI],DX
115
(二)运算类指令
116
1. 算术运算指令 (1) 二进制加法和减法指令 名称 格式 操作 加法 ADD DST,SRC DST SRC+DST
(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 所有状态标志都受影响 ×---×××××
117
Example 编写实现下列二进制运算的程序段 W X+Y+24-Z(X,Y,Z均为字变量) MOV AX, X ; ADD AX, Y ;
SUB AX, Z; MOV W, AX;
118
Example 双倍精度运算(操作数的长度为双字-- 两个16位) 2000H 3000H 低16位 低16位 高16位 高16位
低16位 低16位 高16位 高16位 把2000H地址开始的两个字(低字在前)和3000H地址开始的两个字相加,和存放在2000H开始处。
119
程序段 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位相加结果. 思考:以上是双字(双倍精度)相加,如果更多字(多倍精度)相加,这个程序将如何设计?
120
例3: 假设数的长度(以字计)存放 于2500H字节单元,两个无符号二进制数分别 从2000H和3000H开始存放(低字在前),求两数之和并存放于2000H开始处,试编程实现。
121
参考答案 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 DI ; DEC CL ; JNZ LOOP ; MOV AX , 0H ; ADC AX , 0H ; 处理最高位产生的进位 MOV [SI] , AX ; HLT
122
(2) 加1 减1和比较指令 名称 格式 操作 加 1 INC OPR OPR OPR+1 减 1 DEC OPR OPR OPR-1
(2) 加1 减1和比较指令 名称 格式 操作 加 INC OPR OPR OPR+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: × ×××××
123
NEG指令 NEG指令把操作数当成一个带符号数,如果原操作数是正数,NEG指令则将其变成负数(用补码表示);如果原操作数是负数(用补码表示),NEG指令则将其变成正数。 方法:“各位(包括符号位)求反,末位加1”.
124
Example * 若AL=00010001B=+17,执行NEG AL后, AL=11101111B=[-17]补
125
比较指令 比较指令实际上是做减法,但不回送相减的结果,只是根据结果置标志。通常,把CMP指令安排在条件转移指令(如JZ , JG , JO 等)之前。 例. 如果X>50,转移到TOO-HIGH; 如果带符号减法X-Y引起溢出,则转移到OVERFLOW; 否则,计算 X-Y ,并将结果存放在RESULT中。(其中,X,Y,RESULT均为字变量)。
126
程序段 下述程序段使用了前面介绍的几条指令,也用到了后面即将介绍的条件转移指令. 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:
127
(3) 乘法指令 格式:IMUL SRC (ii) 无符号乘法 格式:MUL SRC (i) 带符号乘法 所执行的操作:
字节操作数: AX (Al)*(SRC) 字操作数:DX:AX (AX)*(SRC) (乘积带符号,并符合一般代数符号规则) (ii) 无符号乘法 格式:MUL SRC 同IMUL,但操作数和乘积均不带符号。
128
(4) 除法指令 带符号除法 格式:IDIV SRC 所执行的操作: 字节除数:AL (AX)/(SRC) 之商
AH (AX)/(SRC) 之余数 字除数: AX (DX:AX)/(SRC)之商 DX (DX:AX)/(SRC) 之余数 商和余数是带符号的:商的符号符合一般代数符 号规则,余数的符号与被除数相同. 无符号除法 格式:DIV SRC 与IDIV相同,但操作数,商和余数均是无符号的。
129
标志位 标志:O D I T S Z A P C IMUL ×--- U U U U X MUL ×--- U U U U X
IDIV U --- U U U U U DIV U --- U U U U U X :根据结果设置 U : 无定义 -: 不影响
130
例:二进制四则混合算术运算程序段 试计算: AX (V-(X*Y+Z-540))/X 之商 DX 余数
(其中,X ,Y ,Z ,V 均为字变量)
131
PROGRAM MOV AX, X; IMUL Y; X*Y,结果在DX:AX中 MOV CX, AX;
MOV BX, DX; 将乘积存在BX:CX中 MOV AX, Z; CWD 将符号扩展后的Z加到BX:CX中的乘积上去 ADD CX, AX; 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;
132
(2) BCD数运算指令 所谓BCD数,就是二进制编码的十进制数(Binary Coded Decimal),它是用4位二进制码表示一位十进制数(0000~1001是合法BCD码;1010~1111是非法BCD码). 组合BCD数:用一个字节表示2位BCD数 例:37 分离BCD数:用一个字节的低4位表示一位BCD数,高4位为0. 0011 0111 0000 0011 0000 0111
133
(i)组合BCD数十进制调整原理 例 1 : 18 + 7 = 25 0 0 0 1 1 0 0 0 - - - - - - - - 18
? (1111是非法BCD码) 需要对结果进行变换(调整),方法:“加6调整” (正确结果) 第3位向第4位(低半字节向高半字节)有进位, AF=1
134
组合BCD数十进制调整原理 在非法BCD码上“加6”,产生向高一位数字的进位: 加法器实际上是按二进制运算 “满16进一”
“进1当10” (少6) 可见,在BCD码结果中,只要一位BCD数字所对应的二进制码超过9(1010~1111),就应“加上6”,产生进位,进行调整。 这可由软件(调整指令)来完成。
135
组合BCD数十进制调整原理 例2 : 19 + 8 = 27 0 0 0 1 1 0 0 1 --------- 19
(结果不对) 运算时,低位数字向高位数字产生进位(AF=1或CF=1),实际上是“满16进一”,但进到高位,当成了10,“少6”,需“加6调整”. (结果正确) 可见,在BCD数运算时,若AF=1(或CF=1)就需在低4位(或高4位)上进行“加6调整”。
136
BCD数十进制调整规则 BCD数加法十进制调整规则:
如果两个BCD数字相加的结果是一个在1010~1111之间的二进制数,或者有向高一位数字的进位(AF=1或CF=1),则应在现行数字上加6(0110B)调整。 BCD数减法十进制调整规则: (1) AF=1,表示低位向高位有借位,低位要进行-6调整。 (2) CF=1,表示高位向高字节有借位,高位要进行-6调整。
137
(ii)组合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 ---×××××
138
例:计算BCD3 BCD1+BCD2 其中,BCD1,BCD2,BCD3定义为字变量,可分别存放4位数字的组合BCD数, 假定(BCD1) =1834 , (BCD2) = 2789. 指出执行每条指令的操作及执行指令后AL, AF, CF 的内容。 3 4 1 8 8 9 2 7 2 3 4 6
139
程序段 指令 操作 AL CF AF MOV AL, BCD1; AL 34 34 - - 不受影响
ADD AL, BCD2; AL BDH DAA ; 调整 BCD * 无关紧要 MOV BCD3,AL; (BCD3) * MOV AL, BCD1+1; AL * ADC AL, BCD2+1; AL CF 40H DAA ; 调整 BCD * MOV BCD3+1,AL; (BCD3+1) * 即 1834+2789=4623
140
组合BCD数 8086没有组合BCD数的乘法和除法调整指令,主要原因是相应的调整算法比较复杂,所以,8086不支持组合BCD数的乘除法运算。
141
(iii)分离BCD数调整指令 加法调整指令(AAA) 减法调整指令(AAS) 乘法调整指令(AAM) 除法调整指令(AAD)
142
异或 XOR DST,SRC DST DST SRC 测试 TEST OPR1,OPR2 OPR1 OPR2
2. 逻辑运算和移位指令 (i)逻辑运算指令 名称 格式 操作 非 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
143
左移1位时,若最高位(即符号位)发生改变(0 1或1 0),则OF=1,未发生改变时,OF =0; 逻辑右移 SHR OPR,CNT 0
(ii) 移位指令 名称 格式 操作 逻辑左移 SHL OPR,CNT (其中,OPR是除立即数以外的任何一种寻址方式,CNT可以是1或CL) 算术左移 SAL OPR,CNT 左移1位时,若最高位(即符号位)发生改变(0 1或1 0),则OF=1,未发生改变时,OF =0; 逻辑右移 SHR OPR,CNT 0 算术右移 SAR OPR,CNT CF CF CF CF
144
逻辑移位: 把操作数作为无符号数进行移位.右移时,最高位补0;左移时,最低位补0. 算术移位: 把操作数作为有符号数进行移位.右移时,最高位保持不变;左移时,最低位补0.
145
(iii) 循环移位指令 不带进位的循环左移 ROL OPR ,CNT 不带进位的循环右移 ROR OPR , CNT CF CF
146
循环移位指令 带进位的循环左移 RCL OPR , CNT 带进位的循环右移 RCR OPR , CNT CF CF
147
移位和循环指令 用来改变数据格式,有时用来提供程序 控制功能(例如根据移位后的CF状态作JC或JNC转移,或一些专门的运算功能。 注意:左移n位与乘以2 (n)等效,例如: 6×2 (2)= ×100= * 同样,右移n位与除以2(n)等效,如果是逻辑右移,除法是无符号的;如果是算术右移,则除法是带符号的(保持最高位不变,并做符号的扩展)
148
例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
149
例2:把从UNPACKED开始的16位分离BCD数转换成组合BCD数,并把结果存在从PACKED开始的单元里。
UNPACKED PACKED … …
150
程序段 MOV DX, 8; 将循环次数计数初值置为8 MOV CL, 4; 移位次数置为4 MOV SI, 0; MOV DI, SI;
CONVERT:MOV AX, WORD PTR[SI+UNPACKED]; SHL AL, CL; SHR AX, CL; MOV PACKED[DI], AL; 存储结果 ADD SI, 2; INC DI ; DEC DX ; 循环计数值减1 JNZ CONVERT
151
(三) 转移指令 无条件转移指令 条件转移指令 循环控制指令 中断及中断返回指令
152
(转移地址的偏移量在寄存器或内存单元中)
无条件转移指令示例 段内直接转移: JMP L ; 段内间接转移: JMP AX; (转移地址的偏移量在寄存器或内存单元中) 段间直接转移: JMP 2500H:3600H 段间间接转移: JMP DWORD PTR[DI] (转移地址在DI,DI+1,DI+2,DI+3四个字节单元中)
153
1. 段内直接转移 段内直接短转移:格式: JMP SHORT OPR (符号地址) 操作: IP IP+8 位位移量(-127~+128) 段内直接近转移: 格式: JMP NEAR PTR OPR(符号地址) 操作: IP IP+16位位移量 2. 段内间接转移: 格式: JMP WORD PTR OPR(可使用除立即数之外 的任何一种寻址方式) 操作: IP (EA)
154
. 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]
155
循环控制指令 通常的循环控制 MOV CX , N BEGIN: …. …. 循环体 …. DEC CX
… 循环体 …. DEC CX JNZ BEGIN LOOP BEGIN 有了LOOP指令,程序得到简化
156
为零或相等循环 LOOPZ OPR/LOOPE OPR ZF=1且CX=0
循环控制指令 从技术上讲,循环控制指令是条件转移指令,只不过它是专门为实现循环控制而设计的。 名称 格式/其它格式 测试条件 循环 LOOP OPR CX = 0 为零或相等循环 LOOPZ OPR/LOOPE OPR ZF=1且CX=0 非零或不相等循环 LOOPNZ OPR/LOOPNE OPR ZF=0 且CX=0
157
循环控制指令(续) 1.执行每条指令时,CX CX-1 2.OPR为一个标号
3.标志---------(意味着ZF并不受CX-1的影响,即ZF=1时,CX未必为0;ZF是前面指令决定的,与CX是否为0无关.)
158
例1:执行下述程序段后,AX= MOV CX , 5 MOV AX , 50 LP1: SUB AX , CX LOOP LP1 HLT
159
例2:在100个字符构成的字符串中寻找第一个$字符。
(在循环出口处可以根据ZF标志和CX寄存器的值来确定是否找到以及该字符的位置)
160
注意,上面程序段中ZF标志是由CMP指令设置的,而与CX减1动作无关。 MOV CX , 100
MOV SI,0FFFH;假设字符串从偏移地址1000H处开始存放 NEXT:INC SI CMP BYTE PTR[SI], ’$’ LOOPNZ NEXT 注意,上面程序段中ZF标志是由CMP指令设置的,而与CX减1动作无关。
161
子程序调用和返回指令 (1)调用指令 名称 格式 操作 段内直接调用 Call DST SP SP-2
名称 格式 操作 段内直接调用 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] (段内间接调用)
162
子程序调用和返回指令 名称 格式 操作 段间直接调用 Call DST SP SP-2 (SP+1,SP) CS
名称 格式 操作 段间直接调用 Call DST SP SP-2 (SP+1,SP) CS SP SP 保存返回地址 (SP+1,SP) IP IP 偏移量 CS 段基值 形成转移地址 例:Call FAR PTR Display
163
子程序调用和返回指令 名称 格式 操作 段间间接调用 Call DST SP SP-2 (SP+1,SP) CS
名称 格式 操作 段间间接调用 Call DST SP SP-2 (SP+1,SP) CS SP SP 保存返回地址 (SP+1,SP) IP IP (EA) CS (EA+2) 形成转移地址 EA:由DST的寻址方式计算出的有效地址 例:Call DWORD PTR [BX+SI]
164
子程序调用和返回指令 (2) 返回指令 名称 格式 操作 段内返回 RET (C3H) IP (SP+1,SP) SP SP+2
名称 格式 操作 段内返回 RET (C3H) IP (SP+1,SP) SP SP+2 段内带参数返回 RET n IP (SP+1,SP) SP SP+n(n 为偶数)
165
子程序调用和返回指令 (2) 返回指令 名称 格式 操作 段间返回 RET (CBH) IP (SP+1,SP) SP SP+2
名称 格式 操作 段间返回 RET (CBH) IP (SP+1,SP) SP SP+2 CS (SP+1,SP) 段间带参数返回 RET n IP (SP+1,SP) SP SP+2 SP SP+n(n为偶数)
166
过程(子程序)的基本结构 Proc-A PROC NEAR(或FAR) ____________ 过程名 ____________ . .
过程名 ____________ . RET ENDP
167
堆栈操作及RET n 指令使用举例 ret ? ret 2
例.在进入子程序FFIT 之前,主程序将字符串的首地址放于堆栈顶部,执行子程序FFIT 时,将字符串首址取到ES和DI 中,并取出要显示的字符,然后调用DISPLAY 子程序进行显示。 主程序: FFIT: DISPLAY: call FFIT call DISPLAY ret ? ret 2
168
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, ; 判取出的字符是否为结束符 JZ EEE PUSH AX ;通过堆栈为DISPLAY子程序传递参数(要显示的字符) CALL DISPLAY INC DI JMP AAA EEE: POP DI POP ES POP BP RET ?
169
堆栈操作及RET n 指令使用举例 DISPLAY 子程序返回地址 AX DI ES BP SP FFIT 子程序的返回地址
字符串首址偏移量 字符串首址段基值
170
8.1.3 指令的机器码格式及指令的执行时间 1. 指令前缀和段超越前缀的编码
前缀并不是一条独立的指令,而是对其后的指令或对指令中操作数的一种限制。 8086/8088提供的前缀有三种: 串操作的重复前缀(REPREPE/REPZ、REPNE/REPNZ) 总线封锁前缀(LOCK) 段超越前缀(ES:、CS:、SS:、DS:) 这些前缀共有7种不同的编码,长度都是一个字节,如表8-20所示。
171
指令前缀及段超越前缀的编码 指令前缀 指令前缀的编码 段超越前缀 段超越前缀的编码 LOCK 11110000(F0H)
指令前缀 指令前缀的编码 段超越前缀 段超越前缀的编码 LOCK (F0H) REPNE/REPNZ (F2H) REPE/REPZ (F3H) REP (F3H) ES: (26H) CS: (2EH) SS: (36H) DS: (3EH)
172
2. 指令的机器码格式 8086/8088的机器指令长度(不包括前缀)随指令的不同而不同,最短的为1个字节,最长的为6个字节。指令代码中各字节的排列顺序依次为:1个字节的操作码,可能存在的1个寻址方式字节,可能存在的1~2个字节的地址位移量(或地址)和可能存在的1~2个字节的立即数。 指令中的地址位移量(或地址)和立即数如果是16位的话,都是低字节放在存储器的低地址单元,高字节放在存储器的高地址单元。指令的一般格式如下图所示:
173
8086/8088指令编码的一般格式 图 低字节 高字节 低字节 高字节 操作码 字节 寻址方式 字节 位移量(或地址) 立即数
174
(1) 操作码字节 操作码字节用来表示该指令执行的操作,每条指令都有操作码字节。大多数指令都使用8位的操作码,但有些指令的操作码少于8位或多于8位。 各种情况下的操作码字节共有10种格式,如图8.8所示。
175
图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 操作码字节的各种编码格式
176
D位用于需要指明两个寄存器/存储器操作数的双操作数指令中。这种指令的两个操作数必须有一个是寄存器,D位则用来指出寻址方式字节中用reg域标识的那个寄存器是源操作数还是目的操作数:
W位用于指明是字节操作还是字操作: 若W=0,则是字节操作; 若W=1,则是字操作。
177
(2) 寻址方式字节 大多数指令的寻址方式字节分为三个域,即mod域、reg域和r/m域。mod域占两位,代表“方式”;reg域占3位,是通用寄存器的3位代码;r/m域占3位,代表存储器的某个地址或某个通用寄存器。 各种情况下的寻址方式字节共有5种格式,如图8.9所示。
178
图8.9 寻址方式字节的各种编码格式 mod reg r/m mod 0 sr r/m mod XXX r/m XXXXXXXX
mod UUU r/m 图8.9 寻址方式字节的各种编码格式
179
表8-21 reg域和sr域所代表的寄存器 reg域 sr域 000 001 010 011 100 101 110 111 00 01
W=1 AX CX DX BX SP BP SI DI ES CS SS DS W=0 AL CL DL BL AH CH DH BH
180
表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
181
例1:将指令“MOV [BX+DI-6],CL”写成机器码格式。
解 :这是一条寄存器送存储器的指令。由附录二可知该指令的格式如下,是一条3字节指令: DW mod reg r/m disp8 因为(reg域指出的)寄存器是源操作数,所以D=0;由CL寄存器的编码知reg=001。因为是字节操作,所以W=0。因为目的操作数是存储器且带有8位位移量,所以mod=01;寻址方式[BX+DI+disp8]的r/m=001。位移量为(-6),其补码是 。因此,该指令的机器码是“ ”。
182
例2:将指令“ADD AX,BX”写成机器码格式。
解:这是一条将两个寄存器的内容相加,将结果送入其中一个寄存器的指令。由附录二可知该指令的格式如下,是一条两字节指令: DW mod reg r/m 因为(reg域指出的)寄存器是目的操作数,所以D=1;由AX寄存器的编码知reg=000。因为是字操作,所以W=1。因为目的操作数是寄存器,所以mod=11,另一个寄存器BX的编码为011。 因此,该指令的机器码是“ ”。
183
4. 指令的执行时间 一条指令的完整执行包括取指令、计算操作数的地址、取操作数、执行指令、存放操作结果等步骤。因此,一条指令的执行时间也就是上述各步骤所需时间的总和。 详细地讨论一条指令的执行时间是很复杂的,即使不考虑人机交互等外在因素,仅从机器的因素来考虑,也有很多因素的影响. 在后面计算指令的执行时间时,都承认一些假定,如:指令已预取在指令队列中,没有外部事件的影响,没有其他处理器竞争占用总线,等等。
184
(1) 有效地址的计算 在存/取存储器操作数以前,需要先计算出它的有效地址EA。EA的计算时间取决于指令的寻址方式,具体情况如表8-24所示。
185
表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
186
(2) 指令执行时间的计算 由于假定每条指令在执行前已经预取在指令队列中,因此,取指令的时间不用考虑。
(2) 指令执行时间的计算 由于假定每条指令在执行前已经预取在指令队列中,因此,取指令的时间不用考虑。 指令在CPU中的执行时间又叫基本执行时间,这个时间对确定的指令可认为是固定的。这样就有下面的等式: 指令的执行时间 =计算有效地址的时间+基本执行时间+访问内存的时间 8086系统中存取一个字操作数时,访问存储器的次数与字操作数的存放地址(奇、偶)有关。当该字操作数的地址是偶数时只需访问一次存储器;当该字操作数的地址是奇数时需要访问两次存储器。 另外还假定访问一次存储器都需要4个时钟周期。
187
表8-25 8086指令的执行时间举例 (1) 指 令 所需时钟周期数 ADD或SUB 寄存器到寄存器 3 内存到寄存器 9+EA
表8- 指令的执行时间举例 (1) 指 令 所需时钟周期数 ADD或SUB 寄存器到寄存器 3 内存到寄存器 9+EA 寄存器到内存 16+EA 立即数到寄存器 4 立即数到内存 17+EA
188
表8-25 8086指令的执行时间举例 (2) 续表 指 令 所需时钟周期数 MOV 累加器到内存 10 内存到累加器 寄存器到寄存器 2
表8- 指令的执行时间举例 (2) 续表 指 令 所需时钟周期数 MOV 累加器到内存 10 内存到累加器 寄存器到寄存器 2 内存到寄存器 8+ EA 寄存器到内存 9+EA 立即数到寄存器 4 立即数到内存 10+EA 寄存器到段寄存器 内存到段寄存器 8+EA 段寄存器到寄存器 段寄存器到内存
189
表8-25 8086指令的执行时间举例 (3) 续表 指 令 所需时钟周期数 IDIV 除数在8位寄存器中 101~112
表8- 指令的执行时间举例 (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(转移时)
190
从表8-25可以看出,寄存器之间的操作比使用任何其他寻址方式的操作都要快。寄存器至存储器的操作比存储器至寄存器的操作慢,因为前者要两次访问存储器。
在表8-26中,以5MHz时钟(时钟周期为0.2μs)的8086系统为例,列出了ADD 指令在几种情况下的执行时间。
191
表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.6 4.2 5.0 4.8 6.4
192
第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 ;
193
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]” 源操作数的有效地址为_____________,物理地址为_____________.
194
5 .将内存1000H地址开始的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开始处,试编程实现。
195
8. 编写一段程序把从PACKED开始的16位压缩的BCD数变成非压缩的BCD数,并把结果存放在从UNPACKED开始的单元里。
7.在数据段中从偏移地址BUF开始连续存放着100个字符,编写一段程序,将该字符串中所有的字母′A′都改成字母′B′。 8. 编写一段程序把从PACKED开始的16位压缩的BCD数变成非压缩的BCD数,并把结果存放在从UNPACKED开始的单元里。
Similar presentations