Download presentation
Presentation is loading. Please wait.
1
微机原理与接口技术 第3章 8086/8088指令系统 黄强 深圳大学 信息工程学院
2
本章内容位于 书本P49—P77,P82—P114
3
第3章 指令系统与汇编语言 本章主要教学内容 本章教学目的 1、8086指令系统的寻址方式、指令格式及应用
第3章 指令系统与汇编语言 本章主要教学内容 1、8086指令系统的寻址方式、指令格式及应用 2、汇编语言基本格式、程序设计步骤和方法 3、顺序、分支、循环、子程序的基本结构和设计方法 4、DOS和BIOS中断调用 本章教学目的 使学生掌握指令系统及其应用,学会程序设计的方法。 教学重点:指令系统的应用、汇编语言程序设计 教学难点:指令的寻址方式、程序设计技巧
4
第3章 指令系统与汇编语言 3.1 寻址方式 3.2 8086指令系统 3.3 汇编语言简述 3.4 汇编语言程序设计
第3章 指令系统与汇编语言 3.1 寻址方式 指令系统 3.3 汇编语言简述 3.4 汇编语言程序设计 3.5 DOS和BIOS中断调用
5
第一节 8086/8088的寻址方式 一、内容: 8086/8088的寻址方式 二、作业:2-1, 2-2, 2-3 , 2-4 , 2-5
第一节 /8088的寻址方式 一、内容: 8086/8088的寻址方式 二、作业:2-1, 2-2, 2-3 , 2-4 , 2-5 三、复习内容:P33-P37, P76-P77 四、予习内容:P52-P80
6
8086/8088的寻址方式讲课内容 一、指令系统概念和指令组成 二、8086/8088寻址方式 三、与转移地址有关的寻址方式 四、小结
7
一、指令系统概念和指令组成 1、指令系统概念 计算机通过执行指令序列来解决问题, 每种计算机都有一组指令集提供用户使用,
这组指令集就称为计算机的指令系统。 2、指令组成 计算机中指令由操作码字段和操作数字段两部分组成。 一条可以由1~7个字节组成。 操作码字段-----―指示计算机要执行的操作, 操作数字段-----―指出在指令执行操作过程中所需要的操作数; 可以是操作数本身; 可以是操作数地址或是地址的一部分; 可以是指向操作数地址的指针 或其他有关 操作数的信息。
8
3、指令的一般格式: 操作码字段: 在机器里只需对某种操作指定确定的二进制代码。 通常用指令的第一个字节表示,不够可以占第二个字节中的3位。
操作数字段: 操作数字段可以有一个,二个或三个地址指令。 例: INC CX ADD AX , BX
9
4、操作数的存放 操作数的存放不外乎三种情况: (1) 操作数包含在指令中 即指令的操作数字段包含操作数本身。这种操作数为立即数。 例:MOV AL , 08H (2)操作数包含在CPU的一个内部寄存器中 例:INC CX 指令中的操作数字段是CPU内部寄存器的一个编码。 这种寻址方式称为寄存器寻址。
10
(3)操作数在内存数据区 操作数在内存数据区,操作数字段包含着此操作数地址。 在8088中,任何内存地址是由两部分组成:
段的基地址:单元所在段的基地址 (大部分情况是数据段寄存器DS中); 段内偏移量:此单元与段基地址的距离。 有效地址EA(Effective Address) : 段内偏移量为适应各种数据结构的需要,可以有几个部分组成,所以也把它称为有效地址EA。
11
寻址方式不同EA的构成不同。 归纳EA可有多种情况构成: 直接寻址,寄存器间接寻址,寄存器相对寻址, 基址加变址寻址,相对基址加变址寻址。 寻址方式——如何寻找内存操作数。 不同寻址方式实质上是构成它段内的偏移量的方法不同。
12
二、8086、8088寻址方式 (一)立即寻址 (Immediate addressing)
(二)寄存器寻址方式 (Register addressing) (三)直接寻址 (Direct addressing) (四)寄存器间接寻址方式(Register indirect addressing) (五)寄存器相对寻址方式(Register relative addressing) 或变址寻址(Index Addressing) (六)基址加变址寻址方式(Based indexed addressing) (七)相对基址加变址寻址方式(Relative based indexed addressing)
13
(一)立即寻址(Immediate addressing)
操作数直接存放在指令中,紧跟在操作码之后,作为指令 的一部分,存放在代码段里,这种操作数称为立即数。 立即数可以是8位或16位的。 16位的立即数是高位字节放在高地址,低位字节放在低地址。 使用场合:经常用于给寄存器赋初值。 注意:只能用于源操作数字段,不能用于目的操作数字段。
14
例: MOV AL,05H 指令执行后: (AL)=05H 例: MOV AX,3064H 指令执行后: (AX)=3064H 立即寻址方式
15
(二)、 寄存器寻址方式 (Register addressing)
操作数在寄存器中,指令指定寄存器号。 对于16位操作数,寄存器可以是: AX,BX,CX,DX,SI,DI,SP,BP。 以及段寄存器。 对于8位操作数,寄存器可以是: AL,AH,BL,BH,CL,CH,DL,DH。 这种寻址方式因为操作数在寄存器中 不需要访问存储器的运算速度较高。
16
例: 指令执行前:(AX)=3064H (SS)=1234H MOV SS,AX 指令执行后: (SS)=3064H (AX)保持不变。 指令执行前: 指令执行后: 寄存器寻址方式
17
(三)直接寻址(Direct addressing)
操作数地址的16位偏移量,直接包含在指令中, 存放在代码段中指令操作码之后, 但操作数一般存放在数据段中, 必须先求出操作数的物理地址, 然后再访问存储器才能取得操作数。 或(10H) 物理地址 : PA=16d×(DS)+EA IBMPC机允许数据存放在数据段以外的其它段中。此时应在指令中指定段跨越(可以是CS,SS,ES)。
18
例:MOV AX,[3100H] (DS)=6000H , (63100H)=3050H 则:(AX)=3050H 又如:用符号地址代替数值地址。 MOV AX,VALUE 或 MOV AX,[VALUE] VALUE——有效操作数单元的 符号地址。 如:VALUE在附加段中, 则应指定段跨越。 MOV AX,ES:VALUE 或MOV AX,ES:[VALUE] 直接寻址方式
19
注意: 例: 要处理某存放在存储器里的变量,可以用直接寻址方式把变量先取到一个寄存器中再作处理。 (1)直接寻址方式适用于处理单个变量。
(2)直接寻址方式隐含的段寄存器是 DS, 8086/8088允许段跨越,即允许使用 CS SS ES作为段寄存器,这时,必须在指令中特别标明。 (3)IBM PC机中规定双操作数指令必须有一个操作数使用寄存器方式,这就是常常先要把一个变量送到寄存器去的原因。 例: 要处理某存放在存储器里的变量,可以用直接寻址方式把变量先取到一个寄存器中再作处理。
20
(四) 寄存器间接寻址方式(Register indirect addressing)
操作数在存储器中, 操作数地址的16位偏移量包含在: BP、BX、SI、DI寄存器中。 1、若选择SI、DI、BX作为间接寻址 操作数一般在现行数据段区域中,用(DS)作为段地址。 即操作数物理地址为: 物理地址PA=16 d ×(DS)+(BX) 物理地址PA=16 d × (DS)+(SI) 物理地址PA=16 d × (DS)+(DI)
21
例:MOV BX,[DI] (DS)=6000H (DI)=2000H PA=62000H (62000H)=50A0H
(BX)=50A0H 寄存器间接寻址方式 MOV BX,[DI]
22
操作数在堆栈段区域中,用SS寄存器的内容作为段地址。 操作数物理地址: PA=16d × (SS)+(BP) 例: MOV [BP], AX
执行前: (SS)=1000H , (BP)=3000H , (AX)=1234H 执行后:PA=13000H (13000H)=1234H 寄存器间接寻址方式 MOV [BP], AX
23
3 、用 SI、DI、BX 、BP作为间接寻址允许段跨越
指令中可以指定段跨越前缀来取得其他段中的数据。 例:MOV ES:[DI], AX MOV DX, DS:[BP] 这种寻址方法可以用于表格处理。
24
(五) 寄存器相对寻址方式(Register relative addressing) 或变址寻址 (Index Addressing)
操作数的有效地址是一个基址或变址寄存器的内容 和指令中指定的8位或16位位移量(displacement)之和。
25
8086/8088 CPU 中有两个变址寄存器 : 源变址寄存器 SI ; 目的变址寄存器 DI 。 操作数一般在内存的数据段中,但允许段跨越。 除有段跨越前缀之外,形成物理地址有二种方式:
26
例: MOV AX, COUNT [BP] 或MOV AX, [COUNT+BP] 或MOV AX, COUNT+[BP]
指令执行前: (SS)=5000H, (BP)=3000H, COUNT=2040H, (AX)=1234H 指令执行后:EA=5040H PA=55040H (55040H)=5548H (AX)=5548H 寄存器相对寻址方式 MOV AX,COUNT[BP]
27
用途:这种寻址方式同样用于表格处理。 表格首地址COUNT 修改基址或变址寄存器来取得表格中的值。 例:某数据表的首地址为COUNT 欲读取表中第10个数据,存放到(AL)中。 第10个数据的有效地址: EA= COUNT + 9 MOV SI , 09H MOV AL , [SI+COUNT] * 直接变址寻址方式也可以使用段跨越前缀 MOV DL,ES:STRING[SI]
28
(Based indexed addressing)
(六) 基址加变址寻址方式 (Based indexed addressing) 操作数的有效地址是一个基址寄存器和一个变址寄存器的内容之和,基址寄存器名和变址寄存器名均有指令指定。
29
除有段跨越前缀之外,形成物理地址有二种方式:
30
例: MOV AX, [BX][SI] 或 MOV AX, [BX+SI] 执行指令前: (DS)=3200H, (BX)=0456H,
(SI) =1094H (334EAH)=4567H 执行指令后: EA=14EAH PA=334EAH (AX)=4567H 基址加变址寻址方式 MOV AX,[BX+SI]
31
用途:这种寻址方式同样适用于数组或表格处理。
表格首地址 基址寄存器中, 用变址寄存器来访问数组中的元素。 二个寄存器都能修改, 所以比直接变址方式更灵。 这种寻址方式允许段跨越。 使用段跨越前缀格式: MOV AX,ES:[BX][SI]
32
(七)相对基址加变址寻址方式 (Relative based indexed addressing)
操作数有效地址是一个基址寄存器和一个变址寄存器的内容和8位或16位位移量之和 。
33
除有段跨越前缀之外,形成物理地址有二种方式:
34
例: MOV AX, MASK[BX][DI] MOV AX, MASK [BX+DI] MOV AX,[MASX+BX+DI]
执行指令前: (DS)=3000H (BX)=1346H (DI)=0500H MASK=1234H (32A7AH)=4050H 执行指令后: EA=2A7AH PA=32A7AH (AX)=4050H 相对基址加变址 MOV AX, MASK+[BX+DI]
35
用途: 这种寻址方式为堆栈处理提供方便: (BP) 栈顶(一般 BP 可指向栈顶) 从栈顶到数组的首地址可以用位移量表示(MASK). 变址寄存器(SI)或(DI)——指向数组中某个元素。
36
三、与转移地址有关的寻址方式 段内转移只需改变 (IP) 段内转移包括两种寻址方式:直接 ,间接。 段间转移改变(CS)(IP)
段内转移包括两种寻址方式:直接 ,间接。 段间转移改变(CS)(IP) 段间转移包括两种寻址方式: 直接 ,间接。 功能: 用来确定转移指令及CALL指令的转移地址。 以转移指令为对象来分析各种转移地址寻址方式。
37
(一)段内直接寻址(Intrasegment direct addressing)
(二)段内间接寻址(Intrasegment indirect addressing) (三)段间直接寻址(Intersegment direct addressing) (四)段间间接寻址:(Intersegment inderect addressing)
38
(一)段内直接寻址(Intrasegment direct addressing)
转向有效地址EA是(IP)当前和指令中指定的8位或16位位移量之和。 相对寻址方式含义: EA(即转向的有效地址) 用相对于(IP)当前值的位移量表示。 位移量:位移量=转向有效地址-(IP)当前值之差。 对于近转,16位位移量可正可负,一般范围是-32768~+32767 对于短转,8位位移量可正可负, 范围是 -128~+127, 这种寻址方式适用于条件转移及无条转移指令。 当用于条件转移指令时,位移量只允许 8 位; 用于无条件转移指令时,位移量 8 位时称为 短跳转。
39
指令汇编语言格式: JMP NEAR PTR PROGIA;(IP)←(IP)当前+16位位移量 JMP SHORT QUEST; (IP)←(IP)当前+8位位移量 调用指令(CALL)也适用。 PROGIA 均为转向符号地址,机器中用 位移量表示。 QUEST 汇编指令中16位位移量,则在符号地址前加操作符 NEAR PTR。 8位位移量 : 前引用标号(标号后定义 ),则在符号地址前加操作符SHORT。 后引用标号(标号先定义 ),则在符号地址前不必加操作符 SHORT。
40
JMP NEAR PTR PROGIA; (IP)←(IP)当前+16位位移量
段内直接寻址 JMP NEAR PTR PROGIA
41
(二)段内间接寻址(Intrasegment indirect addressing)
段内间接寻址: 转向有效地址是一个寄存器或一个存储单元的内容, 这内容可以用数据寻址方式中除立即数以外的任何一种寻址方式取得。得到的转向有效地址用来取代IP寄存器的内容。 这种寻址方式和以下二种段间寻址方式都不能用于条件转移指令。 * 条件转移指令只能适用段内直接寻址的8位位移量。
42
汇编格式:JMP BX JMP WORD PTR [BP + TABLE] 其中: WORD PTR——操作符, (BP)+TABLE 寻址所得地址是一个字的有效地址, 由有效地址形成物理地址里的内容即为转向有效地址IP。 转向物理地址的计算公式:PA=16d(CS)+(IP)
43
段内间接寻址方式的转移指令中转移的有效地址的计算方法:
举例: 指令执行前: 设:(DS)=2000H,(BX)=1256H,(SI)=528FH, TABLE=20A1H, (232F7H)=3280H,(264E5H)=2450H 例1、JMP BX 指令执行后: (IP)=1256H
44
例2、JMP WORD PTR TABLE[BX]
指令执行后: PA= 16d(DS)+(BX)+TABLE = 232F7H (IP) = 3280H=(232F7H) 例3、JMP WORD PTR [BX][SI] PA= 16d (DS)+(BX)+(SI)= 264E5H (IP) = 2450H=( 264E5H) 注意:如果指令操作数已被定义为16位的存储器,则: WORD PTR 可以省去。
45
(三)段间直接寻址:(Intersegment direct addressing). 指令中直接提供了转向段地址和偏移地址。
(三)段间直接寻址:(Intersegment direct addressing) 指令中直接提供了转向段地址和偏移地址。 用指令中指定的偏移地址 (IP) 用指令中指定的段地址 (CS) 完成了从一段到另一段的转移操作 指令汇编语言格式: JMP FAR PTR NEXTROUTINT NEXTROUTINT —— 转向的符号地址 FAR PTR —— 段间转移操作符 OFFSET NEXTROUTINT (IP) SEG NEXTROUTINT (CS)
46
例:JMP FAR PTR CCC
47
(Intersegment inderect addressing)
(四)段间间接寻址 (Intersegment inderect addressing) 用存储器中二个相继字的内容取代IP、CS以达到段间转移目的。 存储单元的地址是由指令指定除立即数方式和寄存器方式以外的任何一种寻址方式取得。 指令汇编语言格式: JMP DWORD PTR [INTERS+BX] DWORD PTR——双字操作符,转向地址双字(段间转移) [INTERS+BX]——数据寻址方式为直接变址寻址方式 * 段间转移必须是无条件转移。
48
例:JMP DWORD PTR [BX] 指令执行前: 设: (DS)=4000H, (BX)=1212H (41212H)=1000H (41214H) =4A00H 指令执行后: (IP)=1000H (CS)=4A00H
49
四、小结 1、三种类型操作数 2、三种类型操作数特点 3、8088中的存储器分段
50
1、三种类型操作数 综观8086/ 8088寻址方式,其操作数有三种类型: 2、三种类型操作数特点:
综观8086/ 8088寻址方式,其操作数有三种类型: 立即操作数、寄存器操作数、存储器操作数。 2、三种类型操作数特点: (1)立即操作数 可以使用立即操作数指令有: 数据传送指令、算术运算指令(乘、除运算指令除外)、 逻辑运算指令等。 立即数只能作为源操作数,不能作为目标操作数。
51
寄存器操作数 8位和16位无符号数和带符号数的取值范围: 寄存器操作数可能存放在: 8086 /8088的通用寄存器、地址指针或变址寄存器
以及段寄存器。
52
通用寄存器包括4个16位寄存器: AX、BX 、 CX 、 DX。用于存放字操作数。 4个16位通用寄存器可以当作8位寄存器使用: AH 、AL、 BH 、BL、 CH、 CL、 DH 、DL存放字节操作数。 通用寄存器、地址指针寄存器可以作为源操作数,也可以作为目标操作数。 与通用寄存器或存储器传送数据时,段寄存器可以作为源操作数或目标操作数. 段寄存器DS、 ES、 SS 、CS存放当前的段地址。 对段寄存器ES 、DS 、SS进行赋值,不能将立即数直接送段寄存器,要将立即数送通用寄存器,再从通用寄存器送段寄存器。CS一般不用赋值。
53
隐含操作数 某些指令规定只能使用指定操作数寄存器, 从汇编形式看,似乎没有指出操作数,实际隐含某些特定寄存器操作数。该寄存器可能是: 累加器 、通用寄存器、变址寄存器、某些段寄存器。
54
(3)、存储器操作数 存储器操作数可能存放在一个、二个、或四个存储器单元中。 操作数类型分别为:字节、字、双字。 存储器操作数可以作为源操作数,也可以作为目标操作数。 但不允许源操作数、目标操作数同时为存储器操作数。 存储器操作数的有效地址EA的取得方法: 直接寻址 寄存器间接寻址 相对寄存器寻址 基址加变址寻址 相对基址加变址寻址 存储器操作数的物理地址PA的取得方法: 一般存储器操作数指令中隐含段寄存器,有的指令允许段跨越, 需要在指令中标明。
55
3、8088中的存储器分段 段区域默认状态: 可以在某一个段64K字节范围内寻找一个内存操作数,以什么样 寻址(寄存器间址、变址、与基址加变址),则操作数就在什么段区域中,在8088中有一个基本约定,只要在指令中不特别说明超越这个约定,则正常情况就按这个基本约定来寻找操作数,这就是所谓的默认状态。 段跨越:数据操作数通常在数据段,但在程序中若需要的话数据可以在码段、堆栈段也可以在附加段。 * 程序段只能在码段 堆栈操作只能在堆栈段 目的串只能在附加段 此外,其他情况都允许段跨越
56
在8088中的这些基本约定和允许超越的情况,如下表示:
57
第二节 80386、80486、80586、Pentium的寻址方式(自学)
(了解 )自学提纲 在8086/8088CPU的七种寻址方式的基础上,又扩充了三种。 8086/8088CPU七种寻址方式: 立即寻址 寄存器寻址 直接寻址 寄存器间接寻址 相对寄存器寻址 基址加变址寻址 相对基址加变址寻址 80386、80486、80586、Pentium 扩充了三种寻址方式: 带比例因子的变址寻址 基址加比例因子的变址寻址 相对基址加比例因子的变址寻址。
58
EA=基址+(变址比例因子)+ 位移量 位移量:8位,16位,32位。 比例因子:取1,2,4,8。
59
80386、80486、80586、Pentium的指令 80386、80486、80586、Pentium的指令比8086/8088的指令
除了寄存器增多了,操作数类型可以使用双字类型以外, 增加了一些指令和一些新的指令类型。 新增加的指令类型是: 条件设置指令 位处理指令(位测试、位扫描) 支持高级语言的指令(边界测试、栈空间处理)。
60
第三节 8086/8088的指令系统 8086/8088的指令系统中共有92种基本指令。 可以分成6个功能组:
第三节 /8088的指令系统 8086/8088的指令系统中共有92种基本指令。 可以分成6个功能组: 1. 数据传送(Data transfer) 2. 算术运算(Arithmetic) 3. 逻辑运算和移位指令(Logic& Shift) 4. 串操作(String manipulation) 5. 控制转移(Control Transfer) 6. 处理器控制(Processor Control)
61
第一部分 指令系统概述 第二部分 8086/8088的指令系统 一. 数据传送(Data transfer)
第一部分 指令系统概述 第二部分 /8088的指令系统 一. 数据传送(Data transfer) 二. 算术运算(Arithmetic) 三. 逻辑运算和移位指令(Logic& Shift) 四. 串操作(String manipulation) 五. 控制转移(Control Transfer) 六. 处理器控制(Processor Control)
62
第一部分 指令系统概述 8086/8088的指令系统中共有92种基本指令。 可以分成6个功能组:
第一部分 指令系统概述 8086/8088的指令系统中共有92种基本指令。 可以分成6个功能组: 1. 数据传送(Data transfer) 2. 算术运算(Arithmetic) 3. 逻辑运算和移位指令(Logic& Shift) 4. 串操作(String manipulation) 5. 控制转移(Control Transfer) 6. 处理器控制(Processor Control)
63
介绍指令系统使用的符号: 八位寄存器: AH,AL,BH,BH,BL,CH,CL,DH,DL
十六位通用寄存器: AX,BX,CX,DX,SP,BP,SI,DI 堆栈指针 SP 指令指针 IP(或PC) 标志位 Flags 目的和源变址寄存器 DI, SI 段寄存器 CS, DS, ES, SS 通用寄存器 r AL或AX(取决于操作数长度) acc
64
src , dest 源,目的操作数(下列寻址方式都可以用)
[BX+SI+n],[BX+DI+n],[BP+SI+n],[BP+DI+n] [SI+n], [DI+n], [BP+n], [BX+n] [N], r [ ] 存储器单元的内容(正常在数据段) ES:[ ] 附加存储器段的内容 OPRD 操作数 Seg 段寄存器(CS,DS,ES,SS) i m 立即数 (n 8位, nn 16位, nnnn 位 )
65
8086/8088指令助记符表 (自学)
66
8086/8088指令助记符表(续)
67
第二部分 /8088指令系统 一、 数据传送指令(Data transfer) (一)通用传送指令(General Purpose Transfer) (二)输入输出指令(Input and Output) (三)目的地址传送指令(Address-object transfer) (四)标志传送指令(Flag register transfer)
68
一. 数据传送指令 功能: 负责把数据、地址或立即数传 送到寄存器或存储单元。 特点: 它是计算机最基本、最重要的一种操作,使用比例最高。
一. 数据传送指令 功能: 负责把数据、地址或立即数传 送到寄存器或存储单元。 特点: 它是计算机最基本、最重要的一种操作,使用比例最高。 种类(分四种): 通用传送指令包括: MOV, PUSH, POP ,XCHG, XLAT。 输入输出指令指令包括: IN, OUT。 目的地址传送指令包括: LEA, LDS, LES 标志传送指令包括 : LAHF, SAHF, PUSHF, POPF 除 SAHF和POPF指令外,对标志位没有影响。
69
(一)通用传送指令(General Purpose Transfer)
8088提供方便灵活的通用的传送操作,适用于大多数操作数。 通用传送指令(除了XCHG以外)是唯一允许以段寄存器为操作数指令。 通用传送指令包括: 1、MOV (Movement) 2、PUSH (Push word onto stack) POP (Pop word off stack) 3、XCHG (Exchange) 4、XLAT (Translate)
70
1. MOV dest, src ; (dest) (src)
目的 源 目的 源 功能: 把一个字节(B)或一个字(W)操作数由源传送至目的。 实现: 寄存器 寄存器/存储器之间; 立即数寄存器/存储器 寄存器/存储器段寄存器之间的数据传送。
71
具体说,通用数据传送指令能实现: ① CPU内部寄存器之间的数据的任意传送 (除了码段寄存器CS和指令指针IP以外)。
具体说,通用数据传送指令能实现: ① CPU内部寄存器之间的数据的任意传送 (除了码段寄存器CS和指令指针IP以外)。 段寄存器之间不能传送。 例: MOV DL,CH ; 8位寄存器 8位寄存器 MOV AX,DX ; 16位寄存器 16位寄存器 MOV SI, BP MOV DS,BX ;通用寄存器 段寄存器 MOV AX, CS ;段寄存器 通用寄存器
72
立即数传送至CPU内部通用寄存器组 (AX、BX、CX、DX、BP、SP、SI、DI)。 用于给寄存器赋初值。 不能直接给段寄存器赋值 例: MOV CL,04H ;立即数8位寄存器 MOV AX,03FFH ;立即数16位寄存器 思考:为什么加WORD PTR , BYTE PTR ?不加对吗? MOV WORD PTR [ SI] ,057BH ;立即数存储器 MOV BYTE PTR MEM, ;立即数存储器
73
CPU内部寄存器(除CS和IP外) 与存储器(所有寻址方式)之间数据传送。 可以实现一字节或一个字的传送。 存储单元之间不能直接传送 例:
MOV MEM , AX ; 累加器存储器,直接寻址 MOV MEM ,DS ;段寄存器存储器,直接寻址 MOV DISP[BX] ,CX ;寄存器存储器,变址寻址 MOV AX , DISP [SI] ;存储器累加器,变址寻址 MOV DS , MEM ;存储器段寄存器,直接寻址 MOV CX , DISP [BX] [SI] ;存储器累加器,相对基址加变址
74
注意: (1)不能用一条MOV指令实现以下传送。 存储单元之间的传送 MOV MEM2 , MEM1 错。 MOV AX , MEM1
注意: (1)不能用一条MOV指令实现以下传送。 存储单元之间的传送 MOV MEM2 , MEM1 错。 MOV AX , MEM1 MOV MEM2 , AX 对。 立即数送段寄存器 例 : MOV DS,2000H 错。 MOV AX, 2000 H MOV DS , AX 对。
75
CS和IP不能作为目标操作数,CS可以作为源操作数。
段寄存器之间的传送 MOV ES , DS ; 错 MOV AX , DS MOV ES , AX ; 对 。 注意CS和IP的使用 CS和IP不能作为目标操作数,CS可以作为源操作数。 例: MOV CS,AX ; 错 MOV AX,CS ;对 。 MOV IP, AX ;错 MOV AX, IP ; 对。
76
(2)段地址的默认 BX、SI、DI间址默认段地址为DS, BP间址默认段地址SS。 (3) 凡是遇到给SS赋值指令,系统自动禁止外部中断,执行本条指令和下条指令,恢复对SS寄存器赋值前的中断开放情况。 这样做为了允许程序员连续用两条指令分别对SS和SP寄存器赋值,同时又防止堆栈空间变动过程出现中断。 *在修改SS和SP的指令之间不要插入其他指令。 (4) 所有通用传送指令不影响标志位 (除SAHF、POPF以外)。
77
MOV指令应用 例: 实现将AREA1开始的100个数据传送到AREA2开始的单元。 100个数据 AREA1: … … AREA2:
78
分析题意: ①可以用200条MOV指令来完成100个数据传送, 指令操作重复,每个数据传送后的地址是变化的。 ② 可以利用循环, 但每循环一次要修改地址(源地址和目的地址), 必须把地址放在寄存器当中,用寄存器间接寻址来寻找操作数.
79
得到如下程序: … MOV SI,OFFSET AREA1 MOV DI,OFFSET AREA2 MOV CX,100
AGAIN : MOV AL,[SI] MOV [DI],AL INC SI ;修改地址指针 INC DI ;修改地址指针 DEC CX ;修改个数 JNZ AGAIN
80
MOV指令的字节数、时钟周期数、CPU与内存间传送次数
例 时钟数 M传送到CPU次数 MOV指令操作数 AX M M AX 10(14) 1 3 MOV COUNT[DI], AX R R MOV AX,TEMP 2 MOV DS,BX M R R M 8(12)+ EA 2~4 MOV BP,STAK_TOP 9(13)+ EA MOV COUNT[BX][SI],CX i m R (段寄存器除外) 4 2~3 MOV CL,2 M 10(14)+ EA 3~6 MOV word ptr [BP],5H 段 16 (CS、IP除外) MOV ES,CX MOV BP,SS M R MOV DS,SEG_BASE MOV[BX]SEG_SAN,CS
81
表中: (1)时钟数——执行指令所需的时钟周期数, 直接决定了指令的执行时间。 时钟数决定因素 : 决定于是字节操作还是字操作; 若是内存操作数,决定于寻址方式 (还要加上内存操 作数的寻址时间 )。 表中b( )的含义: b --字节操作时钟数 ( )--字操作时钟数
82
计算EA 需要的 时钟数:如下表所示: (若段超越,再加两个时钟周期)
83
(2)指令字节数: 指令字节数与寻址方式有关。 通常操作码占二个字节; 立即寻址 : 立即数增加1-2个字节数; 操作数在内存中 : 直接寻址 :直接地址为1-2个字节,总的指令长3-4个字节; 寄存器间接寻址(没有位移量): 2个字节; 变址寻址或者相对基址加变址 : 都有1-2字节的位移量, 指令字节数为2-4个 字节。
84
(3)传送次数: 指执行指令时,内存与CPU之间数据传送的次数。 凡是立即数→寄存器或寄存器之间的传送无此传送数。 凡是寄存器与存储器之间传送次数为1。
85
2. PUSH (Push word onto stack)
POP (Pop word off stack) 这是两条堆栈操作指令。 (1) 先介绍一下什么是堆栈,为什么需要堆栈 堆栈——按照先进后出原则组织的一段内存区域, 特点: 下推式的(规定堆栈设置在堆栈段内)改变SP的内容, 随着推入堆栈内容增加,SP的值减少。 先进后出工作原则(Last In First Out 简称LIFO) 堆栈在内存中的情况:
86
可以用一条立即数传送指令给SP赋值,确定SP在SS段中的初始位置。
堆栈在内存中的情况: 可以用一条立即数传送指令给SP赋值,确定SP在SS段中的初始位置。 例: 设: (SS)=9000H , 堆栈段为64KB MOV SP,0E200H ;(SP)=0E200H 则: 整个堆栈段的物理地址范围为: 90000H~9FFFFH 栈顶的物理地址为:9E200H 堆栈在内存中的情况如右图所示: 堆栈在内存中的情况
87
堆栈用途: 存放CPU寄存器或存储器中暂时不使用的数据, 使用数据时将其弹出; 调用子程序, 响应中断时都要用到堆栈。
调用子程序, 响应中断时都要用到堆栈。 调用子程序(或过程)或发生中断时要保护断点的地址, 子程序或中断返回时恢复断点。
88
主程序 子程序: 子程序:在一个实际程序中,有些操作要执行多次,把要 重 复执行(subroutine)操作编为子程序。
主程序 子程序: 子程序:在一个实际程序中,有些操作要执行多次,把要 重 复执行(subroutine)操作编为子程序。 也常把一些常用的操作标准化、通用化的子程序。 主程序(Main program)——往往要调用子程序 或处理 中断, 暂停主程序,执行子程序或中断服务程序。
89
调用子程序时需保留内容: ① 调用子程序:将下条指令地址即IP值保留下来 (8088中码段寄存器CS和指令指针IP), 才能保证子程序执行完后准确返回主程序继续执行。 ②执行子程序时,通常用到内部寄存器,执行结果会影响 标志位,必须在调用子程序之前将现状保护起来。 ③ 子程序嵌套或子程序递归(自调自) 保留许多信息,而且保证正确返回(且后进先出)。 后保留先取出原则(即LIFO-LAST In First out)。
90
注意:SP——堆栈指针,始终指向栈顶。 SP初值用MOV SP,i m来设定。 下边详细说明一下堆栈用途:
91
存放CPU寄存器或存储器中暂时不使用的数据, 使用数据时将其弹出:
PUSH AX ; 将(AX)入栈 (AX) (AX)
92
使用数据时将其弹出: POP BX
93
调用子程序(或过程)或发生中断时要保护断点的地址,
子程序或中断返回时恢复断点。 子程序嵌套 断点地址压入和弹出情况
94
(2) 堆栈操作指令 (堆栈操作指令有两条):
入栈指令 格式:PUSH src ; (SP) (SP)-2 ((SP)+1,(SP)) (src) 把一个字从源操作数由SP指向堆栈顶部。 操作如:PUSH AX 出栈指令 格式:POP dest ; (dest) ((SP)+1,(SP)) (SP) (SP)+2 把现行SP所指向堆栈顶部的一个字 指定的目的操作数,同时进行修改堆栈指针的操作。 操作如: POP BX
95
应用时注意: 堆栈操作都按字操作。 PUSH , POP 指令的操作数可能有三种: 寄存器(通用寄存器,地址指针,变址寄存器), 段寄存器(CS除外,PUSH CS 合法,POP CS 非法), 存储器。 执行PUSH 指令, (SP)-2 (SP), 低字节放在低地址,高字节放在高地址。 随着推入堆栈内容增加,堆栈就扩展,SP的值减少, 但SP总是指向栈顶, 堆栈工作原则后进先出。 PUSH ,POP指令应该成对使用,保持堆栈原有状态。 堆栈最大容量即为SP的初值与SS之间的差。
96
堆栈应用举例: 例:用BP的基址指令 代替POP指令 例 : 压入堆栈的内容 … 与弹出内容顺序相反 MOV BP,SP PUSH AX …
PUSH BX PUSH CX MOV CX,[BP-6] MOV BX,[BP-4] MOV AX,[BP-2] ADD SP, 6 例 : 压入堆栈的内容 与弹出内容顺序相反 … PUSH AX PUSH BX PUSH CX POP CX POP BX POP AX
97
3、交换指令(Exchange) 注意: 格式:XCHG dest , src ;(dest) (src) 执行操作:
把一个字节或一个字的源操作数与目的操作数相交换。 可以 实现: 寄存器之间 寄存器和存储器之间 注意: 存储器之间不能交换,两个操作数中必须有一个在寄存器中; 段寄存器不能作为一个操作数; 允许字或字节操作,不影响标志位。
98
应用举例: XCHG AX,SI XCHG COUNT[DI], AX XCHG DS, AX (错) XCHG BL,DL
XCHG [BX],[DI] (错) XCHG DS, AX (错)
99
XLAT(Trans late)换码指令:该指令不影响标志位。
格式: XLAT str_table ;(AL)←((BX )+(AL)) 或 XLAT str_table——表格符号地址(首地址), 只是为了提高可读性而设置,汇编时仍用BX。
100
XLAT指令使用方法: 先建立一个字节表格; 表格首偏移地址存入BX;
需要转换代码的序号(相对与表格首地址位移量)存入AL; (表中第一个元素的序号为0) 执行XLAT指令后,表中指定序号的元素存于AL中。 (AL)为转换的代码。
101
XLAT指令应用: 若把字符的扫描码转换成ASCII码; 或数字0~9转换成7段数码所需要的相应代码(字形码)等就要用XLAT指令。
首地址为:Hex_table ,欲查出表中第10个元素(‘A’)
102
执行指令序列: MOV BX,OFFSET Hex_table MOV AL,0AH XLAT Hex_table 假设:
(DS)=F000H, Hex_table=0040H (AL)=0AH 执行XLAT以后: (AL)=41H=(F004AH), 即“A”的ASCII码。 30H 31H 32H ... 39H 41H 42H 46H Hex_table Hex_table+1 Hex_table+2 Hex_table+0AH Hex_table+0BH Hex_table+0FH 'F' 'B' 'A' '9' '1' '2' '0' 16进制数的ASCII码表
103
(二)输入输出指令(Input and Output)
输入输出指令共两条: 1、IN (Input byte or word) 2 、OUT (Output byte or word) 输入指令用于CPU从外设端口接受数据, 输出指令用于CPU向外设端口发送数据。 无论接受还是发送数据,必须通过累加器AX(字)或AL(字节), 又称累加器专用传送指令 。 输入、输出指令不影响标志位。
104
每个外设要占几个端口:数据口,状态口和控制口。
105
信息交换要通过端口, 在IBMPC机里,可以配接许多外部设备, 每个外设与CPU之间交换数据,状态信息和控制命令,
每一种信息交换都要通过一个端口来进行。 端口数:外部设备最多有65536个I/O端口。 A0~A15译码形成。 端口号:端口号(即外设端口地址)为0000H~FFFFH。 PC机仅使用A0~A9译码形成I/O口地址,即1024H个口地址 端口号:0000H~03FFH 其中: A9=1,表示扩充槽上的口地址。
106
长格式: 端口号中前256个端口(0~FFH),可以直接写在指令中,这就是长格式。 端口号代替指令中的PORT, 机器指令用二字节表示,第二字节就是端口号。 短格式: 当端口号≥256时,只能使用短格式, 必须先把端口号放到DX寄存器中。 不需要用任何段寄存器来修改它的值。
107
1、IN (Input byte or word) 输入指令
格式:IN acc, port ;(acc) (port) 具体形式有四种: IN AL, data ; 端口地址8位,输入一个字节 IN AX, data ;端口地址8位,输入一个字 IN AL, DX ;端口地址16位,输入一个字节 IN AX, DX ;端口地址16位,输入一个字 必须通过累加器AX(字)或AL(节)输入数据。
108
2 、OUT(Output byte or word) 输出指令
格式: OUT port, acc ;(port) (acc) 具体形式有四种: OUT data8 , AL ; 端口地址8位,输出一个字节 OUT data8, AX ;端口地址8位,输出一个字 OUT DX , AL ;端口地址16位,输出一个字节 OUT DX , AX ;端口地址16位,输出一个字 必须通过累加器AX(字)或AL(节)输出数据。
109
例1:实现(29H)(28H)→(DATA_WORD)
IN AX,28H MOV DATA_WORD,AX 例2:从端口3FCH 送一个字到AX寄存器 MOV DX,3FCH IN AX,DX ; (AL)←(3FCH), (AH)←(3FDH) 例3:实现将(AL) →(05H) OUT 5,AL;(05H)←(AL)
110
(三)目的地址传送指令(Address-object transfer)
8086 /8088 提供三条: 地址指针写入指定寄存器或寄存器对指令。 1、LEA(Load Effective Address) 2、LDS (Load pointer using DS) 3、LES (Load pointer using ES)
111
1、LEA(Load Effective Address)
格式: LEA reg16 , mem16 ;EA(reg16) 功能:加载有效地址,用于写近地址指针。 把指令中指定的存储器操作数有效地址装入指定的寄存器 。 例:设(BX)=0400H,(SI)=003CH LEA BX,[BX+SI+0F62H] 执行指令后: EA=(BX)+(SI)+0F62H=0400H+003CH+0F62H=139EH (BX)=139EH
112
注意:设 (DS)=3000H BUFFER=1000H (31000H)=0040H (1) LEA 指令与MOV 的区别 LEA BX , BUFFER ;(BX)=1000H MOV BX , BUFFER ; (BX)=0040H LEA 指令与MOV等价 LEA BX , BUFFER ; (BX)=1000H MOV BX , OFFSET BUFFER ; (BX)=1000H
113
(2)LEA 指令中的目标寄存器必须是16位的通用寄存器,
源操作数必须是一个存储器。 (3)请思考下列指令的正、误 LEA DX ,BETA[BX][SI] LEA DX , AX
114
2、LDS (Load pointer using DS)
格式:LDS reg16, mem ;(reg16)←(EA) (DS)←((EA)+2)) 功能:将指令指定32位地址指针送指令指定寄存器和DS。 将指令指定mem32单元的前两个单元内容(16位偏移量)装入指定通用寄存器,把后两个单元内容(段地址) 装入到DS段寄存器。 用于写远地址指针。
115
例: 假设: (DS)=C 000H 指令: LDS SI, [0010H] 执行指令后: (SI)=0180H (DS)=2000H
116
3、LES (Load pointer using ES)
格式:LES reg16, mem ;(reg16)←(EA) (ES)←((EA)+2)) 功能:把源操作数指定的4个相继字节送指令指定的寄存器 及ES寄存器中。 此指令常常指定DI寄存器。 将指令指定mem32单元的前两个单元内容(16位偏移量)装入指定通用寄存器,把后两个单元内容(段地址) 装入到ES段寄存器。 用于写远地址指针。
117
例: 假设: (DS)=B 000H (BX)=080AH 指令: LES DI, [BX] 执行指令后: (DI)=05A2H (ES)=4000H
118
综合举例: 设: (DS)=5000H TABLE=1000H 分析下列指令执行结果: MOV BX,TABLE ;(BX)=0040H
MOV BX,OFFSET TABLE ;(BX)=1000H LEA BX,TABLE ;(BX)=1000H LES BX,TABLE ;(BX)=0040H,(ES)=3000H LDS BX,TABLE ;(BX)=0040H,(DS)=3000H
119
(四)标志传送指令(Flag register transfer) 采用了隐含寄存器(AH、Flags)操作数方式。
8088有四条标志传送操作指令: 1. LAHF(Load AH into flags) 2. SAHF(Store AH into flags) 3. PUSH F(Push flags onto stack) 4. POP F(Pop flags off stack)
120
1.LAHF(Load AH flags flags)
格式:LAHF ;(AH)←(PSW的低字节) 功能:标志寄存器低八位 (AH)。 LAHF指令操作图示意
121
2. SAHF(Store AH into flags)
格式:SAHF ;(PSW的低字节)←(AH) 功能:(AH)送标志寄存器低八位。 3. PUSH F(Push flags onto stack) 格式:PUSH F ;(SP)←(SP)-2 ((SP)+1,(SP))←(PSW) 功能 : 标志进栈。 4. POP F(Pop flags off stack) 格式:POP F;(PSW)←((SP)+1,(SP)) (SP)←(SP)+2 功能 :标志出栈。
122
SAHF、POPF由装入的值确定标志位的值, 即影响标志位。 (2)PUSH F、POPF用于保护调用过程前(PSW),过程返回后恢复。
注意: (1) 标志位的影响 LAHF、PUSHF不影响标志位, SAHF、POPF由装入的值确定标志位的值, 即影响标志位。 (2)PUSH F、POPF用于保护调用过程前(PSW),过程返回后恢复。 例: … PUSH AX PUSH CX PUSH F CALL TRANS POPF POP CX POP AX …
123
二. 算术运算指令(Arithmetic)
内容: 8086/8088提供加、减、乘、除、转换五种基本算术操作; 利用十进制调整指令和ASCII调整指令对BCD码表示的 十进制数进行算术运算; 对带符号数与无符号数进行乘、除运算。 (一)加法指令(Arithmetic) (二)减法指令(Subtraction) (三)乘法指令(Multiplication) (四)除法指令(Division) (五)转换指令
124
特点: 大部分都影响标志位,不同指令影响不同: (1) 加、减法指令影响 SF,ZF,AF,PF,CF,OF; (2) 加1和减1指令不影响CF; (3) 乘法指令影响CF,OF; (4) 除法指令使大部分标志位的状态不确定; (5) 对BCD码调整指令对标志位的影响不同; (6) 转换指令对标志位无影响 都可以用于字节、字的运算; 双操作数指令除源为立即数外,其余必须有一个操作数 为寄存器;单操作数指令不能为立即数。
125
(一)加法指令(Arithmetic) 8088具有5种加法操作指令: 1、 ADD(Addition)加法指令
2、 ADC(Add with carry)带进位加法指令 3、 INC(Increment by 1)加 1指令 4、AAA(ASCII adjust for addition)加法ASCII调整指令 5、DAA(Decimal adjust for addition)加法十进制调整指令
126
1、 ADD(Addition)加法指令 指令格式:ADD dest , src ;(dest) (dest)+(src)
例: ADD CL,10 ;寄存器+立即数 ADD DX,SI ;寄存器+寄存器 ADD AX, MEM ;寄存器+存储器 ADD DATA[BX], AL ;存储器+寄存器 ADD BYTE PTRALPHA[DI],30H;存储器+立即数
127
特点: 可以进行8位、16位的无符号数和带符号数的加法运算; 源操作数和目标操作数不能同时为存储器, 不能为段寄存器;
指令影响标志位的情况: OF=1, 8位带符号数相加,和超出范围(-128~+127), 16位带符号数相加,和超出范围(-32768~+32767); CF=1, 8位无符号数相加,和超过255, 16位无符号数相加,和超过65535。 其他条件标志(SF,AF,PF,ZF)根据定义设定。
128
例 MOV AL,7EH ;(AL)=7EH MOV BL, 5BH ;(BL)=5BH ADD AL,BL ;(AL)=7EH+5BH=D9H 影响标志位的情况: SF=1 , 结果最高位=1 ZF=0 ,结果不等于0 AF=1 ,D3 位向D4 有进位 PF=0 ,”1”的个数为奇数 CF=0 ,无进位 OF=1 ,和超过+127 (两个正数相加,结果为负;反之亦是)
129
2、 ADC(Add with carry)带进位加法指令
格式:ADC dest,src ;(dest)←(dest)+(src)+CF CF: 进位标志CF的现行值(上条指令CF值) 特点: 与ADD同。 用途:主要用于多字节运算中。 类型举例: ADC CX, ;寄存器+立即数+CF ADC AL, BL ;寄存器+寄存器+CF ADC DX, COUNT[SI] ;寄存器+存储器+CF ADC BLOCK[DI], BX ;存储器+寄存器+CF ADC BYTE PTR MEM, 6 ;存储器+立即数+CF
130
计算两个多字节数相加 3B74AC60F8H+20D59E36C1H=? 两个多字节数存放在: DATA1,DATA2的开始单元。
用途举例: 计算两个多字节数相加 3B74AC60F8H+20D59E36C1H=? 两个多字节数存放在: DATA1,DATA2的开始单元。 流程图 多字节数内存存放
131
程序: MOV CX, 5 MOV SI, 0 ; 清SI CLC ;清CF LOOPER: MOV AL, DATA2[SI]
ADC DATA1[SI],AL INC SI ;(SI)+1 (SI) DEC CX ;(CX)-1 (CX) JNZ LOOPER ;(CX)0转 HLT ;停机
132
问题思考: (1) 什么叫溢出?什么叫进位? (2) 有进位就有溢出,没有进位就没有溢出? (1) 溢出------是指带符号数的补码溢出。
(1) 什么叫溢出?什么叫进位? (2) 有进位就有溢出,没有进位就没有溢出? (1) 溢出------是指带符号数的补码溢出。 字长为 n 位带符号数,补码运算能表示范围为:-2 n-1 ~+2 n+1 –1 如果运算结果超出该范围,叫补码溢出,简称溢出。在溢出时, 造成运算错误。 进位------是指运算结果的最高位向更高位的进位。 有进位,CF=1;无进位, CF=0
133
(2)有进位就有溢出,没有进位就没有溢出? 结论:
有进位不一定有溢出,没有进位不一定没有溢出。 数的表示范围: 8位二进制数可以表示十进制数的范围: 8位带符号十进制数的范围:-128~+127 8位无符号十进制数的范围:0~255 16位二进制数可以表示十进制数的范围: 16位带符号十进制数的范围:-32768~+32767 16位无符号十进制数的范围:0~65535
134
以8位二进制数为例分析一下数的溢出与进位情况:
下面分4种情况加以讨论: (1) 带符号数和无符号数都不溢出 (2) 无符号数溢出 (3) 带符号数溢出 (4) 带符号数和无符号数都溢出
135
(1) 带符号数和无符号数都不溢出 。
136
(2) 无符号数溢出 二进制数 看作无符号数 看作带符号数 1 + 7 251 258 + 7 - 5 + 2 相 加 标志
(2) 无符号数溢出 二进制数 看作无符号数 看作带符号数 1 + 7 251 258 + 7 - 5 + 2 相 加 标志 CF=1,OF=0 CF=1 OF=0 溢出 无符号数溢出 结果应为2,错 不溢出 异号数相加 不可能有溢出
137
(3) 带符号数溢出
138
(4) 带符号数和无符号数都溢出
139
结论: (1)带符号数相加溢出 根据OF= 1 ?,判断带符号数产生溢出? OF=1,同符号数相加,结果符号与其相反,产生溢出;
异号数相加,不可能溢出。 (2)无符号数相加溢出 根据CF= 1 ?,判断无符号数产生溢出? CF=1,无符号数相加产生溢出,但结果并没有错, 只是结果放不下。
140
3、INC (Increment by 1 )加 1 指令
格式: INC dest ;(B/W), (dest)←(dest)+1 dest : 寄存器、存储器。不能是段寄存器。 功能:对指定的目标操作数+1 操作数单元。 用途:用于在循环程序中修改地址指针和循环次数。 标志位影响情况:影响SF,ZF,AF,PF,OF。 不影响CF。
141
操作数类型:可以是寄存器,存储器。不能是段寄存器。
例: INC DL ; 8位寄存器+1 INC SI ;16位寄存器+1 INC BYTE PTR [BX][SI] ;存储器+1(字节操作) INC WORD PTR [DI] ;存储器+1(字操作) INC DS ; 错
142
(二)减法指令(Subtraction)
8088有7条减法指令 : 1、SUB(Subtraction)减法指令 2、SBB(Subtraction with borrow)带进位减法指令 3、DEC(Decrement by 1 ) 减 1 指令 4、NEG(Negate) 求补指令 5、CMP(Compare) 比较指令 6、AAS(ASCII adjust for subtraction)减法ASCII调整指令 7、DAS(Decimal adjust for subtraction)减法十进制调整指令
143
1、SUB(Subtraction)减法指令
格式::SUB dest,src;(dest)←(dest)-(src) Src:立即数,寄存器,存储器。 Dest:寄存器,存储器。 例: SUB AL,37H ;寄存器-立即数 SUB BX,DX ;寄存器-寄存器 SUB CX, VAR1 ;寄存器-存储器 SUB ARRAY[SI], AX ;存储器-寄存器 SUB WORD PTRALPHA[BX][DI],512H;存储器减立即数 这种指令影响标志位: A、C、O、P、S、Z标志。 CF=1,无符号数小减大;SF=1,带符号数小减大, OF=1溢出.
144
2、SBB(Subtraction with borrow)带进位减法指令
格式::SBB dest,src;(dest)←(dest)-(src)-CF CF: 进位标志CF的现行值(上条指令CF值) Src:立即数,寄存器,存储器。 dest:寄存器,存储器。 指令影响标志位、B/W数运算情况同SBB 用途:用于多字节数相加 例: SBB BX,100H ;寄存器-立即数 -CF SBB CX,DX ;寄存器-寄存器-CF SBB AL, DATA1[SI] ;寄存器-存储器-CF SBB DISP[BP], BL ;存储器-寄存器-CF SBB BYTE PTRALPHA[SI+6],96H;存储器-立即数-CF
145
问题思考: 减法有借位就有溢出,没有借位就没有溢出? 结论:CF=1 表示不带符号数有溢出。 OF=1 表示带符号数有溢出。 CF值反映无符号数运算中的借位情况: 无符号数相减: CF=1 ,减数>被减数,有借位 CF=0 ,被减数>减数,无借位 补码加法: CF=1, 二进制运算中最高有效位向高位无进位 CF=0, 二进制运算中最高有效位向高位有进位 减法0F位设置: OF=1, 二个数符号相反,结果符号与减数相同; 否则,OF=0。
146
3、DEC (Decrement by 1 ) 减 1 指令
格式: DEC dest ;(B/W) (dest)←(dest)-1 dest : 寄存器 、存储器。不能是段寄存器。 功能:对指定的目标操作数-1 操作数单元。 用途:用于在循环程序中修改地址指针和循环次数。 标志位影响情况:影响SF,ZF,AF,PF,OF。 不影响CF。
147
DEC 用途举例: … MOV AX , 0FFFFH CYC: DEC AX JNZ CYC HLT 用于延时时间。
148
4、NEG (Negate) 求补指令 格式: NEG dest ;B/W, (dest) ← 0 - (dest)
操作: 把操作数按位求反后末位+1。 (dest) ← 0FFFFH -(dest)+1 影响标志:A、C、O、P、S、Z。 CF: 操作数为0时求补,CF=0 ; 一般使CF=1. OF: 对-128 或-32768求补,OF=1; 否则OF=0.
149
应用举例:求绝对值 在内存中, 从AREA1开始存放100个带符号数。 求各数的绝对值存于AREA2的开始单元。 流程图
150
程序: LEA SI, AREA1 LEA DI, AREA2 MOV CX, 100 CHECK: MOV AL, [SI]
OR AL, AL ;(AL)内容不变,置标志 JNS NEXT ;SF=0转NEXT NEG AL ;负数求补 NEXT: MOV [DI], AL ;送目标 INC SI INC DI DEC CX JNZ CHECK HLT
151
5、CMP(Compare) 比较指令 格式:CMP dest,src ; B/W (dest)-(src) 结果不送,置标志。 影响标志:A、C、O、P、S、Z。 src: 立即数,寄存器,存储器。 dest:寄存器,存储器。 例: CMP AL,0AH ;寄存器与立即数比较 CMP CX, DI ;寄存器与寄存器比较 CMP AX, AREA1 ;寄存器与存储器比较 CMP [BX+5], SI ;存储器与寄存器比较 CMP WORD PTRALPHAGAMMA,100H;存储器与立即数比较
152
用途: 用比较指令来比较两个数之间的关系: 两者是否相等,两个数中哪个大。 (1) 根据Z标志,判断两者是否相等;
(2) 根据CF标志, 判断两个无符号数的大小; (3) 用S、O标志,判断二个带符号数的大小。
153
(1) 根据Z标志,可判断两者是否相等 例: CMP AX, BX ZF=1, (AX) = (BX),两者相等 ZF=0, (AX) = (BX),两者不相等 (2) 根据CF标志, 判断两个无符号数的大小 例: 比较AX,BX寄存器, 将大数 (AX) … CMP AX,BX JNC NEXT ; CF=0转NEXT XCHG AX,BX NEXT:…… 结论:CF=0 ,(AX) > (BX); CF=1, (AX) < (BX)
154
(3) 用SF、OF标志,判断二个带符号数的大小
设:被比较二个带符号数分别为 : A、B 分四种情况讨论: A>0, B>0 A<0, B<0 A>0, B<0 A<0, B>0
155
四种情况讨论(操作数以8位为例): 4 A B 结论 7 5 A>0, B>0 SF=0,OF=0 则:A>B
CMP A, B 结论 7 5 A>0, B>0 SF=0,OF=0 则:A>B 情 况 SF=1,OF=0 则:A<B -5 2 -7 -2 -5 -7 1 -(-7) +2 A<0,B<0 SF=1,OF=0 则:A<B SF=0,OF=0 则:A>B -(-5) -2 3 +127 -63 A>0,B<0 OF=1,SF= 则:A>B -(-63) +190 4 A<0,B>0 SF=0,OF= 则:A<B -(+127) -190
156
(2)O=S=0或S=O=1时: 记作 SO=0 , 则:A>B; O、S异号时: 记作 SO=1 , 则: A<B。
分析以上四种情况得出如下结论: (1) OF=0 时: SF=0, 则:A>B SF=1, 则:A<B OF=1时: SF=1 , 则:A>B SF=0,则:A<B (2)O=S=0或S=O=1时: 记作 SO=0 , 则:A>B; O、S异号时: 记作 SO=1 , 则: A<B。 (3) SO=0 同时ZF=0时, A>B, 用JG/JNLE转移指令; SO=1时, A<B, 用JL/JNGE转移指令。
157
CMP指令应用举例:带符号数找最大值 若自BLOCK开始的内存缓冲区中,有100个带符号数。找出最大值。并存放到MAX单元中。 思路:
再取第三个数, … 经过99次比较,在(AX)中得到最大数。
158
编程: … MOV BX,OFFSET BLOCK … MOV AX,[BX] INC BX MOV CX,99
编程: … MOV BX,OFFSET BLOCK MOV AX,[BX] INC BX MOV CX,99 AGAIN:CMP AX,[BX] JG NEXT ;(AX) >(16d(ds)+(BX))转NEXT NEXT: INC BX INC BX DEC CX JNE AGAIN MOV MAX,AX ;MAX单元存放最大值 …
159
三、逻辑运算和移位指令 (一)逻辑运算指令 1、AND(Logical and ) 逻辑“与”指令
2、 TEST(Test or non-destructive logical and ) 测试指令 3、OR(Lgical inclusive or ) 逻辑“或”指令 4、XOR(Logical exclusive or) 逻辑“异或”指令 5、NOT(Logical not ) 逻辑“非”指令 特点: 8088可以对8位,或16位操作数执行逻辑操作。 逻辑运算是按位操作,操作数应该是位串而不是数。 影响条件码: (NOT指令除外,其他指令同) CF=0F=0, A未定义 , SF ZF PF ↕ ↕ ↕
160
1、AND(Logical and )逻辑“与”指令 格式:AND dest, src ;B/W,(dest)(dest ∧ (src)
执行操作:进行“与”运算, 两位中有一位为0(或二位都为0),则结 果 为0,否则为1。 操作类型举例: AND AL, 0FH ;寄存器 ∧ 立即数 AND CX, DI ; 寄存器 ∧ 寄存器 AND SI, MEM_NAME ; 寄存器 ∧ 存储器 AND ALPHA [DI], AX ; 存储器 ∧ 寄存器 AND word ptr [BX][SI], 0FFFEH ; 存储器 ∧ 立即数
161
(1) 清CF , 自己“与”自己. 操作数不变 ,CF=0 例:AND AL ; 结果:操作数不变 ,CF=0。
注意: “与”指令中操作数不能同时为存储器; 影响条件码: CF=0F=0, A未定义 , SF ZF PF ↕ ↕ ↕ “与”指令的用途: (1) 清CF , 自己“与”自己. 操作数不变 ,CF=0 例:AND AL ; 结果:操作数不变 ,CF=0。 (2) 使操作数中若干位保持不变,若干位与“1”相与; 而若干位置为“0 “的场合,若干位与“0” 相与。 例: 若(AL)=43H AND AL, 0FH ; (AL)=03H, (AL)0~3不变; ;(AL)4~7=00H,屏蔽高4位。
162
“与”指令应用举例: 例1:将英文小写字母ASCII转换成大写。 小写英文字母ASCII为:‘a’~’z’ 61H~7AH 大写英文字母ASCII为:‘A’~’Z’ 41H~5AH 程序: MOV AL, ’z’ AND AL,0DFH ;(AL)=5AH 例2:判断键盘按下的字符是不是‘Y’? MOV AH, 7 INT H ;键入无回显,(AL)=输入键的字符码 AND AL, 0DFH CMP AL, ‘Y’ JE YES … YES: … 61H 41H FDH
163
2、 TEST(Test or non_destructive logical and )测试指令
格式: TEST dest , src;(dest)∧(src) src: 立即数、寄存器、存储器。 dest: 寄存器、存储器。 执行操作: 二个操作数相与的结果不存,置条件码。 操作类型举例: TEST BH, ; 寄存器 ∧ 立即数 TEST SI , BP ;寄存器 ∧ 寄存器 TEST DI ,TABLE[BX] ; 寄存器 ∧ 存储器 TEST [SI],CH ;存储器 ∧ 寄存器 TEST word ptr [BX][DI], 6ACEH ;存储器 ∧ 立即数
164
用途: 常常用来检测一些条件是否满足,但又不希望改变原有的操作数的情况下,常在此指令后边加一条 条件转移指令。 例:判断A单元中数据的奇偶性 设: (A )= 0AEH 程序:MOV AL,A ;(AL)=0AEH TEST AL,01H JZ EVEN ; 结果=0为偶数转EVEN … 奇数处理 … EVEN:偶数处理 检测(AL)的最低位是否为0,若为0转EVEN
165
3、OR(Lgical inclusive or )逻辑“或”指令
格式:OR dset, src;(dset)←(dset) (src) dest: 寄存器、存储器。 src: 立即数、寄存器、存储器。 执行操作: 进行按位“或”运算 两位操作数中任一位为1(或都为1), 则该位(结果)=1, 否则为0。 操作类型举例: OR BL,0F6H ; 寄存器 立即数 OR AH, BL ;寄存器 寄存器 OR CL ,BETA[BX][DI] ; 寄存器 存储器 OR GAMMA[SI] ,DX ;存储器 寄存器 OR BYTE PTR MEM_BYTE , 80H ;存储器 立即数 ∧ ∧ ∧ ∧ ∧ ∧
166
(1)清CF , 自己与自己“或”,操作数不变,CF=0 例: OR AL ;(AL)不变,CF=0
注意: “或”指令中操作数不能同时为存储器; 影响条件码: CF=0F=0, A未定义 , SF ZF PF ↕ ↕ ↕ 用途: (1)清CF , 自己与自己“或”,操作数不变,CF=0 例: OR AL ;(AL)不变,CF=0 (2)使某个操作数若干位保持不变,若干位与“0”或 ; 而若干位置1。若干位与“1”或 。 (3) 将两个操作数信息组合。 若(AL)=03H 用OR指令组合使(AL)=33H=’3’ 。 OR AL,30H ;(AL)=33H
167
4、XOR(Logical exclusive or)逻辑“异或”指令
格式:XOR dset , src ;B/W(dset) (dset) (src) dest: 寄存器、存储器。 src: 立即数、寄存器、存储器。 执行的操作:对指令的两个操作数进行按位“异或”运算。 二位不相同时为1, 相同时为0。 操作类型举例: XOR DI, 23F6HH ; 寄存器 立即数 XOR SI , DX ;寄存器 寄存器 XOR CL , BUFFER ; 寄存器 存储器 XOR MEM[BX],AX ;存储器 寄存器 XOR byte ptrTABLE[BP][SI], 3DH ; 存储器 立即数
168
用途:对某些特定位求反,某些特定位与“1” 其余位保持不变,保持不变与“0” 。 应用举例:
注意: “或”指令中操作数不能同时为存储器; 影响条件码: CF=0F=0, A未定义 , SF ZF PF ↕ ↕ ↕ 用途:对某些特定位求反,某些特定位与“1” 其余位保持不变,保持不变与“0” 。 应用举例: 例1: 将(AL)中的第1、3、5、7位求反 0、2、4、6位保持不变。 MOV AL, 0FH XOR AL,0AAH
169
例2: 比较三条(AX)清“0”指令: XOR AX , AX ; 清AX , 清CF,2个字节,3个T。 SUB AX, AX ;清AX , 清CF,2个字节,3个T。 MOV AX , 0 ;清AX ,不影响标志位, 3个字节,4个T。 XOR清“0”指令在多字节累加程序中十分有用。 例3: 将存放在TABLE开始的100个字节的16进制数进行累加, 和存于SUM+1、SUM单元。
170
程序: 100个字节的16进制数 进行累加。 流程图 LEA BX , TABLE MOV CL,100 XOR AX ,AX
LOOPER:ADD AL,[BX] JNC GOON INC AH GOON: INC BX DEC CL JNZ LOOPER MOV SUM , AX HLT 流程图
171
5、NOT(Logical not )逻辑“非”指令 格式: NOT dest ;B/W 指令操作数只有一个,指令对操作数按位求反。
执行操作: 字节求反:(dest)0FFH-(dest) 字求反: (dest 0FFFFH-(dest) 源操作数:寄存器、存储器。不能是立即数。 影响标志位:对标志位无影响。 操作类型举例: NOT AH ; 8位寄存器求反 NOT CX ;16位寄存器求反 NOT BYTE PTR [BP] ;8位存储器求反 NOT WORD PTR COUNT ;16位存储器求反
172
综合举例: 1.使某些位置“0”。 IN AL,61H;(AL)=×××× ×× × ×B ↑设备控制寄存器 ↑想使此位为0 执行指令: AND AL,0FDH 即可。 使某些位置“1”。 IN AL,61H;(AL)=×××× ×××× 执行指令: OR AL, ↑想使此位为“1” 3. 使某些位求反: IN AL,61H ;(AL)= × × × × × × 0 × XOR AL,02H ⊕ × × × × × × 1 × 4. 测试某些位(测奇偶性): 测试 “奇”“偶”性。 见TEST指令的用途例子。
173
逻辑指令应用小结: (1)AND指令用来对指令的指定位清“0”。 (2)OR指令常用来对某些位置1。
(3)XOR指令用在程序开头,使某个寄存器清“0”。 (4)NOT指令对某个数据取反,+1成补码。 (5)TEST指令用来检测指定位为1,还是0。
174
(二)移位指令 (8088有8条移位指令) : 1、 算逻移位指令( 4条 ): SHL , SHR, SAL , SAR 。 (1)、 SHL/SAL(Shift logical left/shift arithmetic left) 逻辑左移/算术左移指令 (2)、SHR (Shift logical right ) 逻辑右移指令 (3)、SAR (Shift arithmetic right )算术右移指令 2、循环移位( 4条): ROL, ROR , RCL, RCR。 (1)、ROL (Rotate left ) 不含CF循环左移指令 (2)、ROR (Rotate right ) 不含CF循环右移指令 (3)、RCL (Rotate left through carry )含CF循环左移指令 (4)、RCR (Rotate right through carry )含CF循环右移指令
175
共同点: 所有移位指令都可以作B/W操作。 指令中的 dest : 寄存器、存储器寻址方式。 cnt : 表示移位次数
cnt=1,1可写在指令中,不能是1以外的常数。 cnt>1,用CL存放移位次数 ,不能是其他寄存器。 如: SAL AX,1 MOV CL,4 SAL AX,CL 利用移位指令编制 *, / 程序, 执行时间比直接用 * ,/ 指令快, 速度可提高5-6倍。
176
条件码设置: 算逻移位移位指令: 执行多次移位指令后对CF、OF的影响: CF=从目标操作数移出的最后一位;OF不定。
SF、ZF、PF,AF无定义。 ↕ ↕ ↕ 循环移位指令:SF、ZF、PF、AF不影响。 OF、CF影响情况在指令中讲: ROL、 RCL影响标志OF、CF情况相同 ; ROR 、 RCR影响标志OF、CF情况相同 。
177
1、 算逻移位指令( 4条 ) : SHL , SHR, SAL , SAR
(1)、 SHL/SAL(Shift logical left/shift arithmetic left) 逻辑左移/算术左移指令 格式: SHL dest ,cnt ;逻辑左移指令, B/W SAL dest ,cnt ;算术左移指令, B/W dest : 寄存器、存储器寻址方式。 cnt : 表示移位次数 cnt=1,1可写在指令中。 cnt>1,用CL存放移位次数 。
178
SHL/SAL指令操作示意图如下图所示:
执行操作:相当于无符号数的×2功能。 SHL/SAL指令操作示意图如下图所示: 指令格式举例: SHL AH,1 SAL SI, CL SAL WORD PTR [BX+5] ,1 SHL BYTE PTR , CL dest CF
179
(2)、SHR (Shift logical right )逻辑右移指令 格式: SHR dest ,cnt ;逻辑右移指令, B/W
执行操作:相当于无符号数的÷2功能。 SHR指令操作示意图如下图所示: dest CF dest : 寄存器、存储器寻址方式。 指令格式举例: SHR BL , 1 SHR AX , CL SHR BYTE PTR [DI+BP],1 SHR WORD PTR BLOCK ,CL
180
(3)、SAR (Shift arithmetic right )算术右移指令 格式: SAR dest ,cnt ;算术右移指令, B/W
执行操作:相当于带符号数的÷2功能,对负数向下舍入 IDIV指令对负数向上舍入。(下页解释) SAR指令操作示意图如下图所示 dset dest : 寄存器、存储器寻址方式。 指令格式举例: SAR AL , 1 SHR DL , CL SHR WORD PTR TABLE[SI],1 SHR BYTE PTR STATUS ,CL
181
用SAR指令与用IDIV指令做除法的区别:
MOV AX , 81H ; (AX) = -127 SAR AX , 1 ; (AX)= - 64 用IDIV指令做除法(IDIV指令对负数向上舍入) : MOV AX , 81H ;(AX)= -127 MOV CL , 2 IDIV CL ;(AL)= -63 ,(AH)= -1
182
应用举例: (BX)=84F0H SHR BX,1 ; (BX)=4278 CF=0,OF=1,SF=0,ZF=0
MOV CL,02H 或SAR BX,1 SAR BX,CL SAR BX,1 ; CF=0,OF无意义, SF=1,ZF=0
183
(3)每四位一组存入堆栈(字操作) (BX)=84F0H (SS)=3000H (CH)=4 (SP)=1000H MOV CH,4
MOV CL,4 NE : ROL BX,CL MOV AX,BX AND AX,000FH PUSH AX DEC CH JNZ,NE … (CH)=4 ROL BX,CL MOV AX,BX AND AX,000FH PUSH AX (BX)=4F08H (AX)=4F08H (AX)=0008H (30FFEH)=0008H (CH)=3 (BX)=F084H (AX)=F084H (AX)=0004H (30FFCH)=0004H (CH)=2 (BX)=084FH (AX)=084FH (AX)=000FH (30FF8H)=000FH (CH)=1 (BX)=84F0H (AX)=84F0H (AX)=0000H (30FF4H)=0000H
184
共同点: 影响标志OF、CF 2、循环移位( 4条): ROL, ROR , RCL, RCR。
ROL、ROR 不含CF循环移位指令,操作数移动8次后还原。 RCL、 RCR 含CF循环移位指令,操作数移动9次后还原。 影响标志OF、CF ROL、 RCL影响标志OF、CF情况相同 ; ROR 、 RCR影响标志OF、CF情况相同 。 SF、ZF、PF、AF不影响。
185
(1)、ROL (Rotate left )不含CF循环左移指令 格式: ROL dest ,cnt ;不含CF循环左移指令, B/W
移动8次后操作数还原。 dest CF 指令格式举例: ROL BH , 1 ROL DX , CL ROL WORD PTR TABLE[DI],1 ROL BYTE PTR ALPHA ,CL
186
影响标志OF、CF 情况: 左循环移动1次后: 左循环移动多次后: OF 值不定。 SF、ZF、PF、AF不影响。
移位后,最高有效位(符号位)是否发生变化: 如果移位后,最高有效位与CF不等 则: OF = 1, 否则:(无变化时)OF = 0 CF根据各条指令的规定设置。 左循环移动多次后: OF 值不定。 CF=从目标操作数移出的最后一位。 SF、ZF、PF、AF不影响。
187
(2)、ROR (Rotate right )不含CF循环右移指令 格式: ROR dest ,cnt ;不含CF循环右移指令, B/W
右移8次后操作数还原。 dest CF 指令格式举例: ROR CX , 1 ROL BH , CL ROL BYTE PTRBETA , 1 ROL WORD PTR COUNT , CL
188
影响标志OF、CF 情况: 右循环移动1次后: 否则 : OF=0。 右循环移动多次后: OF 值不定。 CF=从目标操作数移出的最后一位。
SF、ZF、PF、AF不影响。
189
(3)、RCL (Rotate left through carry )含CF循环左移指令
格式: RCR dest ,cnt ;含CF循环左移指令, B/W 执行操作:RCL指令操作示意图如下图所示 左移9次后操作数还原。 dest CF 指令格式举例: RCL BX , 1 RCL DL , CL RCL BYTE PTR ARRAY[DI] , 1 RCL WORD PTR [SI+BP] , CL 影响标志:RCL 与ROL 影响标志OF、CF情况相同
190
(4)、RCR (Rotate right through carry )含CF循环右移指令
格式: RCR dest ,cnt ;含CF循环左移指令, B/W 执行操作:RCR指令操作示意图如下图所示 右移9次后操作数还原。 dest CF 指令格式举例: RCR DI, 1 RCR SI , CL RCR WORD PTR[SI+BX+3], 1 RCL BYTE PTRPORT, CL 影响标志:RCR 与 ROR 影响标志OF、CF情况相同
191
小结: 1 CL 带进位循环左移移9次还原 循环右移(不带CF) 移8次还原 循环左移(不带CF) 移8次还原 执行操作 名称 指令格式
算术右移 (带符号数÷2) 逻辑右移 (无 符号数÷2) 执行操作 名称 指令格式 SHL oprd, 1 CL 逻辑左移 (无符号数*2) CF SAL oprd, 算术左移 SHR oprd, SAR oprd, ROL oprd, ROR oprd, RCL oprd, 1 1 RCR oprd,
192
循环移位指令(Rotate)与移位指令(Shift)不同点:
循环移位指令移位后,操作数中原来各数位的信息不会丢失,这是移动了位置,必要时可以恢复。 循环移位指令可以对操作数进行测试。 例:测试(AL)5 =? 0 MOV CL , 3 ROL AL , CL JNC ZERO … ZERO: …
193
利用带进位循环移位指令将两个寄存器或存储器单元
组合起来一起移位。 例: 将DX、AX组合起来构成32位寄存器向左移一位。 如下图所示: 32位寄存器向左移一位 程序: SHL AX , 1 RCL DX , 1
194
四、串操作指令(String manipulation )
“串”就是内存中一段地址相连的字节或字。 串操作—对串中各项进行操作,也叫数据块操作。 8088有5种基本操作: 1、 MOVS(Move string) 串传送指令 2、CMPS(Compare string) 串比较指令 3、SCAS(Scan string) 串扫描指令 4、LODS(Load from string) 从串取指令 5、STOS (Store in to string) 存入串指令
195
共同点: 可以只有源操作数,可以只有目标操作数,可能二者都有。 源操作数用SI 寻址,隐含DS值为段地址,可以用段跨越前缀指定其它段。
目标操作数用DI寻址,隐含ES为段地址。 每次操作对SI、DI 调整: DF=1,DI、SI自动-1 (字节)或-2(字); DF=0,DI、SI自动+1(字节)或+2(字)。 与上述指令基本配合使用前缀有: REP(Repeat)重复。 REPE/REPZ(Repeat while equal/zero) 相等/为零则重复。 REPNE/REPNZ(Repeat while not equal/not zero)不相等/不为零则重复。
196
下面分二种情况来讨论: (一) 与REP相配合工作的MOVS、STOS、LODS指令 REP 重复串操作直到(CX)=0为止
(二) 与REPE/REPZ和REPNE/REPNZ联合工作的CMPS和SCAS指令 REPE/REPZ 当相等/为零时重复串操作 REPNE/REPNZ 当不相等/不为零时重复串操作
197
(一) 与REP相配合工作的MOVS、STOS、LODS指令
REP 重复串操作直到(CX)=0为止 格式:REP String Primitive 串指令 String Primitive 可为:MOVS、STOS、LODS。 MOVS(Move String) 串传送 LODS(Load from String) 从串取指令 STOS(Store into String) 存入串指令
198
REP 重复串操作执行过程: (1)当(CX)= 0 ,结束REP, 执行REP后的下一条指令。 (2) 当(CX)≠0, (CX) (CX) -1 , (3) 执行REP后的串指令, (4) 重复(1)~(3)。 REP 执行流程图
199
(1) MOVS dest,src;((ES):(DI)←((DS):(SI))
MOVS(Move string)串传送 串传送有3种格式: (1) MOVS dest,src;((ES):(DI)←((DS):(SI)) MOVSB (字节);(SI)←(SI)±1,(DI)←(DI) ±1 MOVSW (字);(SI)←(SI)±2,(DI)←(DI)±2 当方向标志 CLD , DF=0时 用“+” STD , DF=1时 用“-” 该指令不影响条件码 。 *如: MOVS ES:BYTE PTR [DI],DS:[SI] * MOV单指令不能完成 存储单元之间的数据传送; MOVS指令就是为解决 存储单元之间数据传送而设置的。
200
例:将内存的数据段中以AREA1为首地址的100个数据,传送到附加段中的AREA2为首地址的区域。
用MOVS串操作指令编程: MOV AX,SEG AREA1 MOV DS,AX MOV AX,SEG AREA2 MOV ES,AX MOV SI,OFFSET AREA1 MOV DI,OFFSET AREA2 MOV CX,100 CLD ; DF=0,增址传送 LOOP1:MOVS ES:BYTE PTR[DI], DS:[SI]
201
应用MOV指令编程: MOV AX,SEG AREA1 MOV DS,AX MOV AX,SEG AREA2
MOV ES,AX MOV SI,OFFSET AREA1 ;将ARE1偏移地址→SI MOV DI,OFFSET AREA2 MOV CX,100 LOOP1:MOV AL,[SI] ; (AL)←((DS):(SI)) MOV ES:[DI],AL ;((ES):(DI))←(AL) INC SI INC DI DEC CX JNE LOOP1
202
归纳在执行MOVS指令时,应该先做好以下准备工作:
(1) 数据段中源串首地址(如反向传送到末地址)存入SI寄存器中。 (2) 附加段中目的串首地址(或反向传送末地址)存入DI寄存器中。 (3) 数据串长度存入CX寄存器。 (4) 建立方向标志 建立方向标志介绍两条指令: · CLD(clear direction flag) 功能:DF=0,执行串处理指令时 可以使地址自动+1或+2。 · STD(set direction flag) 功能:DF=1,执行串处理指令时可以使地址自动-1或 -2。
203
LODS(Load from string) 从串取指令
从串取指令有3种格式: LODS src;(字节)(AL) ((DS):(SI)), (SI) (SI) ±1 (字)(AX) ((DS):(SI)),(SI) (SI)±2 LODS B (字节);(AL) ((DS):(SI)),(SI) (SI) ±1 LODS W (字) ;(AX) ((DS):(SI)),(SI) (SI)±2 功能:该指令把由(SI)指定的数据段中某单元内容 (AL) 或 (AX)中。 DF=0,(SI)← (SI)+1或+2 DF=1,(SI) ←(SI)-1或-2
204
LODS应用注意: (1) 指令允许用段跨越前缀来指定非数据段的存储区。 (2) 该指令不影响条件码。 一般说来,
(1) 指令允许用段跨越前缀来指定非数据段的存储区。 (2) 该指令不影响条件码。 一般说来, 它不与REP联用,每重复一次,累加器的内容就改变一次。 (AL)中只能保持最后一个元素。 有时缓冲区中的一串字符需要多次取出测试时可用本指令。 适用于在一个循环中,用基本串操作指令构成复杂串操作时很有用。
205
将(AL)或(AX) ((ES):(DI)),(DI) ±1或±2(DI) 存入串指令有3种格式:
3 STOS(Store into string) 存入串指令 将(AL)或(AX) ((ES):(DI)),(DI) ±1或±2(DI) 存入串指令有3种格式: STOS dest;(字节) ((ES):(DI)) (AL) , (DI) (DI) ±1 (字) ((ES):(DI)) (AX) , (DI) (DI) ±2 (2) STOS B (字节); ((ES):(DI)) (AL) , (DI) (DI) ±1 (3) STOS W (字) ; ((ES):(DI)) (AX) , (DI) (DI) ±2 用途: 与REP联用时,(CX)←缓冲区长度。用来建立一串相同的值。
206
例:在附加段STORE开始存5个空格 程序: MOV AL,20H ;‘_’ (AL) MOV CX,5 MOV DI,offset STORE CLD REP STOSB ;((ES):(DI)) (AL) (DI) (DI)+1
207
例:内存中有一个首地址为BLOCK补码表示的有符号数的数据块。 要求将正、负数分开,分别存于二个缓冲区:
学习LODS,STOS指令应用 例:内存中有一个首地址为BLOCK补码表示的有符号数的数据块。 要求将正、负数分开,分别存于二个缓冲区: 存放正数的缓冲区首址为PUOS-DATA, 存放负数的缓冲区首址为MINUS-DATA。 设: 源数据块用SI寻址, 正数的目的区用DI寻址, 负数的目的区用BX寻址。 循环次数 ( CX )。
208
传送过程: 用LODS指令把源数据取入(AL)中, 检查其符号,确定正、负, 若为正数用STOS指令送至正数缓冲区,
若是负数,把(DI)与(BX)交换,仍使用STOS传送, 传送 完后再 将(DI)与(BX)交换,恢复原值。
209
程序:START: MOV SI,OFFSET BLOCK
MOV DI,OFFSET PUOS-DATA ; 正数缓冲区 MOV BX,OFFSET MINUS-DATA ;负数缓冲区 MOV CX,COUNT CLD GOON: LODS B TEST AL,80H JNZ MINS ;若负数转MINS STOS B ;正数 ,(DI)←(AL),(DI)←(DI)+1 JMP AGAIN MINS: XCHG BX,DI STOSB ;负数 ,(DI)←(AL),(DI)←(DI)+1 XCHG BX,DI AGAIN:DEC CX JNZ,GOON HLT
210
(二) 与REPE/REPZ和REPNE/REPNZ联合工作的CMPS和SCAS指令
格式:REPE(或REPZ)string primitive 当相等重复前缀REPZ String primitive可为 : CM PS , SCAS 1、CM PS(Compare string ) 串比较指令 2、SCAS (Scan string ) 串扫描指令,搜索指令
211
执行过程: 注意: REPZ执行流程 当(CX)= 0 , 结束REPZ, 执行REPZ下一条指令;
(2) 当(CX)≠0,将CX 的内容减1, 执行REPZ后的串指令; (3) 当ZF = 1, 返回 (1) ; (4) 当ZF≠1, 则结束REPZ 执行REPZ下一条指令。 注意: ◆ (CX)减1操作不影响标志 ◆ ZF标志由串操作决定 ◆ 当 (CX) = 0或ZF=0时退出循环 REPZ执行流程
212
格式:REPNE(或REPNZ)string primitive 当不相等重复前缀REPNZ
string primitiveString primitive可为 : CM PS , SCAS 1、CM PS(Compare string ) 串比较指令 2、SCAS (Scan string ) 串扫描指令,搜索指令
213
执行过程: 注意: REPNZ执行流程 当(CX )= 0 , 结束REPNZ, 执行REPNZ下一条指令。
(2) 当(CX)≠0,将CX 的内容减1, 执行REPNZ后的串指令。 当ZF = 0, 返回(1); 当ZF≠0, 则结束REPNZ, (4) 执行REPNZ下一条指令。 注意: ◆ (CX)减1操作不影响标志 ◆ ZF标志由串操作决定 ◆ 当 (CX) = 0或ZF=1时退出循环 REPNZ执行流程
214
(1) CMPS dest,src;((ES) :(DI) -(DS):(SI)),结果不存,置标志
1、CM PS(Compare string ) 串比较指令 (SI)—作为源串地址,(DI)—目的串地址 串比较指令有3种格式: (1) CMPS dest,src;((ES) :(DI) -(DS):(SI)),结果不存,置标志 CMPS B (字节);(SI) (SI)±1,(DI)←(DI) ±1 CMPS W (字);(SI) (SI)±2,(DI) (DI)±2 执行操作: ((ES) :(DI) -(DS):(SI)),结果不存,置标志。 字节操作:(SI) (SI)±1,(DI)←(DI) ±1 字操作:(SI) (SI)±2,(DI) (DI)±2 注意: 两数相减,只影响标志,不影响操作数。 其它操作规定与MOVS同。
215
学习REPZ CMPSB指令 例:利用CMPS指令对STRING1和STRING2二个字符串进行 比较,相同在RESULT 单元送00H,不同送0FFH。 MOV SI,OFFSET STRING1 MOV DI,OFFSET STRING2 MOV CX,COUNT CLD REPZ CMPSB JNZ UNMAT ;若串不同,在RESUL单元中置0FFH MOV AL,0 ;若串相等,在RESULT单元中置00H JMP OULPT UNMAT:MOV AL,0FFH OUTPT: MOV RESULT,AL HLT
216
2、SCAS (Scan string ) 串扫描指令,搜索指令
(DI)—字符串起始地址,(AL)或(AX) — 关键字 串扫描指令有3种格式: 格式:SCAS dest SCASB(字节);(AL)-((ES):(DI)),(DI)(DI)±1 SCASW(字);(AX)-((ES):(DI)),(DI) (DI)±2 注意: (AL)或(AX) - 目的串 两数相减,只影响标志,不影响操作数。 其它特性与MOVS同。
217
REP NE SCASB指令应用。 例:要搜索的关键字 放在(AL)或(AX)中,搜索某一数据块或字符串中有无关 键字,若有,把搜索次数记下来,且记录关键字地址;若次数为0,表示没有要搜索的关键字。 MOV DI,0FFSET BLOCK;设置数据块地址指针 MOV CX,COUNT ;设置数据块长度 MOV AL,CHAR ; 关键字送入AL或AX REP NE SCASB ;(CX)≠0,Z=0 继续SCASB JZ FOUND MOV DI,0 JMP DONE FOUND:DEC DI MOV POINTR,DI MOV BX,OFFSET BLOCK SUB BX,DI MOV DI,BX ;把搜索次数记下来,且记录关键字地址 DONE: HLT
218
应用举例: 例:一个数据块由大小写英文字母、数字、其他符号组成, 用CR(ASCII码0DH)结束。数据块首地址为BLOCK1。 将其传送到BLOCK2为首地址的内存区,并将英文中小 写英文字母(a~z)转换成大写英文字母(A~Z),其余不变。 分析: 大小写英文字母中相应ASCII码的关系: ‘a’~’z’相应ASCII码为: 61H~7AH ‘A’~’Z’相应ASCII码为:41H~5AH 英文中小写英文字母(a~z)转换成大写英文字母(A~Z): 只要将小写的ASCII码减去20H即可。 程序和流程图如下:
219
程序: 流程图 LEA SI , BLOCK1 LEA DI , BLOCK2 CLD NEXT: LODSB CMP AL , 0DH
JZ DONE CMP AL , 61H JC OK CMP AL , 7BH JNC OK SUB AL , 20H OK: STOSB JMP NEXT DONE: HLT 流程图
220
小结:串操作指令重复前缀,操作数,地址指针
地址指针寄存器 MOVS REP 源,目标 (DS): (SI) , (ES): (DI) CMPS REPE/REPNE (DS): (SI) ,(ES): (DI) SCAS 目标 (ES): (DI) LODS 无 源 (DS): (SI) STOS
221
五.控制传送指令(Control transfer instructions) (一)、控制传送指令概述
控制传送指令包括四种: 转移指令,循环控制指令,过程调用指令,中断指令。 1、转移指令 转移指令包括两种: (1)、JMP(Jump) 无条件转移指令 (2)、Jcc 条件转移指令
222
(1)、 JMP(Jump)无条件转移指令 转移分成两类:段内或段间转移。 无条件转移指令有五种格式: 段内直接短转移 段内直接近转移 段内间接转移 段间直接远转移 段间间接转移 JMP指令的操作:无条件地将控制转移到指令中规定的目的地。 目标地址可以是:直接方式/间接方式给出。 JMP指令不影响标志位。
223
(2)、Jcc 条件转移指令 汇编程序设计中常利用条件转移指令来实现分支。 “cc”-表示条件。
操作数必须是短标号。转移范围为:-128~+127 具体条件转移指令分四种情况讨论: 根据单个条件标志的设置情况转移 JZ(JE)/JNZ(JNE),JS/JNS,JO/JNO,JP(JPE)/JNP(JPO), JB(JNAE、JC)/JNB(JAE、JNC), 根据两个无符号数比较结果转移 JB(JNAE、JC)/JNB(JAE、JNC),JBE(JNA)/JNBE(JA) 比较两个带符号数,并根据比较结果转移 JL(JNGE)/JNL(JGE),JLE(JNG)/JNLE(JG) 测试CX的值为零转移 JCXZ
224
2、 过程调用指令 如果有一些程序段在不同地方反复出现,可以将这些程序段设计成为过程(子程序)供调用。过程结束,返回调用处。
过程调用指令包括:过程调用指令和返回指令 (1)、 CALL( Call a procedure)调用 CALL调用指令 段内直接调用 段间直接调用 段内间接调用 段间间接调用 (2)、 RET( Reture from procedure)返回 RET返回指令 段内返回 段间返回 段内带立即数返回 段间带立即数返回
225
循环控制指令用于使一些程序段反复执行形成循环程序。
3、循环控制指令 循环控制指令用于使一些程序段反复执行形成循环程序。 循环控制指令有三种: (1)、LOOP (Loop) 循环指令 (2)、LOOPE/LOOPZ (Loop if equal / Loop if zero)当相等/为“0”循环 (3)、LOOPNE/LOOPNZ (Loop if not equal/ Loop if not zero) 当不相等/不为“0”循环
226
4、中断指令 8086/8088CPU 可以在程序中安排一条中断指令引起中断过程,这种中断称为软中断。 8086/8088CPU共有三条中断指令: (1)、INT (Interrupt) (2)、INTO(Interrupt if overflow) (3)、IRET(Interrupt Return)
227
归结控制转移指令分类 指令类型 助记符 无条件转移 JMP 条件转移
JE/JZ, JNE/JNZ, JS, JNS, JP/JPE, JNP /JPO,JO, JNO, JC, JNC, JB/JNAE, JAE/JNB, JA/JNBE, JBE/JNA,JG/JNLE, JGE/JNL, JL/JNGE, JLE/JNG ,JCXZ 循环控制 LOOP, LOOPE/LOOPZ, LOOPNE/LOOPNZ 过程调用 CALL, RET 中断指令 INT, INTO, IRET
228
(二).控制传送指令(Control transfer instructions)
1、转移指令 转移指令将程序控制从一处转换到另一处的最直接方法。 在CPU内部,转移是通过将目标地址传送给IP来实现的。 注意:CS—段地址 转移地址 IP—偏移量 调用地址寻址
229
先介召控制和非控制转移指令的概念 非控制转移指令:指令本身对CS和IP均无操作,形成顺序执行结构。 顺序执行结构: 顺序存放,顺序执行 控制转移指令: 以CS和IP为主要操作对象, 改变CS和IP寄存器的值, 就改变了程序执行的流程。 ◢ 程序是指令的集合 ◢ 指令在内存中顺序存放
230
在8086/8088中,指令的地址固定由CS和IP两个寄存器决定。 CS和IP两寄存器的内容决定了程序的流程 ,
reset复位后,( CS ) = FFFFH,( IP ) = 0 故8088从内存FFFF:0000H处取第一条指令执行, 第一条指令在内存的ROM区。 非控制转移指令 CPU取来一条指令后, 自动将IP的值加上该指令的字节数, 使IP顺序指向下一条指令, CPU取来紧接着的指令执行。 (此时IP的变化由CPU内部的硬件自动完成)
231
控制转移指令以CS和IP为主要操作对象 控制转移指令改变CS和IP的值, 使程序产生分支、调用结构。
分支结构、调用结构: 顺序存放,非顺序执行 例:比较(AX)、(BX)的大小,将大数存于( max )单元。 CMP AX, BX JGE great XCHG AX, BX great: MOV [max], AX
232
(1)、JMP(Jump)无条件转移指令 JMP(jmp)跳转指令。 JMP指令必须指定转移的目标地址(或转向地址)。
转移分成两类:段内或段间转移。 段内转移:只要改变IP寄存器的内容 指在同一段的范围之内进行转移 即用新的转移目标地址代替原有的IP值。 段间转移:要修改IP、 CS寄存器的内容 转到另一段去执行程序。 即转移目标地址= 新的段地址和偏移地址两部分组成。
233
段内直接短转移: 格式:JMP SHORT OPR OPR—在汇编语言中使用符号地址。 在机器语言中存放位移量D8
段内直接短转移: 格式:JMP SHORT OPR OPR—在汇编语言中使用符号地址。 在机器语言中存放位移量D8 位移量D8 = 符号地址的偏移地址 - 当前IP的值 执行操作:(IP)←(IP)当前+D8 SHORT 短属性标号 8位位移量D8的范围在(-128 ~ 127)之间,占有一个字节。 而指令本身占有两个字节。
234
例如:代码段内有一条无条件转移指令在汇编语言中使用符号地址。 JMP SHORT NEXT指令执行过程:
(IP)←(IP)当前+D8
235
8位位移量D8的范围在(-128 ~ 127)之间,否则出错。
如:tager: …… JMP tager JMP SHORT tager …… tager: 标号与控制转移指令在同一段中, 后引用的标号可以不用SHORT, 前引用的标号必须使用SHORT
236
段内直接近转移: 格式:JMP NEAR PTR OPR OPR—在汇编语言中使用符号地址。 在机器语言中存放位移量D16
段内直接近转移: 格式:JMP NEAR PTR OPR OPR—在汇编语言中使用符号地址。 在机器语言中存放位移量D16 位移量D16 = 符号地址的偏移地址 - 当前IP的值 执行操作: (IP)←(IP)当前+D16 NEAR近属性标号 位移量为D16范围:-32768~+32767H,占有两个字节。 而指令本身占有三个字节。可以转移到段内的任一位置。 过程:如同SHORT,只是位移量为D16范围-32768~+32767H, 占有两个字节。
237
段内间接转移: (CS)不变,只改变(IP)
格式:JMP WORD PTR OPR OPR —为16位寄存器、 或存储器(除立即数以外的任何一种寻址方式) 执行操作: (IP) (EA) 或(IP) (reg16) 指令格式举例: JMP AX JMP SI JMP TABLE [BX] ; 操作数已定义为16位存储器 JMP ALPHA_WORD ;操作数已定义为16位存储器 JMP WORD PTR [BP][DI]
238
例: (DS)=1000H, (BX)=1000H, (CX)=5000H, (CS)=3000H
(11000H)=1234H, ( 11002H)=5678H JMP CX ; (IP)=5000H JMP WORD PTR [BX] ;(CS)=3000H , (IP)=1234H (PA)=(16d(DS)+(BX))=(11000H)=1234H 例: (DS)=1000H, (BX)=1000H, (CX)=5000H, (CS)=3000H (11000H)=1234H, ( 11002H)=5678H JMP CX ; (IP)=5000H JMP WORD PTR [BX] ;(CS)=3000H (IP)=1234H (PA)=(16d´(DS)+(BX))=(11000H)=1234H
239
段间直接(远)转移: (CS) 、 (IP)都改变
格式:JMP FAR PTR OPR; OPR—在汇编语言中使用符号地址。 符号地址与指令不在同一个段里。 在机器语言中则要指定转向地址的偏移地址和段地址 执行操作: (IP)←OPR所在的段内偏移地址。 (CS)←OPR所在的段的段址。 而指令本身占有5个字节: 用2个字分别存放符号地址的段值、偏移值, 用1个字节存放操作码。
240
FAR 远属性标号, 标号与控制转移指令不在同一段中。 在汇编语言中,在机器语言中存放如下: 例: C1 SEGMENT
… JMP FAR PTR next_prog C ENDS C SEGMINT next_prog: … C ENDS C1段 … … E A OP码 5 0 新(IP)=0250H JMP指令 0 2 0 0 新(CS)=2000H 2 0 … … C2段 20000H … … next_prog: 20250H 2000:0250H … …
241
段间间接转移:(CS) 、 (IP)都改变
格式:JMP DWORD PTR OPR OPR —可以使用存储器 (除立即数和寄存器以外的任何一种寻址方式) 执行操作: (IP)←(EA) (CS)←(EA+2) 例:已知 (BX)=1000H,(SI)=2000H , (DS)=2000H (23000H)=2211H, (23002H)=4433H JMP DWORD PTR [BX][SI] 则: (BX)+(SI)=3000H (IP)=(PA)=(16d(DS)+(BX)+(SI))=(23000H)=2211H (CS)=(PA+2)=4433H
242
( 2)、Jcc 条件转移指令 根据单个条件标志的设置情况转移(10种) JZ(JE)/JNZ(JNE),JP(JPE)/JNP(JPO),
JS/JNS, JO/JNO, JB(JNAE、JC)/JNB(JAE、JNC), 根据两个无符号数比较结果转移(4种) JB(JNAE、JC)/JNB(JAE、JNC),JBE(JNA)/JNBE(JA) 比较两个带符号数,并根据比较结果转移(4种) JL(JNGE)/JNL(JGE),JLE(JNG)/JNLE(JG)
243
指令格式:J cc OPR 操作:根据上一条指令所设置的条件码来判别测试条件转移。 每一种条件转移指令都有它的测试条件。 满足条件时 : (IP)←(IP)当前+ 符号扩展到16位后的位移量D8, 使用相对寻址方式,范围-128~+127个字节 不满足条件时:(IP)不变,顺序执行下一条指令
244
注意几点: 所有条件转移指令都是相对转移形式, 范围(-128~+127)。 当需往一个较远地方进行条件转移时, 选用条件转移转到附近一个单元, 然后,再用无条件转移转到较远的目的地。 ② 条件转移指令中,相当一部分指令是在比较完二个数大小后,根据结果而决定是否转移, ③条件转移指令不影响标志位
245
按转移条件不同,条件转移指令可以分为四大类: ① 以单个状态标志作为转移条件助记符 转移条件
① 以单个状态标志作为转移条件助记符 转移条件 助记符 转移条件 JZ/JE ZF=1 JNZ/JNE ZF=0 JS SF=1 JNS SF=0 JO OF=1 JNO OF=0 JP/JPE PF=1 JNP/JPO PF=0 JC CF=1 JNC CF=0 ② 以CX的值为0作为转移条件 助记符 转移条件 JCXZ CX=0
246
③以两个无符号数比较的结果作为转移条件 ④以两个带符号数比较的结果作为转移条件 助记符 转移条件 JA/JNBE
CF∨ZF=0 高于/不低于等于 JAE/JNB/JNC CF= 高于或等于/不低于/无进位 JB/JNAE/JC CF= 低于/不高于等于/有进位 JBE/JNA CF∨ZF=1 低于或等于/不高于 ④以两个带符号数比较的结果作为转移条件 助记符 转移条件 JG/JNLE (SF⊕OF)∨ZF=0 大于/不小于等于 JGE/JNL SF⊕OF= 大于或等于/不小于 JL/JNGE SF⊕OF= 小于/不大于等于 JLE/JNG (SF⊕OF)∨ZF=1 小于或等于/不大于
247
例:比较二个数是否相等 如相等做动作1 否则做动作2 ……
条件转移指令应用 例:比较二个数是否相等 如相等做动作1 否则做动作2 …… CMP AX,BX JE action_1 Action_2: …… action_1 : …… 或 …… CMP AX,BX JNZ action_2 action_1: …… action_2: ……
248
例: X,Y放在X,Y单元里,(带符号数判断) 先判X>50,YES→too_high,
NO→ 做X-Y , 溢出→overflow ,否则求|XY|→result MOV AX,X CMP AX,50 JG too_high ;大于转too_high SUB AX,Y JO overflow ;溢出转overflow JNS nonneg ; S=0转nonneg NEG AX nonneg: MOV result ,AX too_high: …… overflow: ……
249
例:在M中有一个首地址为array的N字数组,
要求测试其中正数、0及负数的个数. (带符号数判断) 正数个数放在: (DI)中, 的个数放在: (SI)中, 负数的个数放在: N-(DI)-(SI)送(AX) 如果没有负数转skip, 如果有负数转neg_val 程序: mov cx,N ; N字数组 mov bx,0 mov di,bx mov si,bx again: cmp word ptr arrary[bx],0 jle less_or_ag inc di ;正数个数 jmp short neat less_or_ag: jl neat inc si ; 0的个数 neat: add bx,2 dec cx jnz again mov ax,N sub ax,di sub ax,si jz skip;没有负数 jmp near ptr neg_val;有负数 skip: …… neg_val: ……
250
2、 过程( 子程序 )调用指令 子程序—程序中具有独立功能的部分编写成独立程序模块。 子程序(过程)定义格式: 符号名 PROC 类型
…… 符号名 ENDP 子程序调用和返回指令: CALL RET(RETURN) 过程有两种类型: 按过程与调用语句间的位置,过程有两种类型。 NEAR类型:调用指令与过程在同一个段中 FAR类型:调用指令与过程不在同一个段中 CALL指令和RET指令都不影响条件码。
251
(1)、 CALL( Call a procedure)调用
段内直接调用 段间直接调用 段内间接调用 段间间接调用
252
段内直接调用 格式:CALL DST ;(SP)←(SP)-2, ((SP)+1,(SP))←(IP)
段内直接调用 格式:CALL DST ;(SP)←(SP)-2, ((SP)+1,(SP))←(IP) ; (IP) ← (IP)+D16 DST—给出转向地址(子程序的入口地址)。 D16—机器指令中的位移量(转向地址和返回地址之差)。 位移量为D16范围-32768~+32767H,占有两个字节。
253
工作过程如下: 例: NEAR 类型过程 code SEGMENT ;code段 … CALL subp ;调用 指令 YYY入栈 ,D16 =subp-yyy XXX:YYY … subp PROC NEAR ;过程定义 RET ;返回 subp ENDP code ENDS
254
子程序和调用程序在同一个程序模块中,子程序可以直接访问模块中的变量。
例:两个数据变量X与Y相乘 子程序和调用程序在同一个程序模块中,子程序可以直接访问模块中的变量。 DATASG SEGMENT X DW 100 Y DW 10 DATASG ENDS CODESG SEGMENT MAIN PROC FAR ASSUME CS:CODESG, DS:DATA SG START: … CALL subp … RET MAIN ENDP subp PROC NEAR MOV AX,X MOV BX,Y MUL BX RET subp END CODESG ENDS END START
255
段内间接调用: 格式: CALL DST; ↑ WORD PTR OPR OPR —为16位寄存器, 或存储器(除立即数以外的任何一种寻址方式) 执行操作: (SP)←(SP)-2 ((SP)+1,(SP))←(IP) (IP)←(EA) EA—由DST寻址方式所确定的有效地址。
256
段间直接调用: 格式:CALL FAR PTR DST; 执行操作 : (SP)←(SP)-2 ((SP)+1,(SP))←(CS)
段间直接调用: 格式:CALL FAR PTR DST; 执行操作 : (SP)←(SP)-2 ((SP)+1,(SP))←(CS) ((SP)+1,(SP))←(IP) (IP)←DST偏移地址(指令中第2,3字节 ) (CS)←DST段地址(指令中第4,5字节 )
257
例 : … CSEG1 SEGMENT CALL FAR PTR subp;α处的CS:IP入栈转subp α: … …
例 : … CSEG SEGMENT CALL FAR PTR subp;α处的CS:IP入栈转subp α: … … CSEG ENDS CSEG SEGMENT subp PROC RET subp ENDP CSEG2 ENDS
258
段间间接调用: 格式: CALL DWORD PTR DST 执行操作: (SP)←(SP)-2 ((SP)+1,(SP))←(CS)
段间间接调用: 格式: CALL DWORD PTR DST 执行操作: (SP)←(SP)-2 ((SP)+1,(SP))←(CS) ((SP)+1,(SP))←(IP) (IP)←(EA) (CS)←(EA) 转子程序入口 EA—由DST的寻址方式确定的有效地址。
259
(2)、 RET( Reture from procedure)返回
放在子程序的末尾 使子程序在功能完成后返回调用程序继续执行。 *为能准确返回 ,返回指令类型与调用指令类型相对应。 RET返回指令有4种: 段内返回 段间返回 段内带立即数返回 段间带立即数返回 在子程序调用时,返回地址入栈 返回时:将返回地址出栈 (IP)(段内或段间)。 (CS)(段间)。
260
段内返回: 格式: RET; 机器码: C3H或者C2H 执行操作:(IP)←((SP)+1,(SP)) (SP)←(SP)+2
段内返回: 格式: RET; 机器码: C3H或者C2H 执行操作:(IP)←((SP)+1,(SP)) (SP)←(SP)+2 段间返回: 机器码: CBH或CAH 执行操作: (IP)←((SP)+1,(SP)) (CS)←((SP)+1,(SP))
261
段内带立即数返回 格式: RET EXP; 执行操作: (IP)←((SP)+1,(SP)) (SP)←(SP)+2
段内带立即数返回 格式: RET EXP; 执行操作: (IP)←((SP)+1,(SP)) (SP)←(SP)+2 (SP)←(SP)+D16 EXP—是一个表达式 计算出来的常数成为机器指令中位移量D16,修改堆栈 指针。
262
例如:RET EXP 堆栈使用情况: …… RET EXP 堆栈使用情况: DELCHAR PROC …… RET 4
CODE SEG MENT ASSUME CS:CODE,DS:DATA MAIN PROC FAR START: MOV AX,DATA MOV DS,AX …… PUSH BX PUSH CX CALL DELCHAR CS:XXXX MOV AH,4CH INT 21H MAIN ENDP DELCHAR PROC …… RET 4 DELCHAR ENDP CODE ENDS END START RET EXP 堆栈使用情况:
263
段间带立即数返回: 格式:RET EXP; 执行操作: (IP)←((SP)+1,(SP)) (SP)←(SP)+2
段间带立即数返回: 格式:RET EXP; 执行操作: (IP)←((SP)+1,(SP)) (SP)←(SP)+2 (CS)←((SP)+1,(SP)) (SP)←(SP)+D16 CALL指令和RET指令都不影响条件码。
264
例:学习使用 段内、段间直接调用指令的使用及堆栈情况 主程序 MAIN在一个代码段中
例:学习使用 段内、段间直接调用指令的使用及堆栈情况 主程序 MAIN在一个代码段中 子程序 PRO-A PRO-B PRO-C 在另一个代码段 程序调用关系: 另一个代码段 PRO-A PRO-B …… …… CALL near ptr PRO-B CALL near ptr PRO-C (IP)=2500H (IP)=4000H …… …… CALL near ptr PRO-C RET (IP)=3700H …… PRO-C …… RET RET (SP)=0100H MAIN …… CALL far ptr PRO-A (CS)=0500H (IP)=1000H
265
堆栈情况:
266
(3) 、小结 : 指令格式: JMP 操作数 操作数 执行操作 ◢ 位移量 = 符号地址的偏移量 - 当前IP的值。
符号地址 (SHORT) (IP) ← (IP)当前+ 8位位移量 符号地址 ( NEAR属性) (IP) ← (IP)当前+ 16位位移量 reg (16位)或 mem ( DW类型 ) (IP) ← ( reg ) 或(IP) ← (mem) 符号地址 ( FAR属性) (IP) ← 符号地址的偏值 (CS) ← 符号地址的段值 mem ( DD类型 ) (IP) ← ( mem ), (CS) ← (mem+2 ) ◢ 当前IP的值为控制转移指令下一条指令的偏移地址。 ◢ 位移量 = 符号地址的偏移量 - 当前IP的值。 ◢ 符号地址(目标地址)= 当前IP的值 + 位移量
267
转移方式:由CS是否变化、以及操作数类型决定情况如下表
跳转范围 段内直接短 方 式 不变 符号地址(SHORT) -128 ~ 127即0~FFH 段内直接近 方 式 符号地址(NEAR属性) 一个段内0~FFFFH 段 内间接方式 Reg mem (DW类型) 段 间直接方式 变 符号地址(FAR属性) 整个内存0~FFFFFH 段 间间接方式 mem(DD类型)
268
各控制转移指令允许使用的转移方式 转移方式 无条件转移JMP 条件转移 Jcc 循环转移 LOOPxx 子程调用CALL 段内直接短 方 式
√ × 段内直接近 方 式 段 内间接方式 段 间 直接方式 段 间间接
269
例 : JMP again (√) JMP BX (√) JMP WORD PTR [BX] (√) JMP DWORD PTR (√) Jz AX (×) LOOP BX (×) Jnz next (×) (若 next的位移量超出-128~127) 指令JMP、CALL 、Jcc、LOOPxx本身对标志无影响。
270
3、循环控制指令 格式 : LOOPxx 符号地址 执行 操作 : ①(CX) ← (CX)- 1 此操作不影响标志
执行 操作 : ①(CX) ← (CX)- 1 此操作不影响标志 ② 检查转移条件xx,满足转向目标地址去执行; 不满足执行LOOPxx后一条指令 转移方式 只允许段内直接短方式,跳转范围-128~127 助记符 转移条件 不转移条件 LOOP CX≠0 CX=0 LOOPZ CX≠0且ZF=1 CX=0或ZF=0 LOOPNZ CX≠0且ZF=0 CX=0或ZF=1
271
与条件转移指令不同的是:循环指令隐含 ( CX ) 减1操作。 例:用循环指令将BL寄存器的内容按二进制形式显示出来 学习: LOOP指令
MOV CX , 8 next: ROL BL , 1 MOV DL , BL AND DL , B ADD DL , B MOV AH , 2 INT H DEC CX JNZ next …… LOOP next
272
循环指令说明: LOOP退出循环条件是(CX)=0 LOOPZ和LOOPNZ提供了提前结束循环的可能, 不一定要等到(CX)=0才退出循环。
▲ 在串中查找字符,查到了,就可退出, 可用LOOPNZ,不相等时继续查找。 ▲比较两串时,当有字符不等,就可退出,说明两字符串不等。 可用LOOPZ,当相等时继续比较。 ▲执行完 LOOPNZ或LOOPZ后,根据ZF标志的值判断结果 对查找字符,ZF=1,说明找到;否则没有找到。 对串比较,ZF=1, 说明两串相等;否则不等。
273
(CX) (CX)-1 (CX) = 0 ? 例: 在string字符串中查找空格字符,串长度为N。 用条件转移: JZ MOV CX, N
修改偏址BX Y N AL 关键字 CX 串长度N DS:BX 串首址 判[BX]是关键字? (CX) (CX)-1 找到处理 未找到处理 (CX) = 0 ? 结束出口 用条件转移: JZ MOV CX, N MOV AX, SEG string MOV DS, AX LEA BX,string MOV AL,20H next: CMP AL,[BX] JZ find INC BX DEC CX JNZ next 未找到处理 …… Find: 找到处理
274
next: CMP AL,[BX] JZ find
用条件转移: JZ MOV CX, N MOV AX, SEG string MOV DS, AX LEA BX, string MOV AL,20H next: CMP AL,[BX] JZ find INC BX DEC CX JNZ next 未找到处理 JMP exit find: 找到处理 exit: 结束出口 用循环指令:LOOP NZ next MOV CX, N MOV AX, SEG string MOV DS, AX LEA BX, string MOV AL,20H next: CMP AL, [BX] PUSH F INC BX POP F LOOP NZ next JZ find 未找到处理 JMP exit find: 找到处理 exit: 结束出口 DEC BX next : INC BX CMP AL,[BX] LOOP NZ next JZ find 未找到处理 JMP exit find: 找到处理 exit: 结束出口
275
用LOOPZ和LOOPNZ指令提供提前结束循环的可能性。
有时需要字符串中查找一个字符,找到后可提前结束循环, 用LOOPZ、LOOPNZ来处理。 例:40个元素构成的数组,找出第一个非零元素。 MOV CX,28H MOV SI,0FFH NEXT1:INC SI CMP BYTE PTR [SI],0 LOOPZ NEXT1 ;当Z=1、(CX)≠0循环; 当Z=0,或(CX)=0结束循环。 JNZ OKK ;当找到非零元素转OKK。 CALL DISPLAY1 ;当找不到非零元素转DISPLAY1 …… OKK: CALL DISPLAY2 DISPLAY …… RET DISPLAY ……
276
4、中断指令 中断(Interrupt): 有时当系统运行或程序运行期间遇到某些特殊情况, 需要计算机自动执行一组专门的例行程序来进行处理。 中断例行程序(或中断子程序)(Interrupt routine): 所执行的这组程序就称为中断子程序。 种类: 中断分为内部(软)中断和外部(硬)中断两种。 内部中断—如除法运算中除数为0、中断指令引起的中断。 外部中断—处理I/O设备与CPU之间的通信。
277
CPU响应一次中断自动完成三件事情: (PSW)入栈 — 保护现场, (CS),(IP)保存入栈 — 保留断点, 转中断例行程序去执行。
中断返回时: 恢复(IP)、(CS)及(PSW) 中断向量:中断例行程序入口地址。 IBM-PC中,存储器的最底地址00000H——003FFH为中断向量区, 存放256种类型中断例行程序入口地址, 每个中断向量占4个单元。 中断指定类型号N × 4——取得指定类型的中断向量地址。
278
IBM-PC机中为每个类型规定了一种功能。
例:中断类型9,9 × 4=36 00024H——00027H单元中放中断向量。 IBM-PC机中为每个类型规定了一种功能。 中断类型 功能 类型0 除数为0中断例行程序 类型1 单步 类型2 非屏蔽中断, NMI 类型3 设置断点 类型4 溢出处理中断,INTO指令 类型10 显示设备中断 类型20 程序结束中断 类型21 DOS系统功能调用功能程序 *除非特别注明,类型号是以16进制形式表示的。
279
(1). 介绍几条指令:INT n,IRET 格式:INT n ; n—常数或表达式,n=0—255 或INT 执行操作: (SP)←(SP)-2,((SP)+1,(SP)) ←(PSW) (SP)←(SP)-2,((SP)+1,(SP)) ← (CS) (SP)←(SP)-2,((SP)+1,(SP)) ← (IP) (IP) ←(N×4) (CS) ←(N×4+2) 清除IF、TF,避免进入中断以后不被外面其它中断所打断 及进入中断以后按单步执行。
280
类型0~3的中断称为内部中断。 类型0 :指令系统没有INT0这条指令 除数为0中断 除数为0 :它既不是外部中断 也不是软件中断。 是由 CPU自身产生的,所以无对应中断指令。 有符号数进行除法所得的商超出规定范围 有符号数进行除法运算,所得的商超出规定范围, CPU自动产生类型为0的中断,转入响应的中断处理程序。 。
281
内存0:0000H~0:03FFH区域中,构成中断向量表,存放中断处理程序入口地址。 每4个单元对应1个中断源。关系如下表:
中断处理程序入口地址的地址 类型 00000H~00001H 类型0(IP) 00002H~00003H 类型0(CS) 00004H~00005H 类型1(IP) 00006H~00007H 类型1(CS) 00008H~00009H 类型2(IP) 0000AH~0000BH 类型2(CS) 0000CH~0000DH 类型3(IP) 0000EH~0000FH 类型3(CS) 00010H~00011H 类型4(IP) 00012H~00013H 类型4(CS) …… 003FCH~003FDH 类型255(IP) 003FEH~003FFH 类型255(CS)
282
类型1——单步中断 TF=1进入单步中断。 单步中断不是由外部硬件或程序中的中断产生, 而是CPU测试TF=1时产生的。 单步中断——每执行一条指令,进行一次单步中断处理, 显示出一系列内 部寄存器的值, 并告 示一些附带的信息。 一般用于调试程序中逐条执行用户程序。 对于有重复前缀串操作指令——单步操作下,每重复一次将产生一个单步中断,而不 是整个串操作结束后进入单步操作。 思考: 单步操作T、P 不同点?
283
类型2——NMI中断,非屏蔽中断 NMI中断是由NMI引腿引入,不受IF屏蔽, 只要NMI腿出现中断请求 中断处理子程序入口地址在0:0008H——0:000BH中, CPU予以响应, 进入对应的中断处理。 一般用于处理系统的重大故障。
284
这样运行到断点处执行INT3,转入中断处理程序 , 显示一系列寄存器值,并给出一些重要信息,用户可 判断正误。
类型3——断点中断8088提供的一种调试手段。 设置断点过程(在DEBUG下): -G = 起始地址 断点地址 用户程序指定断点: 用断点的中断指令INT3来代替原有指令, 把用户原有指令进栈保存, 这样运行到断点处执行INT3,转入中断处理程序 , 显示一系列寄存器值,并给出一些重要信息,用户可 判断正误。 断点中断还负责恢复进入中断前的被INT3替换掉的那条指令。
285
(2) 类型4——溢出中断,INTO指令 格式: INT O ; 该指令检测OF标志, OF=1执行 INT O,否则执行INTO下一条执行。 执行操作: (SP)←(SP)-2 , ((SP)+1,(SP)) ←(PSW) (SP)←(SP)-2 ,((SP)+1,(SP)) ←(CS) (SP)←(SP)-2 ,((SP)+1,(SP)) ←(IP) (IP) ←(10H) (CS) ←(12H) IF=TF=0
286
执行: OF为1时,执行 INT O ; OF为0时,执行INTO下一条执行。 例 、、、 INTO 、、、 类型4中断子程 → 、、、
287
使用注意事项: ①对于无符号,有符号 *、/,指令各不相同。 ②对于无符号,有符号 +、- 指令同,
①对于无符号,有符号 *、/,指令各不相同。 ②对于无符号,有符号 +、- 指令同, 有、无符号数 +、- 都有可能产生溢出。 对于无符号数溢出不是什么错误,表示低位字节或字向高位产生进位、借位。 有符号数溢出意味着出错所以应避免。 ③有符号数,OF=1——表示有符号数产生溢出。 无符号数,OF=1——并不表示错误。 ④对CPU来说分不清楚进行的是有、无符号+ -运算,只能是程序员清楚。 8088提供了一条INTO指令,专门用来判断有符号数+、-溢出。
288
∴ INTO跟在有符号数+、-后面: OF=1,执行INTO,进入类型4的溢出中断,给出设置标志。 OF≠1,执行INTO,也转入中断后子程序, 程序对标志进行测试很快返回。 * 这条指令可以写在一条算术指令后面。 若产生溢出,OF=1,则启动中断过程,不进行任何操作。
289
(3) IRET——从中断返回指令(Interrupt return)
所有中断过程(服务程序)不管是硬还是软,最后一条指令一定是: IRET退出中断过程,返回中断时断点。 格式:IRET 执行操作: (IP)←((SP)+1,(SP)) , (SP) ←(SP)+2 (CS)←((SP)+1,(SP)) , (SP) ←(SP) ( PSW)←((SP)+1,(SP)), (SP) ←(SP)+2
290
六、处理器控制指令 (一)标志处理指令 (二)其他处理机控制指令 1、CLC (Clear carry flag ) 清CF标志
2、STC(Set carry flag ) 置CF标志 3、CMC(Complement carry flag ) 对CF求反 4、CLD(Clear direction flag ) 清DF标志 5、STD(Set direction flag ) 置DF标志 6、CLI(Clear interrupt flag ) 清IF标志 7、 STI (Set interrupt enable flag ) 置IF标志 (二)其他处理机控制指令 1、NOP(No operation ) 空操作 2、 HLT(Halt ) CPU暂停状态 3、 WAIT (Wait while pin not asserted ) CPU等待状态 4、 ESC(Escape ) 交权 5、 LOCK(Lock bus ) 总线锁定
291
▲ 设置和清除标志的指令,只影响指令指定的标志。
1. 标志处理指令 ▲ 设置和清除标志的指令,只影响指令指定的标志。 指令格式 执行操作 CLC CF=0 STC CF=1 CLM CF ← CLD DF=0 STD DF=1 CLI IF=0 STI IF=1
292
2.其他处理机控制指令 ① 暂停指令HLT 格式 : HLT 执行 : 使CPU处于暂停状态 用于等待外部中断,中断处理结束后,
例 、、、 、、、 STI ;允许外部中断 HLT ;等待中断 MOV AX, 0
293
● 在中断允许情形下(IF=1),在INTR线上有请求
只有以下几种情况才能脱离暂停状态: ● RESET线上有复位信号 ● 在NMI线上有请求 ● 在中断允许情形下(IF=1),在INTR线上有请求 ② 空操作指令NOP 格式 : NOP 指令不执行任何操作, 但占有3个时钟周期,继续执行下条指令。 其机器码占一个字节单元, 在调试程序时,修改程序用。 做短暂延时 只有以下几种情况才能脱离暂停状态: ●RESET线上有复位信号 ●在NMI线上有请求 ●在中断允许情形下(IF=1),在INTR线上有请求 ② 空操作指令NOP 格式 NOP 指令不执行任何操作,但占有3个时钟周期,继续执行下条指令。 ①其机器码占一个字节单元, 在调试程序时,修改程序用。 ②做短暂延时
294
③处理器脱离(processor Escape)
格式:ESC mem mem——指出一个存储单元, 不能是寄存器和立即数寻找方式 执行: 8088从存储器中读出操作数并放到总线上, 协处理器由此知道要执行什么操作,得到操作数,从而 代替8088操作。 调动协处理器工作的联络手段,ESC二字节指令。 能区分要调用哪个协处理器进行什么操作; 能指出放在存储器中的操作数。
295
④ 处理器等待(Process OR wait)
执行: 处理器等待,CPU处于空操作, 等待外中断发生, 中断结束后,可继续执行下面程序 ⑤ LOCK总线锁定 LOCK实际上是一个指令前缀,可以放在任何一条指令前面。 用来维持总线的锁存信号直到与其联合的指令执行完; CPU与其他协处理器协同工作时,可以避免破坏有用信息。
Similar presentations