《微型计算机原理与接口技术》教案1

更新时间:2024-05-25 01:09:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

第1章 基础知识

1.1 概述

1946年,世界上第一台计算机ENIAC在美国问世以来,计算机技术的发展日新月异,在五十多年的历史中,先后经历了电子管计算机、晶体管计算机、集成电路计算机,到大规模、超大规模集成电路计算机这样四代的更替。目前已有了第五代“非冯·诺依曼”计算机和第六代“神经”计算机的研制计划。

所谓“非冯·诺依曼”计算机,是将现有的计算机系统结构进行改革,把电脑仿真为人脑的结构。每个人的脑体只有900克左右,但它能存储和处理及其大量的信息,并具有分析和综合的能力,这就是人的智能。计算机研究有一个分支,叫人工智能,就是所谓第五代的人工智能计算机。

生物大脑神经网络可看成一个大规模并行处理的、紧密耦合的、能自行重组的计算机网络。神经网络使人能有效地组织和处理信息,对神经网络研究,并从大脑工作的模型中抽取计算机设计的模型,这就是所谓第六代的神经网络计算机。

计算机按其性能、价格、体积、规模不同可分为巨型机、大型机、中型机、小型机、微型机和单片机六类。

其中微型计算机诞生于20世纪70年代。由于其体积小、价格低,在各行各业的得到了广泛的应用。

微型计算机的发展历史是和大规模集成电路的发展密不可分的。1963年、1964年研制出了小规模集成电路SSI(Small Scale Integration)。到60年代后期,在一个几平方毫米大的硅片上,已可集成数千个晶体管,这就出现了大规模集成电路LSI(Large Scale Integration),为微型计算机的核心部件微处理器的生产打下了基础。现代最新型的集成电路已可在单个芯片上集成上千万个晶体管,线宽小于0.13μm,工作频率已超过2GHz。 到目前为止,微型计算机的核心部件微处理器(说明)的发展过程大致可分为六代(参见P.4表1-1):

1.第一代4位或低档8位微处理器(说明“位”的概念) 其发展大约从1971年到1973年。1971年美国Intel公司研制成功世界上第一个微处理器Intel4004,并于次年推出低档8位微处理器Intel8008。

第一代微处理器指令系统较简单,运算能力较弱,速度也较慢,执行一条指令需10~20μS,即0.05MIPS(million instruction per second),软件主要用机器语言(说明)和汇编语言(说明),它主要用于计算器及各种家用电器上。

2.第二代高档8位微处理器

1973年至1978年,各公司相继推出了第二代高档8位微处理器。1973年,美国Intel公司率先推出了Intel8080,这是一个划时代的产品,它是第一个真正实用于微型计算机的微处理器。它的存储器寻址空间(说明)增加到64K字节,并扩充了指令集,指令执行速度达0.5MIPS。软件方面,除使用汇编语言外,还可使用BASIC、FORTRAN等高级语言,后期产品,如以8085A、Z80及MC6502等CPU为核心的具有磁盘和各种外设的微型计算机,还可用简单的操作系统,如CP/M(Control Program/Monitor)。

这个时期推出的微处理器除Intel公司的产品(8080、8085)外,还有Zilog公司的

1

Z80及Motorola公司的M6800等。

3. 第三代16位微处理器

1977年前后,超大规模集成电路(VLSI)研制成功,在一块芯片上可集成上万个晶体管,为研制16位微机创造了条件。1978年,Intel公司率先推出8086,为与原8位机兼容,又同时推出了准16位的微处理器8088。它的内部结构是16位,但外部数据总线是8位,其指令系统与8086完全兼容。以8088芯片为核心的IBMPC及PC/XT等准16位微型计算机很快占领了市场。

在此同时,Zilog及Motorola公司也相继推出了同一级别的产品Z8000及MC68000等。

16位微处理器比8位微处理器集成度提高了一个数量级,功能大大增强。主要表现在以下各个方面:

△数据总线的位数由8位增加到16位,大幅度提高数据处理能力(举例说明)。 △地址总线由16位增加到20位,扩大了寻址范围。

△时钟频率达5~40MHz,基本指令执行时间约0.15μS。系统运算速度大大提高,同时内部结构也作了改进。采用“流水线”结构(简单说明),处理速度明显加快。另外内部通用寄存器增多,减少对存储器访问(说明),且大多数通用寄存器都可作累加器使用。

△扩充了指令系统,指令功能大大加强,寻址方式(说明)也较为丰富。由于指令系统指令数量多,复杂程度高,故这类计算机称为复杂指令系统计算机CISC(Complex Instruction Set Computer).

△可处理多种数据类型。如二进制位、压缩BCD码、非压缩BCD码、字节、字、双字、字串等(说明)。

△中断(说明)功能增强。

△具有构成多微处理器系统能力。 △配有较强的系统软件。

1982年,Intel公司又推出16位高级微处理器80286,它具有多任务系统所必需的任 务转换功能。同年Motorola公司也推出了同类型的MC68010。这两种微处理器的数据总线虽仍是16位的,但地址总线增加到24位,使存储器直接寻址能力达到16MB,在20世纪80年代中、后期及90年代初期,80286成为个人计算机的主流CPU。

4.第四代32位高档微处理器

1985年,Intel公司推出第四代微处理器80386,它是一种与8086向上兼容的超级微处理器,具有32位数据线,32位地址线,存储器直接寻址能力达4GB,其执行速度达3~4MIPS。同时推出的还有Motorola公司的MC68020等产品。32位微处理器无论从结构、功能、应用范围等各个方面看,可以说是小型机的微型化,已接近同时期小型机的水平。

随着大规模集成电路工艺水平的进一步提高,1989年,Intel公司又推出了性能更高的32位微处理器80486,它在芯片上集成120万个晶体管,是80386的4倍。80486时在微处理器80386的基础上集成数字协处理器80387及8KB容量的高速缓冲存储器而构成的。它采用了RISC(Reduction Instruction Set Computer精简指令系统计算机)技术,与RAM进行高速数据交换的突发总线等先进技术。这些新技术的采用,使80486在同等时钟频率下,处理速度要比80386快2到4倍。同期推出的产品还有Motorola公司的MC68030及其后继产品MC68040等。

5. 第五代32位高档微处理器

2

1993年,Intel公司又推出了新的32位微处理器Pentium(奔腾),它集成了330万个晶体管,数据线64位,地址线36位,工作频率为60/66MHz, 处理速度达110MIPS。1994年又推出了第二代Pentium(以P54C代称),工艺更先进,工作频率达90/100 MHz。在体系结构上,Pentium在内核中采用更先进的RISC技术,它汇集了CISC和RISC技术的优点。同时采用超标量结构,拥有两条“流水线”,使之每个时钟周期内最多可执行两条指令。同时内置高性能的浮点运算部件及两个8K字节的超高速的缓冲存储器,使整个微处理器的性能大大提高。

同时推出第五代微处理器的还有IBM、Apple和Motorola三家联盟的PowerPC及AMD公司的K5等产品。

6.第六代Pentium微处理器

1996年,Intel公司推出了Pentium Pro,该微处理器采用了0.35μm的工艺,时钟频率为200MHz,运算速度达200MIPS。

1998年到2001年,Intel公司又先后推出了Pentium Pro的改进型产品PentiumⅡ和PentiumⅢ。CPU的集成度已高达1千万个晶体管,时钟频率达1GHz以上,其他公司类似产品还有AMD公司的K7等产品。

近年来,市场上已推出PentiumⅣ系列,其CPU集成度已达2千5百万个晶体管,工作频率达到2GHz。

1.2 计算机中的数制

日常生活中,人们惯于用十进制来计数,但计算机只能识别由“0”和“1”构成的二进制代码(说明为什么),而用二进制表示的数又显得冗长,为阅读和书写方便,往往采用十六进制数。为此,首先要掌握这三种数制及其之间的转换关系。

1.2.1 常用计数制

1.十进制数

1)十进制数中有0~9共十个数字符号。 2)逢10进1(10为基数)。

3)各位数的“权”为10。 例:(3256.87)10 = 3×103+2×102+5×101+6×100+8×10-1+7×10-2=3256.87 即:(D)10 = Dn-1×10n-1+Dn-2×10n-2+?+D1×101+D0×100+D-1×10-1+?+D-m×10-m

n?1i

=

?Di??mi?10

i式中n表示小数点左边的位数(自0开始),m表示小数点右边的位数(自1开始)。

2.二进制数

1)二进制数中只有0、1两个数字符号。 2)逢2进1 (2为基数)。

3)各位数的“权”为2i。 例:(1010.11)2 = 1×23+0×22+1×21+0×20+1×2-1+1×2-2 = 10.75 即:(B)2 = Bn-1×2n-1+Bn-2×2n-2+?+B1×21+B0×20+B-1×2-1+?+B-m×2-m

3

n?1=

?Bi??mii?2

3.十六进制数

1)十六进制数共有十六个数字符号0~9及A~F。 2)逢16进1。

3)各位数的“权”为16i.

例:(2AE.4)16 = 2×16+10×16+14×16+4×16 = 586.25

n-1n-210-1-m

即:(H)10 = Hn-1×16+Hn-2×16+?+H1×16+H0×16+H-1×16+?+H-m×16

n?12

1

0

-1

=

?Hi??mii?16

4.其他进制数(略)

需要指出的是,除了用基数作下标来表示数的进制外,还可再数的后面加上字母B(Binary)、H(Hexadecimal)、D(Decimal)来分别表示二进制数、十六进制数和十进制数,而十进制数后面的D往往可以省略。

1.2.2各种数制之间的转换

由于人们习惯使用十进制数,计算机只能识别二进制数,而人们编程又多采用十六进制数,因此必然会产生不同进位制之间的转换问题。

1.非十进制数转换为十进制数

按“权”展开,例见P7例1-5。 2.十进制数转换为非十进制数 (1)十进制数转换为二进制数 整数部分与小数部分分别转换。 整数部分:“除2取余”。 小数部分:“乘2取整”。

例:将十进制数112.25转换为二进制数。 整数部分:

2 112 2 56 0 2 28 0 2 14 0 2 7 0 2 3 1 2 1 1 0 1

小数部分:

0.25 × 2

0.5 0 0.5 × 2

1.0 1

4

从而得:(112.25)10 = (1110000.01)2 或写作:112.25 = 1110000.01B (2)十进制数转换为十六进制数 同样整数部分与小数部分分别转换。 整数部分:“除16取余”。

小数部分:“乘16取整”。

例:将十进制数301.6875转换为十六进制数。 整数部分:

16 301 16 18 D 16 1 2 0 1

小数部分:

0.6875

× 16 4.1250

+ 6.875

11.0000 B

从而得到(301.6875)10 = (12D.B)16

或写作:301.6875 = 12D.BH

需要指出的是,如要将十进制数转换为二进制数,为避免除2次数过多出现差错,往往先将之变为十六进制数,后再变为二进制数,而后者的转换是非常方便的。

3.二进制数与十六进制数之间的转换 (1)二进制数转换为十六进制数

“四位一撇”法:

例:将二进制数110100110.101101B转换为十六进制数 1,1010,0110.1011,01 = 1A6.B4H(注意:首尾要补零) (2)十六进制数转换为二进制数 “以四代一”法:

例:将十六进制数2A8F.6DH转换为二进制数

2A8F.6DH = 10,1010,1000,1111.0110,1101B

1.3 无符号二进制数的算术运算和逻辑运算

1.3.1 二进制数的算术运算(略)

1.3.2 无符号数的表示范围

1.无符号二进制数的表示范围

8位二进制数的表示范围为OOH~FFH(0~255),16位二进制数的表示范围为0000H~FFFFH(0~65535),一个n位的无符号数,它可表示数的范围为0~2n-1。

如运算结果超出数的表示范围,将产生溢出,结果将出错。例见P.11例1-13。 2.无符号二进制数的溢出判断

5

两个无符号数相加(或相减),如最高位有进位(或错位),则产生溢出。这在计算机运算中很容易以C标志来进行判断(以后展开讲)。

1.3.3 二进制数的逻辑运算

逻辑运算包括“与”、“或”、“非”及“异或”四种运算,与算术运算不同的是它对二进制数按位进行操作,因之不存在进位(或借位)问题。 1.“与”运算

“与”运算的规则为“见0为0,见1不变”。例见P.12例1-14。

2.“或”运算

“或”运算的规则为“见0不变,见1为1,”。例见P.12例1-15。

3.“非”运算

“非”运算的规则为按位取反。例见P.12例1-16。

4.“异或”运算

“异或”运算的规则为“同则为0,异则为1”。 例见P.12例1-17。

1.3.4 基本逻辑门及常用逻辑部件(略)

1.4 带符号二进制数的表示及运算

计算机只能识别“0”和“1”这两个代码,因之,在计算机中,数的正负号也只能由“0”和“1”来表示。通常规定,一个有符号数的最高位代表符号,该位为0代表正,该位为1代表负。

习惯上把符号数值化了的数,称为机器数,而把其原来的数值称为真值。

1.4.1 带符号数的表示方法

在计算机中,带符号的数有三种表示方法,即原码、补码和反码。不管是哪一种表示方法,其最高位均为符号位,用“0”表示正数,用“1”表示负数。下面以8位二进制数位例加以说明。

1.原码

一个带符号数的原码记作[X]原。在原码表示法中,数值部分为该数的绝对值,以符号位表示该数的正负。

例见P.16例1-19。

需要指出的是在原码表示法中,0的原码有两种不同的表示形式,即+0和-0。 [+0]原 = 00000000

[-0]原 = 10000000

原码表示法的优点是简单,易于理解。它的缺点是不便于运算(举例说明)。

2.反码

一个带符号数的反码记作[X]反。在反码表示法中,对于正数,数值部分即为该数的原

6

值;而对于负数,其数值部分为该数的绝对值各位取反。同样,以符号位表示该数的正负。

例见P.17例1-20。

在反码表示法中,0的反码也有两种表示形式: [+0]反 = 00000000 [-0]反 = 11111111

由上可知,由于在原码和反码表示法中,数值0的表示法不是唯一的,必然对运算带来不利(缺乏唯一性)。为此,引入补码的概念。

3.补码

一个带符号数的补码记作[X]补。在补码表示法中,对于正数,其数值部分仍为该数的原值;对于负数,其数值部分为该数的绝对值各位取反再加1。也仍以符号位表示该数的正负。(即[X]补 = [X]反+1)。

例见P.18例1-21。

特别需要指出的是,与原码和反码不同,在补码表示法中,0的表示法是唯一的。 [+0]补 = [+0]原 = [+0]反 = 00000000

[-0]补 = [-0]反+1 = 11111111+1 = 00000000

∴[+0]补 = [-0]补 = 00000000

另需指出的是,对于机器数,10000000在补码表示法中定义为-128(同样,对于16位的机器数1000000000000000,在补码表示法中定义为-32768)。

1.4.2 真值与补码之间的转换

要把一个用补码表示的二进制数转换为带符号的二进制数,可分两种情况来处理。

如该数为正数,则除符号位外,其余7位即是此数的二进制数值,转换很为简单。 例:已知[X]补 = 00101110,求X的真值。 解:X = 00101110 = +46

如该数为负数,则可将该数补码数值部分再求一次补,即可得到该数绝对值。 例:已知[X]补 = 11010010,求X的真值。

X=11010010+1 = 00101110

∴X = -46

为什么要引进补码的概念呢?这是因为引进补码后,在计算机运算时,可将减法运算演变为加法运算。

例:求Y = 99-58 = 99+(-58)= 41

[99]补 = 01100011

[-58]补 = 11000110 00111010(58的二进制代码)

求反:11000101

求补:11000110

01100011 +11000110 1 00101001 即为[41]

由于计算机中求反很易实现,故上述运算过程在计算机上较简单。而众所周知,对于二进制数的算术运算,乘法运算可转换为左移和加法运算,而除法运算可转换为右移和减法运算。由此得到,在计算机中,加、减、乘、除,均可由加法和移位两种操作得以实现,这就是引入补码的最终目的!

7

1.4.3 补码的运算

补码运算具有如下规律: 1)[X+Y]补 = [X]补+[Y]补 2)[X-Y]补 = [X]补-[Y]补

3)[X-Y]补 = [X]补+[-Y]补

这里[-Y]补称为对补码数[Y]补的变补。变补规则为对[Y]补的各位(包括字符位)按位..取反加1,结果即为[-Y]补(当然也可直接对-Y求补码,结果相同)。

例见P.19例1-24及例1-25。

需要强调的是上述三个公式的成立是有条件的。其条件是:式中X、Y、-Y、X+Y及X-Y都必须在补码的表示范围内,倘若超出补码的表示范围,等式便不再成立,详见下节。

1.4.4 带符号数运算时的溢出问题

1.带符号数的表示范围

(1)8位二进制数,原码、反码和补码的表示范围

△原码 11111111~01111111(-127~+127) △反码 10000000~01111111(-127~+127) △补码 10000000~01111111(-128~+127)(数的状态和数的个数对应) 当运算结果超出上述范围时就会产生溢出。 (2)16位二进制数,原码、反码和补码的表示范围 △原码 FFFFH~7FFFH(-32767~+32767) △反码 8000H~7FFFH(-32767~+32767) △补码 8000H~7FFFH(-32768~+32767) 同样,当运算结果超出上述范围时就会产生溢出。

2.带符号数运算时的溢出判断

带符号数运算时的溢出判断的规则是:

在运算中,当最高位和次高位同有进位或同无进位,则无溢出。如两者一个有进位,一个无进位,则有溢出。

例见P.21例1-26、例1-27及P22例1-28、1-29。

1.5 二进制编码

计算机除处理数值领域的问题外,还被大量用于处理非数值领域的问题,这要求计算机能识别文字、字符和各种符号(例见P.22)。而所有字符符号及十进制数都必须转换为二进制代码才能为计算机所识别。

1.二进制编码的十进制数(BCD码数)

用二进制编码来表示十进制简称BCD码(Binary Coded Decimal)。BCD码的编码方式有多种,最常用的是8421码。

(1)8421码

BCD码与二进制码的对应关系如P.23表1-9所示。其特点为: ①用4位二进制数表示1位十进制数。 ②BCD码是十进制数,逢10进1。

8

(2)BCD码与十进制数、二进制数的转换。

十进制数用BCD码表示十分简单,只要对十进制数每位按表1-9进行转换即可。 例见P.23例1-30。

显而易见,如要将BCD码转换为其对应的十进制数也十分简单,只要将每4位二进制代码变成其对应的十进制数即可。

BCD码与二进制数之间的变化要稍麻烦些,一般要以十进制数为桥梁进行转换。 例见P23例1-31及例1-32。

为避免与二进制数混淆,BCD码书写时通常将每位BCD码(4位二进制码)写成一组,中间留一空格,且加下标BCD。

(3)计算机中BCD码的存储方式

在存储单元为8位的情况下,BCD码有两种表示方法。一种是压缩BCD码表示方法,例10010010表示十进制数92(即一个字节表示2个十进制数),另一种表示方法为非压缩BCD码(也称扩展BCD码),同样是十进制数92,用非压缩BCD码就表示为:0000100100000010。

2.字符的编码

为能让计算机识别,各种字符也必须用特定的二进制代码编写,目前在计算机中普遍采用的是ASCII码(American Standard Code for Information Interchange美国标准信息交换码)。

ASCII字符编码表见附录A,它是用7位二进制代码来表示128个字符和符号。 一般规定一个ASCII码存放在字节的低7位,字节的最高位在通信中常用作奇偶校验位(简单说明什么是奇偶校验)。

1.6 常用术语解释

1.6.1 数据单位

1.位(bit)、兆位(Mb)、千兆位(Gb)和兆兆位(Tb)

位是计算机处理的最小数据单位,它只有“0”、“1”两种状态。Bit通常缩写为b。

20

Mb(Megabit)代表1024×1024位,也即2位。 Gb(Gigabit)代表1024Mb,也即230位。 Tb(Terabit)代表1024Gb,也即2位。

2.字节(byte)、KB、MB、GB和TB 1个字节包含8个二进制位,Byte通常缩写为B。字节是计算机中存储容量的基本单位。 在计算机中,1K为1024,即210,所以1KB = 1024Byte。以此类推,1MB = 1024KB,1GB = 1024MB,1TB = 1024GB。

3.字(word)

字在不同场合有不同意义。它是数据总线的宽度。一个字代表两个字节,在8086系列 的机型中为16位。

40

1.6.2 计算机通信速率单位(略,待到有关章节再讲)

1.6.3 兼容性

9

Δ系统兼容:若在一个系统上开发的硬件和软件能在另一个系统上成功运行,则称两个系统兼容。

Δ向上兼容:若兼容性是旧系统到新系统的单向发展,则称为向上兼容(举例说明)。

10

第2章 微型计算机基础

2.1 微型计算机基本结构

微型计算机是计算机的一种。它体积小,重量轻,一般供个人使用。所以通常称个人计算机(Personal Computer PC)。微型计算机由硬件系统和软件系统两大部分组成,称之为微型计算机系统,其组成如P.27图2-1所示(作解释)。

2.2.1 微型计算机的概念结构

各种微型计算机从概念结构上来说都由运算器、控制器、存储器和输入输出设备等部分组成。这些组成部分往往合并和分解为若干个功能模块,分别由不同的部件予以实现。 从大的功能部件来看,微型计算机的硬件主要由CPU、存储器、I/O接口和I/O设备组成,各部分之间通过数据总线(data bus DB)、地址总线(address bus AB)、控制总线(control bus CB)连接在一起。

DB、AB、CB这三总线通常为系统总线,它是计算机各部件间传送信息的公共通道。这种总线结构形式的优点是设计简单、灵活性强、易于扩展、便于故障诊断和维修。故所有微型计算机系统都采用了总线结构形式。P.28图2-2为微型计算机的结构框图。

1.硬件系统

1)微处理器(或称中央处理单元,CPU)

CPU是微型计算机的核心部件,是整个系统的运算和控制中心。微机性能、档次不同主要取决于CPU。各种CPU均有其特定的指令系统。然而无论哪种CPU,其内部组成总是大同小异的,一般都有运算器、控制器和寄存器三个主要部分。其典型结构如P.29图2-3所示,下面分别对各部分加以说明:

Δ运算器(又称算术逻辑单元Arithmetic and Logic Unit ALU):它是以加法器为基础,辅之以移位寄存器及相应的控制逻辑组合而成的电路,在控制信号作用下,完成各种算术运算和逻辑运算。 Δ控制器:一般由指令寄存器(Instruction Register IR)和指令译码器(Instruction Decoder ID)和控制电路组成,是CPU的指挥控制中心。它从存储器中依次取出程序的各条指令,并根据指令要求向微机各部分发出相应控制信号,使各部分协调工作。

Δ寄存器组:它是CPU内部的若干个存储单元。分为专用寄存器和通用寄存器两种。由于有这些寄存器,CPU在运算时出现中间结果,可暂放在寄存器中,以避免对存储器的频繁访问,而缩短指令执行时间,给编程带来方便。

2)存储器(Memory)

这里所指的存储器是指系统的内存或称主存,是微机的存储和记忆部件,其用途是存放数据和程序。微机的内存一般都由半导体存储器构成。 (1)内存单元的地址和内容

内存由许多单元组成,每个单元存放一组二进制数(例8位二进制数),称为一个字节。一台微机中内存单元的总量称为该机的内存容量,单位为字节。为区别个不同的内存单元,往往要对内存单元进行编址。如8086CPU的内存编址从00000H开始,一直到FFFFFH为止,

11

共2个存储单元。每个存储单元有唯一的地址。CPU如要访问其内存单元,可通过指定该内存地址予以实现。

内存单元中存放的信息称为内存单元的内容,它与内存地址在形式上都是一个二进制数,但在本质是两个完全不同的概念。详见P.29图2-4说明。

(2)内存的操作 CPU对内存单元的操作有读、写两种。P.30图2-5的(a)、(b)两图分别描述了CPU存储器的读、写操作过程(作解释)。 需要指出的是读操作不会改变被读存储器的内容。这一特点称为非破坏性读出(no destructive read out)。反之,写操作将破坏该存储器的内容。

上述类型存储器即可读出也可写入信息,因此这种存储器称为读写存储器,也称为随机存取存储器。

(3)内存的分类

按工作方式不同,内存可分为两大类,即随机存取存储器(random access memory RAM)和只读存储器(read only memory ROM)。 ROM中的信息只能被CPU读取,而不能由CPU任意写入。但ROM中的信息不象RAM那样在机子断电后会丢失,所以ROM往往被用来存放程序,或各种常数及表格等。ROM内容的写入要使用专用设备。

有关存储器的详细内容将在第五章中具体介绍。 3)输入输出设备和输入输出接口。

输入输出设备(简称I/O设备或外设)是微型计算机重要的组成部分。常用的输入设备有键盘、鼠标、扫描仪等。常用的输出设备有显示器、打印机、绘图仪等。而磁带、磁盘等则既是输入设备,又是输出设备。

由于I/O设备种类繁多,结构原理各不相同。与CPU相比,外设的速度较低,且数据格式和逻辑电平一般也与计算机不能直接兼容。因此,一般来说,微机与I/O设备之间的连接与信息交换不能直接进行,而必须通过一个中间部件作桥梁,该部件称作输入输出接口(简称I/O接口),有时又称为I/O适配器(I/O adapter)。

4)总线(bus)

总线是由一组导线和相关电路组成的,是各种公共信号线的集合,用作微机各部分间转送信息所共同使用的“高速信息公路”。在CPU、存储器和I/O接口之间传输信息的总线称为“系统总线”,它包括数据总线、地址总线和控制总线。

(1)数据总线(data bus DB)

数据总线用来传送数据信息,是双向总线。CPU可通过DB从内存或I/O设备输入数据,也可通过DB向内存或I/O设备输出数据。 (2)地址总线(address bus AB)

地址总线用于传送CPU发出的地址信息,是单向总线。传送地址信息的目的为指明与CPU交换信息的内存或I/O设备的地址。

(3)控制总线(control bus CB)

控制总线用来传送控制信号、时序信息和状态信息等。其中有的是CPU向内存或外设发出信息,也有的是内存或外设向CPU发出的消息。因此,CB中每根线的方向是单向的,但CB作为一个整体来讲是双向的。

2.软件系统

软件包括系统软件和应用软件两大类。

应用软件是用户解决各类实际问题而编制的程序(举例)。

20

12

系统软件包括操作系统(OS)和系统实用程序。

操作系统用于管理计算机的硬件与软件资源,进行任务调度,提供文件管理系统等,还包括各种外设的驱动程序。

系统实用程序包括各种高级语言的翻译/编译程序、汇编程序、数据库系统、文本编辑程序、调试程序,以及许多系统工具程序等。

计算机中程序设计语言分为机器语言、汇编语言和高级语言三种。机器语言程序是计算机能识别和直接执行的二进制代码形式的程序。汇编语言程序是用助记符语言表示的程序,计算机要通过“汇编程序”的翻译才能识别。而高级语言是不依赖于具体机型的程序设计语言(举例),由高级语言编写的程序需经过编译程序和解释程序的翻译才能执行。

文本编辑程序是供输入或修改文本用的程序。

另外在编写程序时,往往还需要几种系统程序,如系统程序库、连接程序和装入程序等。

一般操作系统都有一个通用的系统程序库,程序库中的子程序可供调用(以后要讲到)。把待执行的程序与程序库其他已翻译好的程序连接起来成为一个整体的准备程序称为连接程序。另一种准备程序是把执行的程序加载到内存中,称为装入程序。

上面简单地介绍了计算机的硬件和软件,需要强调的是硬件系统和软件系统是相辅相成的,共同构成微型计算机系统,两者是缺一不可的。现代计算机软硬件发展的趋势是两者统一融合,相互促进,使计算机技术不断发展。

2.1.2 微型计算机的工作过程

微型计算机究竟是如何进行工作的,这是学习微机原理必须探讨的一个重要问题。 1.存储程序计算机

目前,一般的微型计算机都为存储程序计算机。所谓“存储程序”,是指把处理问题的步骤和所需的数据事先送入存储器保存。运行时,由计算机的控制部件逐条取出并执行,从而使计算机能自动连续地进行处理。“存储程序”的设计思想是计算机发展史上的一个里程碑。

(1)程序与指令

所谓指令是控制计算机进行各种操作和运算的命令。

所谓程序是计算机为解决某一具体问题所编制的一系列指令的有序集合(见P.33图2-6)。 机器指令必须满足两个条件:一是指令的形式必须是计算机能够理解的(由此,指令也必须用二进制编码形式表示)。二是指令规定的操作必须是计算机能执行的(每条指令都有相应的电子线路来实现)。每台计算机的指令都有自己的格式和具体含义,但他们都有一个共同点,即指令必须指明要进行何种操作(操作码)以及操作的对象(操作数)。 每台计算机都有其特定的指令系统,指令系统的优势决定了计算机的性能。一台计算机的指令种类是有限的,但在人的精心设计下,可实现信息处理的任务可以无限多,计算机能忠实地按照程序,有条不紊地执行规定的操作,完成预定的任务。

(2)存储程序工作原理

多年来,尽管计算机的体系结构发生了重大变化,性能不断提高,但存储程序控制始终是现代计算机的结构基础。

“存储程序”是指把程序和数据送到具有记忆功能的存储器中保存起来,计算机工作时,只要给出程序中第一条指令的地址,控制器便根据存储器中的指令周而复始地取出指令、分析指令、执行指令,直至指令全部执行完毕为止。

13

2.微型计算机的工作过程

微型计算机的工作过程实际上就是逐条执行指令序列的过程。也就是不断地取指令和执行指令的过程,见P.34图2-7(展开解释)

指令通常包括操作码(operation code)和操作数(operand)两部分。操作码表明计算机进行何种操作,而操作数指明操作对象。它可能给出操作的数的本身或其所在的地址,指令根据操作或其操作对象不同而有单字节、双字节或三字节乃至四字节之分,因此,在执行一条指令时,可能要处理1-4个不等字节数的信息代码。

3.模拟机中存储程序工作的例子

以计算机完成5+8 =?这一个简单的任务为例,说明程序编制及微机内部执行该程序各条指令的具体操作过程(详细介绍P.36~P.39四个操作示意图及执行三条指令的过程)。

2.2 8088/8086微处理器

本节详细介绍8086微处理器系列中的主导产品8086和8088 CPU的硬件结构。由于这两种CPU的差异很小,本节将以8086为主进行介绍(在没有特别指明时所介绍内容对两者均适用)。

2.2.1 8088/8086微处理器概述

8086和8088均属第三代微处理器。8088存储器和外设进行数据传输的外部数据总线宽度为8位,而8086数据总线的宽度为16位,除此而外,两者几乎无差别。

8086/8088都有40个脚的外部引线,均在单一5V电源下工作。

8086/8088在最小配置下仅需4个外围芯片即可构成一个小型的应用系统,如P.40图2-13所示(作解释)。

8086/8088具有最小和最大两种工作模式,将在以后分别介绍。

2.2.2 8088/8086的指令流水线

在程序执行过程中,CPU有规律地重复以下过程:

Δ从存储器取出下一条指令;

Δ如指令需要,从存储器读取数据(操作数); Δ执行指令;

Δ如指令需要,将结果写入存储器。

在8088/8086未问世前,微处理器用串行方式完成上述过程。从8088/8086开始,CPU采用一种新的结构来完成这些工作。8088/8086将上述步骤分配给两个独立的部件,执行单元(execution unit EU)负责执行指令;而总线接口单元(bus interface unit BIU)负责取指令、取操作数和写结果。当这两个单元独立进行工作时,大多数情况下取指操作和执行指令操作可同时并行进行,从而加快了程序的运行速度。P.41图2-14将并行操作和以前的串行操作方式进行了比较。显示出流水线操作的优越性。

由P.41图2-14可知,指令队列操作过程为:EU不断地从指令队列中取出指令并执行。当EU从指令队列中取走指令,指令队列出现空字节时,BIU即自动执行一次取指令周期,从内存中取出后续指令代码放入队列中(到遇到跳转指令时,BIU使指令队列复位,从新的内存地址取指),指令队列的存在使得EU和BIU并行工作,而减少了为取指而等待的时间,提高了CPU的执行效率和运行速度,同时,也减低了对存储器存取速度的要求。

14

需要指出的是8088/8086中指令队列的个数和级数都很少,远远不能与现在各种新型的CPU(如pentium)相提并论,但它首先在微处理器中采用中流水线结构,从而使8088/8086成为CPU发展史上一个里程碑。

2.2.3 8088/8086的功能结构(原2.2.3 8088外部引脚及其功能放在本节后讲)

1.8088/8086的结构

8088与8086的结构极为相似,都是由执行单元EU和总线接口单元BIU两大部分组成,其内部结构框图如图P.46图2-16所示。

执行单元EU负责执行指令,它由算术逻辑单元(运算器)ALU、通用寄存器、标志寄存器FLAGS和EU控制电路组成。工作时,EU不断地从指令队列取出指令代码,后对其译码,产生完成指令所需要的各种控制信息。数据运算在ALU中进行,运算结果的特征保留在标志寄存器FLAGS中。

总线接口单元BIU负责CPU与存储器及I/O接口之间的信息传送。它由段寄存器、指令指针寄存器、指令队列、地址加法器及总线控制逻辑组成。8088的队列长度为4字节,8086的队列长度为6个字节。

当EU从指令队列中取走指令,指令队列出现空字节时,BIU就自动执行一次取指周期,从内存中取出后续指令放入队列中。当EU需要数据时,BIU据EU给出的地址,从指定的内存单元或外设中取数据供EU使用。当运算结束时,BIU将运算结果送入指定的内存单元或外设。当指令队列空时,EU就等待,直到有指令为止。若BIU正在取指时,EU发出访问总线的请求,则必须等BIU取指完毕后,该请求才能响应。当遇到跳转指令时,BIU使指令队列复位,从新的地址取指,并由EU取执行。

指令队列的存在,使EU和BIU并行工作,从而提高CPU的工作效率,加快了整机的运行速度。

BIU中的地址加法器用来产生20位的物理地址,由于8086/8088的寄存器都是16位的(见下说明)无法装载20位的物理地址。为解决此矛盾,8086/8088采用了将地址空间分段的方法,即将220(1MB)的地址空间分成若干个64KB的段,然后用段基址加上段内偏移地址的方法来访问地址为20位的物理存储器。具体方法如P.47图2-17所示。8086/8088规定段的起始地址最低四位总是0,即XXXXOH,这样每个段的基地址只需用16位便可表示(即XXXXOH中的XXXXH),也即段基址实际上是段起始地址的高16位,由于段基址的这一特点,因此将段基址左移4位后和段内偏移量(16位)相加,即可获得物理地址。

2.8088/8086的内部寄存器

8088/8086内部有14个16位寄存器。按其功能分为三大类:第一类是通用寄存器(8个),第二类是段寄存器(4个),第三类是控制寄存器(2个),具体见P.47图2-18。

(1)通用寄存器

通用寄存器包括数据寄存器、地址寄存器和变址寄存器。 ①数据寄存器AX、BX、CX、DX

数据寄存器一般用于存放参与运算的数据或运算的结果。每个数据寄存器都是16位寄存器,但又可将高、低8位分别作为两个独立的8位寄存器使用。其高8位记作AH、BH、CH、DH,低8位记作AL、BL、CL、DL,这种灵活的使用方法给编程带来方便,使之既可处理16位数据,也能处理8位数据。

数据寄存器除作为通用寄存器使用外,还有其各自的习惯用法:

AX(accumulator)为累加器。是最常用的寄存器,用于存放算术逻辑运算中的操作数。另外,所有的I/O指令都通过累加器与外设接口之间传送信息。

15

BX(base)为基址寄存器。常用来存放访问内存时的基地址。

CX(count)为计数寄存器。在循环和串操作专用做计数器。

DX(data)为数据寄存器。在寄存器间接寻址的I/O指令中存放I/O端口地址。 另外,在做双字长乘除法运算时,DX与AX配合,存放一个双字长数(32位),其中DX存放高16位数据,AX存放低16位数据。

②地址指针寄存器SP、BP

SP(stack pointer)为堆栈指针寄存器。它在堆栈操作中存放栈顶偏移地址,永远指向堆栈的栈顶。

BP(base pointer)为基址指针寄存器。一般也常用来存放访问内存时的基地址。但要注意BP是和SS段寄存器配对使用的(而BX通常是和DS段寄存器配对使用的)。

作为通用寄存器,SP和BP也可存放数据,但更经常地用于存放内存单元的偏移地址(两者的默认段寄存器都是SS)。

③变址寄存器SI、DI

SI(source index)为源变址寄存器,DI(destination index)为目标变址寄存器,主要在变址寻址方式中作为索引指针。

(2)段寄存器CS、SS、DS、ES

CS(code segment)为代码段寄存器,SS(stack segment)为堆栈段寄存器,DS(data segment)为数据段寄存器,ES(extra segment)为附加数据段寄存器。段寄存器用于存放段基址,即段起始地址的高16位。

(3)控制寄存器IP、FLAGS

IP(instruction pointer)为指令指针寄存器,用以存放指令的偏移地址。CPU取指总以CS内容为段基址,以IP内容为段内偏移地址。当CPU取走一个指令代码后,IP内容自动加1,指向指令代码的下一个字节。用户程序不能直接访问IP。

FLAGS为标志寄存器或程序状态字(program status word PSW)。它是16位寄存器,但只使用了其中9位。这9位包括6个状态标志,如P.46图2-19所示。

状态标志记录了算术和逻辑运算结果的一些特征,具体如下:

△CF(corny flag)进位标志位。当进行加(减)法运算时,如最高位有进(借)位,则CF = 1,否则CF = 0。

△PF(parity flag)奇偶标志位。当算术或逻辑运算结果中,低中“1”的个数.8.位.为偶数时,PF = 1,为奇数时,PF = 0。

△AF(auxiliary flag)辅助进位标志位。在加(减)法操作中,由低半字节向高半字节进位(或借位)发生时,AF = 1,否则AF = 0。该标志通常用于对BCD码算术运算的结果进行调整(详见3.3.2)。

△ZF(zero flag)零标志位。当运算结果为0时,ZF = 1,否则ZF = 0。

△SF(sign flag)符号标志位。当运算结果的最高位为1时,SF = 1,否则SF = 0。 △OF(overflow flag)溢出标志位。当算术运算结果超出了带符号数的范围,即产生溢出时,OF = 1,否则OF = 0。注意,8位带符号数的范围是-128~+127,16位带符号数的范围是-32768~+32767。

需要强调的是,不同指令执行结果对状态标志位的影响是不相同的,具体将在指令系统中作介绍。

控制标志位用于设置控制条件。控制标志一旦被设置后,便对其后的操作产生控制作用。具体如下:

△TF(trap flag)跟踪标志位(也称陷阱标志位)。当TF = 1时,使CPU处于单步执

行指令的工作方式。这种方式便于对程序进行调试。每执行一条指令后,自动产生

16

一次单步中断,从而使用户能逐条地检查程序执行的结果。

△IF(interrupt-enable flag)中断允许标志位。当IF = 1时,CPU能够响应外部的 可屏蔽中断;当IF = 0时,则不响应外部可屏蔽中断请求。但此标志对外部非屏蔽中断请求,或内部产生的中断不起作用。8086/8088有两条指令STI和CLI专门用于设置和消除IF标志。 △DF(direction flag)方向标志位。DF = 1,使串操作按地址减1方式进行,而DF = 0,使串操作按地址加1方式进行。

2.2.4 8088的外部引脚及其功能

8088和8086 CPU都是具有40个引脚的集成电路芯片,采用双列直插式封装。P.42图2-15是8088的引脚图,8086与之基本相同。8088的许多引脚具有双重定义和功能,采用分时复用方式(解释)工作,即在不同的时刻,这些引脚上的信号是不同的。

8088有最大和最小两种工作模式,通过在MN/MX输入引脚上加上不同的电压来进行选择。当MN/MX= 1时,8088工作在最小模式。此时,所构成的微机中只包括一个微处理器8088,系统总线由8088的引脚直接引出生成,系统所用芯片最少。当MN/MX= 0时,8088工作在最大模式。在此模式下,构成的微机中除有8088 CPU外,还可外接数字协处理器8087,构成多微处理器系统。在最大模式下,系统总线要由8288共同生成(见后详细介绍)。P.42图2-15中括号内的管脚信号用于最大工作模式。

1.最小模式下的引线

最小模式下,8088的引线分为三类。

第一类为数据、地址、状态线,它们包括:

△A16~A19/S3~S6,地址、状态复用引脚,三态输出。在8088 CPU执行指令的过程中,在总线周期的T1时刻,从该4个引脚送出地址的最高4位A16~A19。在T2、T3、T4时刻,这4个引脚送出状态信号S3~S6,在这些状态信息里,S6恒等于0,S5指示中断允许标志位IF的状态,S4、S3组合指示CPU当前正在使用的段寄存器,其编码表参见P.42表2-2。

△A8~A15,地址输出,三态。CPU寻址内存或I/O接口时,从这8个引脚送出地址A8~A15。

△AD0~AD7地址数据分时复用的双向信号线,三态。当ALE = 1时,这些引脚上传输的是地址信号。当DEN= 0时,这些引脚上传输的是数据信号。 第二类为控制线,它们包括:

△IO/M,输入输出端口/存储器控制信号,三态。用来区分当前操作是访问存储器还是访问I/O端口。当IO/M= 1,访问I/O端口。当IO/M= 0,访问存储器。

△WR(write line),写信号输出,三态。当WR= 0时,表示CPU正在对存储器或I/O端口进行写操作。 △DT/R(data transmit/receive),数据传送方向控制信号,三态输出。用于确定数据的传送方向。DT/R= 1,CPU向存储器或I/O端口发送数据;当DT/R= 0时,CPU从存储器或I/O端口接收数据。此信号用于控制总线收发器8286/8287的传送方向(见2.3.4)。 △DEN(data bus enable),数据总线允许信号,三态输出,低电平有效。当DEN= 0,表示总线上有有效数据,它在每次访问内存或I/O端口以及在中断响应期间有效。它常用作数据总线驱动器的片选信号。 △ALE(address latch enable),地址锁存允许信号,三态输出,高电平有效。当ALE = 1时,表示地址线上有有效地址。因此,它常作为控制信号,将A0~A19锁存到地

17

址锁存器。

△RD,读选通信号,三态输出。当RD = 0时,表示CPU正在对存储器或I/O端口进行读操作。

△READY,“准备好”信号输入引脚,高电平有效。接收内存或I/O设备的响应信号。当READY = 1时,表示存储器或I/O设备已准备好,CPU可以进行数据传送。若存储器或I/O设备没准备好,使READY = 0 。CPU在T3周期采样READY信号,若其为低,CPU会自动插入等待周期TW(1个或多个)直至READY变为高电平后,CPU才脱离等待状态,完成数据传送过程。

△INTR,可屏蔽中断请求输入信号,高电平有效。CPU在每条指令的最后一个周期采样该信号,以决定是否进入中断响应周期。该中断请求信号可以软件屏蔽。

△TEST,测试信号输入引脚,低电平有效。当CPU执行WAIT指令时,每隔5个时钟周期对此引脚进行一次测试。若为高电平,CPU继续处于空转状态进行等待,直到引脚变为低电平,CPU才结束等待状态,继续执行下一条指令。

△NMI,非屏蔽中断请求输入信号,上升沿触发。该引脚上的中断请求信号不能用软件

TEST屏蔽,CPU在当前指令结束后立即进入中断过程。

△RESET,系统复位输入信号,高电平有效。为使CPU完成内部复位过程,该信号至少在4个时钟周期内保持有效。复位后,CPU内部寄存器状态如P.44表2-3所示(作说明)。当RESET返回低电平后,CPU即重新启动。 △INTA(interrupt acknowledge),中断响应信号输出,低电平有效。它是CPU对中断请求信号INTR的响应。在响应过程中,CPU在INTA引脚上连续送出两个负脉冲,用作外部中断源中断向量的读选通信号。

△HOLD(hold)总线保持请求信号输入,高电平有效。当HOLD = 1,表示某一总线主控设备(如DMA控制器)要占用系统总线。通过此引脚向CPU提出请求。 △HLDA(hold acknowledge),总线保持响应信号输出,高电平有效。这是CPU对HOLD请求的响应信号。当CPU收到有效的HOLD信号后,就会对其作出响应。此时,CPU将停止执行程序,使其数据、地址、控制总线处于高阻状态。同时,由此引脚输出一个有效的HLDA,表示CPU已放弃对总线的控制权。当CPU检测到HOLD变为低电平后,就立即使HLDA变低,CPU收回总线控制权,继续执行其程序。

△SS0,系统状态信号输出。它与IO/M和DT/R信号决定了最小工作模式下,当前总线周期的状态。三者组合所表示的微处理器操作状态见P.44表2-4(解释)。 △CLK,时钟信号输入引脚。8088的标准时钟频率为4.77MHz,时钟的占空比为33%。 第三类为电源线,只有2根线: △VCC,5V电源输入引脚。 △GND,地线。

2.最大模式下的引线

当MN/MX引脚为低电平时,8088工作在最大模式之下。此时P.42图2-15引脚图中除带括号的引线外,其他引线作用与最小模式完全相同。下说明带括号的引线:

△S2、S1、S0(status),总线周期状态信号输出,三态。这三个信号连接到总线控制器8288的输入端,8288对之译码后可产生系统总线所需的各种控制信号。S2、S1、S0的不同组合其对应的操作状态见P.45表2-5(解释)。

△RQ/GT1,RQ/GT0(request/grant),总线请求/总线响应信号。两个引脚均具有双向功能。既为总线请求输入,也为响应输出。RQ/GT0比RQ/GT1具有更高的优先权。

18

该两个引脚的功能类似于最小工作模式下的HOLD和HLDA信号。决定CPU是否控制系统总线。

△LOCK,总线封锁信号输出。低电平有效。该信号有效时,CPU锁定总线,不允许其他总线控制设备申请使用系统总线。LOCK信号由前缀指令“LOCK”产生,LOCK指令后面一条指令执行完后,LOCK信号即失效。

△QS1,QS0(queue status),指令队列状态输出。根据该状态信号,可了解指令队列的操作状态。QS1 ,QS0的编码如P.45表2-6所示(解释)。

△HIGH,在最大模式下始终为高电平输出。

此外,在最大模式下,RD不再使用。

2.2.5 8088/8086的存储器组织

1.物理地址和逻辑地址

8088/8086有20条地址线,可寻址的最大内存容量为1MB(2),其中每一个内存单元都有一个20位的地址,称为内存单元的物理地址。前已介绍,8088/8086内部寄存器都只有16位,而访问内存往往会通过寄存器间接寻址。显然,如不采取特殊措施,是无法访问1MB的存储空间的。8088/8086采用了将地址空间分段的方法来解决此问题,即将1MB的存储器空间分为若干个64KB的段,然后用段基地加上段内偏移来得到存储器的物理地址,以实现访问物理存储器。

段基址和段内偏移(偏移地址)又称为逻辑地址。通常写为XXXXH:YYYYH形式。其中XXXXH是段基址,YYYYH是偏移地址。物理地址和逻辑地址之间的关系为:

物理地址 = 段基址×16 + 段内偏移(偏移地址)

例:逻辑地址为3A00H:12FBH,对应的物理地址是3B2FBH。

由于8088/8086CPU中有4个段寄存器,所以,可同时访问4个存储段。段与段之间可以重合、重叠、紧密连接和间隔分开(画图说明)。

分段寻址的好处是允许程序在存储器内重定位(浮动)。可重定位程序是一个不加修改就可以在任何存储区域中运行的程序,只要程序中不使用绝对地址访问存储器,就可把一个程序作为一个整体移到一个新的区域。

在DOS中,程序载入到内存时由操作系统来指定段存储器的内容,以实现持续的重定位。

2.段寄存器的使用

段寄存器的设立不仅使8088存储空间能扩大到1MB,而且为信息按其特征分段存储带来了方便。

在存储器中,信号按特征可分为程序代码、数据、堆栈等。程序段用来存放程序的指令代码;数据段用来存放数据;堆栈用来传送参数,保存数据和状态信息。有时某种类型的段还可能有多个,通过修改段寄存器内容,可将这些段设置在存储器的任何位置上,这些段可相互对立,也可部分或完全重叠。

8088/8086对不同的访问内存类型所使用的段寄存器和相应的偏移地址的来源有一些具体的约定,详见P.50表2-7(作解释)。

根据表2-7,可知:

·访问存储器时,其段地址可由“默认”段寄存器提供,也可由指定的段寄存器提供。 ·当指令中没有“指定”使用一个段寄存器时,就由“默认”的段寄存器来提供访问内存的段地址。大多数情况下,都用“默认”段寄存器。

·1、2、4这三种类型的内存访问只能用“默认”段寄存器。3、5、6这三种类型的内

20

19

存访问,允许在指令中指定使用另外的段寄存器,使之可灵活地访问不同的内存段。 ·DS、ES和SS的段基地设置可用传送指令完成,但用户程序中不允许设置CS,CS一般由操作系统进行设置。另外宏汇编语言中的伪指令ASSUME及JMP、CALL、RET、INT和IRET等指令可改变和影响CS的内容(以后会讲到)。

·更改段寄存器的内容意味着内存段的移动。这意味着无论是程序段、数据段,还是堆栈段都可以超出64KB的容量,都可以用重新设置段寄存器内容的方法来扩大段,且各内存段都可在这个存储空间中浮动。

·表中前四类内存操作,其偏移地址均由一个16位的指针寄存器(IP、SP)或变址寄存器(SI、DI)提供,而后两类内存操作,则须根据不同的寻址方式来计算偏移地址。

2.2.6 8088/8086的工作时序

微处理器是按照一定的时序来工作的。一条指令的执行需要若干个总线周期,而一个总线周期又由若干个时钟周期构成。

微处理器在运行过程中是按照一个统一的时钟一步一步地执行每一个操作的。每个时钟脉冲的持续时间称为一个时钟周期。显然,时钟周期越短,CPU执行的速度就越快。 在8088 CPU中,CPU与内存、接口都通过总线来进行通信,这种通过总线来进行读、写的过程称为一个总线周期。一个总线周期将包括多个时钟周期。典型的总线周期如P.51图2-20所示(解释)。

8088在最小工作模式下的时序(最大工作模式下,大致相同)简单介绍如下:

8088读-总线周期和写-总线周期时序图分别入P.52图2-21和图2-22所示(具体分析)。

需要指出的是:在某些情况下,当内存和接口的速度较慢,使得在4个时钟周期里不能完成读、写操作。此时,可通过时钟产生器8284(见P.65图2-32)产生一个低电平信号送到8088的READY端,8088 CPU在每个总线周期的T3开始处都要检测READY的状态。若READY为低电平,则CPU不执行T4,而是在T3之后插入一个等待时钟周期TW(图中未画出)。以等待存储器或I/O端口完成读、写操作(在TW周期中还不断检测READY状态),直到某个TW开始时,READY已变为高电平,才执行T4时钟周期,以达到可靠地读写内存或I/O端口的目的。

CPU的读或写,是在T4开始时刻,也即在RD或WR信号的后沿(即上升沿)进行的,这时数据线上的数据已达稳定状态,以保证读写的有效进行。

2.3 系统总线

2.3.1 概述

微型计算机自诞生以来一直采用总线结构。CPU通过总线读取指令,并实现与内存和外设交换信息。在CPU、内存与外设性能确定的情况下,总线通信的速度是制约计算机整体性能的关键。

在计算机三十多年的发展过程中,总线技术之所以能得到迅速发展是由于采用总线结构后,在系统设计、生产、使用和维护上有很多优越性,概括起来有以下几个方面:

·便于采用模块结构设计方法,简化系统设计; ·各厂商便于生产与之兼容的硬件板卡和软件; ·便于系统的扩充与升级;

20

·便于故障诊断和维修。

总线是一组信号线的集合,是计算机系统各部件之间传输数据、地址、控制信息的公共通路。它由一组导线和相关的控制驱动电路组成。在微型计算机系统中常把系统总线看成一个独立部件。

1.总线的分类

(1)按相对于CPU的位置划分,可分为片内总线和片外总线。

在CPU内部,算术逻辑部件ALU、寄存器、控制部件及地址形成部件之间传输信息所用的总线称为片内总线;而通常所说的总线则是指片外总线,是CPU与内存和I/O接口之间进行通信的通路。片内总线可称为内部总线或内总线(internal bus),而把片外总线称为外部总线或外总线(external bus)。

(2)按总线的层次结构分,可分为CPU总线、系统总线和外设总线。

CPU总线包括数据线、地址线、控制线,一般是指从CPU引脚上引出的连接线,用来实现与其他芯片之间的连接。

系统总线也称为I/O通道总线,也同样包括数据线、地址线和控制线,用来与存储器和扩充插槽上的各种扩展板卡相连接。系统总线有多种标准(见下介绍),以实用于各种系统。CPU总线一般要通过专用的控制电路在空间上、时间上进行重组,才能转换成系统总线。 外设总线是指计算机主机与外部设备接口的总线,实际上是一种外设的接口标准。目前在微机上流行的接口标准有:IDE(integrated disk electronics)、SCSI(small computer system interface)以及USB(universal serial bus通用串行总线)、IEEE(美国电气与电子工程师协会)1394四种。前两者主要用作硬盘、光驱等设备接口,后两种新型的外设总线可以用来连接多种外部设备。

2.系统总线

微型计算机上的系统总线有ISA、MCA、EISA、PCI、AGP等多种标准。

ISA(industry standard architecture)工业标准线,是美国IBM公司为推出PC/AT微机而制订的一种总线标准,也称AT总线。

MCA(micro channel architecture)微通道总线结构,是IBM公司专为其PS/2系统开发的总线标准(未有效推广)。

EISA(extended industry standard architecture)扩充工业标准线,是在ISA总线基础上为32位CPU设计的。

PCI(peripheral component interconnect)外设互连总线,是Intel公司联合IBM、DEC、Apple、Compaq、Motorola等百余家PC工业界主要公司,于1992年提出的一种高性能的32/64位标准总线。

目前,微机系统中最常见的只有ISA和PCI两种,而前者正逐步淘汰,使PCI总线几乎独占鳌头。

3.单总线结构和多总线结构(简讲)

2.3.2 总线技术(略讲)

2.3.3 常见系统总线简介

2.3.4 8088系统总线

1.最小模式下的系统总线

21

最小模式下(MN/MX引脚接高电平),CPU仅支持少量设备组成的单处理器系统,系统总线构成如P.65图2-32所示。

?20条地址线,用3片8282(或用74LS245)锁存器构成。

?8条双向的数据线,用1片8286(或用74LS245)双向总线驱动器构成。

?CPU本身产生全部总线控制信号(DT/R、DEN、ALE和IO/M)和命令输出信号(DR、 、INTA)并提供请求访问总线的控制信号(HOLD、HLDA),以满足总线主控设备(如8257DMA控制器等)的总线保持请求。

WR上述最小模式下的系统总线,在实际应用中,还应考虑以下两个问题:

(1)若8088 CPU控制总线的驱动能力不够,可加上总线驱动器74LS244进行驱动。 (2)因没对系统总线形成器件(8288、8286)作进一步控制,系统总线尚不能进DMA传送。

2.IBM PC的系统总线和最大模式下的系统总线

在最大模式(MN/MX引脚接低电平)下,增加一个8288总线控制器,就使CPU能支持系统总线上的多个处理器,P.66图2-33位最大模式的组成框图。

在最大模式下,由总线控制器提供所有总线控制信号和命令。

·CPU的部分引脚进行了重新定义(如S2、S1、S0),以支持多处理器工作方式。 ·8288总线控制器使用CPU S2、S1、S0三个引脚输出的状态信号来产生总线周期所需的全部控制和命令信号(参见P.45表2-5,并作解释)。 ·地址总线和数据总线仍分别由三个8288地址锁存器,及一个8286双向总线驱动器构成。 ·当系统总线形成之后,内存及各接口就可以直接与系统总线相连,从而构成所需的微型计算机系统(如IBM PC)。 ·三总线归纳如下: 地址信号线:A0~A19 数据信号线:D0~D7

控制信号线:MEMR、MEMW、IOR、IRW。

在图2-33系统中仍未解决DMA传送问题,解决方案总的原则是,在进行DMA传送时, 一定要保证总线形成电路所有输出信号都呈高阻状态,即让CPU放弃对总线的控制权。

2.4 新型CPU简介(暂略)

22

第3章 指令系统及汇编语言程序设计

本章以8088/8086为例,介绍微型计算机的指令系统,之所以采用8088/8086的指令系统作范例有以下几个方面的原因:

·指令的兼容性。8088/8086的指令系统是所有80X86系列CPU指令系统的基础,80286、80386,乃至pentium等新型CPU指令系统都是在此基础上进行扩充。用8088/8086指令系统编写的程序可毫无改动地在80286、80386、80486及pentium等CPU上运行。

·应用的广泛性。在现有的微机系统中,绝大多数都是80X86系列的CPU。 ·资料易于寻找。给应用开发及教学带来方便。

3.1 概 述

控制计算机完成指定操作的命令称为指令。不同的计算机具有各自不同的指令,其所有指令的集合,即为该计算机的指令系统。

指令系统不仅定义了一台计算机的指令集,而且还定义了使用这些指令的规则。为能使用汇编语言编写程序,必须对机器的指令系统非常熟悉。

8086和8088的指令系统是相同的,为叙述方便,通称为8086指令系统。 8086 CPU的指令系统共包括92种基本指令,按其功能分为六大类: ·数据传送类; ·算术运算类;

·逻辑运算和移位类; ·串操作类; ·控制转移类; ·处理器控制类。

P.94表3-1给出了上述六大类中常用指令的助记符,有关指令的格式、执行的操作及其功能将在本章第3节中详细介绍。

3.1.1 指令的基本构成

8086指令的长度在1~7个字节之间,包括操作码(指令码)和操作数。操作码确定指令进行何种操作,一般占1~2个字节。操作数确定操作的对象,一条指令的操作数最多有两个。一条指令的长度除与操作码有关外,还与指令中操作数的多少及操作数的类型有关。操作数越多,类型越复杂,其指令长度也就越长。

8086指令的一般格式如下:

操作码 [操作数],[操作数]

操作码用便于记忆的助记符来表示,操作数可以是双操作数(源操作数和目标操作数),也可以是单操作数,有个别指令没有操作数或隐含操作数。8088/8086指令系统的操作数有立即操作数、寄存器操作数和存储器操作数三类。

1.立即操作数

·所谓立即数是指具有固定数值的操作数(即常数)。 ·立即数可以是字节(8位)或字(16位),当其分别代表无符号数和带符号数时,各自取值范围如P.95表3-2所示。

23

·在指令中,立即数操作数只能作为源操作数,而不能作为目标操作数。

2.寄存器操作数

·寄存器操作数存放在8086 CPU的8个通用寄存器或段寄存器中,即可作为源操作数也可用作目标操作数。 ·通用寄存器中的AX、BX、CX、DX可作为4个16位寄存器用来存放16位操作数,也可作为8个8位寄存器AH、AL、BH、BL、CH、CL、DH、DL用来作为字节操作数。而SI、DI、BP、SP只能存放字操作数。

·段寄存器用来存放当前操作数的段基地址。在传送数据时,段寄存器可作为源操作数或目标操作数(注意代码段操作数一般不作为目标操作数,虽允许这样做)。另需特别注意:不允许将立即数直接送段寄存器,也不允许在两个段寄存器间直接传送数据。

·仅有个别指令将标志寄存器FLAGS作为指令的操作数。

3.存储器操作数

·存储器操作数可以是字节、字或双字,分别放在1个、2个或4个存储单元中。 ·存储器操作数既可作为源操作数,也可作为目标操作数。但一般说来,不允许源操作数和目标操作数同时为存储器操作数。

·存储单元有20位的物理地址,有段基地址和偏移地址两部分构成。所以要找到一个存储器操作数,必须首先确定操作数所在的段。一般来说,在没有特别指定的情况下,CPU采用默认的段寄存器来确定操作数所在的段。段寄存器使用的一些基本约定如P.96表3-3所示(作解释,特别说明“段超越”)。

·各存储器段往往用指向它的段寄存器来表示。如一个数据段基址由DS来指明,这个段可称为DS段。倘若段基址既在DS中,又在ES中,则该段既可称为DS段,也可称为ES段。 ·存储器操作数的偏移地址可通过不同寻址方式由指令给出。

3.1.2 指令的执行时间

了解指令的执行时间在一些特定场合(如延时、中断、控制等)是十分重要的。 一条指令的执行时间包括取指令、取操作数、执行指令及传送结果等几个部分,单位用时钟周期数来表示。

不同指令执行时间有较大差别。P.96~97表3-4列出了部分常用指令的执行时间及访问存储器的次数(作说明)。

存取操作数的时间与采用的寻址方式有关。寻访寄存器操作数需要时间最短,立即操作数次之,存储器操作数指令的执行速度最慢(例见P.98)。这是因为前两者不需访问内存,因此执行速度很快,而访问存储器要由BIU计算出所在单元的20位物理地址,然而再执行有关读写操作,所以所需时间大大增加。为寻访存储器操作数,在计算物理地址时,先需计算偏移地址,各种寻址方式,计算偏移地址所花的时间,如P.98表3-5所示。若有段超越的情况,则需再加2个时钟周期。

3.2 8086的寻址方式

所谓寻址方式,主要是指获得操作数所在地址的方法。寻址方式一般是指针队员操作

24

数而言的。

在8088/8086系统中,寻址分为两种不同的类型。一类是寻找操作数的地址,另一类是寻找要执行的下一条指令的地址。后者主要在程序转移或子程序调用中发生,待以后介绍。本节主要讨论针对操作数的8种寻址方式。

3.2.1 立即寻址(immediate addressing)

立即寻址方式中,源操作数是一个立即数。它作为指令的一部分紧跟在操作码之后,存放在内存的代码段中。这里的立即数可以是8位或16位的整数。若为16位数,存放于两个单元,规定低8位在低地址单元存放。

例见P.99例3-1(详细说明)。

3.2.2 直接寻址(direct addressing)

直接寻址方式中,指令的操作码后面直接给出操作数的16位偏移地址。该地址与指令的操作码一起存放在内存的代码段,也是低8位在前,高8位在后。操作数本身若非使用段超越,默认存放在数据段DS中。

例见P 99例3-2(详细说明)。

需要注意,为使直接寻址与立即寻址相区别,指令系统规定偏移地址必须用括号括起来。

若操作数不是存放在DS段,则在指令中要用段超越符号加以说明。例见P.100例3-3。 在汇编语言中,可以一个符号来表示操作数的偏移地址,通常称为符号地址。例见P.100用BUFFER代替偏移地址1200H,但BUFFER必须在程序的开始处予以定义(详见第4章)。

3.2.3 寄存器寻址(register addressing)

寄存器寻址方式中,操作数在CPU内部的寄存器。它们可以是数据寄存器(8位或16位),也可以是地址指针(SP、BP),变址寄存器(SI、DI)或段寄存器。

例见P.100例3-4。

3.2.4 寄存器间接寻址(register indirect addressing)

与寄存器寻址方式不同,在寄存器间接寻址方式中,寄存器的内容不是操作数,而是操作数的偏移地址,操作数本身在存储器中。

存放存储器地址的寄存器称为地址指针。寄存器间接寻址方式可用的寄存器只允许是SI、DI、BX和BP这4个,简称为间址寄存器。一般情况下,如偏移地址在SI、DI和BX中,则以DS为段寄存器,如偏移地址在BP中则以SS为段寄存器。同样,也允许段超越。

为与寄存器寻址有所区别,规定用作间址的寄存器必须加上方括号。

例见P.101例3-5及P.102例3-6。

3.2.5 寄存器相对寻址

寄存器相对寻址中,操作数也存放在存储其中。把指令中规定的间址寄存器的内容加上指令中给出的一个8位或16位的地址位移量,构成操作数的偏移地址。段寄存器的确定仍如上寄存器间接寻址。由于位移量也可看作一个相对值,故把这种带位移量的寄存器间接寻址方式称为寄存器相对寻址。

例见P.102例3-7。

寄存器相对寻址常用于存取表格内容或一维数组中的元素。可把表格中的起始地址作为位移量,表中数据序号(或元素的下标值)放在间址寄存器中(反之亦然),即可存取表

25

格数据或一维数组中的任意元素。

例见P.102例3-8。

需要特别指出的是在汇编语言中,相对寻址的书写格式有几种不同的形式,例见P.103。 注意:在有些教科书中,也有将使用BX或BP作为间址寄存器的寄存器相对寻址称为基址寻址;而将用SI、DI作为间址寄存器的寄存器相对寻址称为变址寻址。

3.2.6 基址—变址寻址

在基址—变址寻址方式中,偏移地址由一个基址寄存器(BX、BP)的内容和一个变址寄存器(SI、DI)的内容相加而形成,称为基址—变址寻址。在默认情况下,指令中如用BX作基址寄存器,则段地址在DX中,如用BP作基址寄存器,则段地址在SS中。同样,也可允许段超越。

例见P.103例3-9。

使用基址—变址寻址方式时,不允许同时使用两个基址寄存器或两个变址寄存器。

3.2.7 基址—变址—相对寻址

基址—变址—相对寻址是基址—变址寻址的扩充。指令中指定一个基址寄存器,一个变址寄存器,同时还给出一个8位或16位的位移量,将三者相加得到操作数的偏移地址。默认的段寄存器,仍取决于使用的基址寄存器,也允许段超越。

例见P.104例3-10。 使用该寻址方法可方便地访问二维数组。利用基址寄存器存放数组的首址,而变址寄存器和位移量分别确定行和列的值,则可寻访二维数组中的指定行和列的元素。

与寄存器相对寻址类似,基址—变址—相对寻址指令也可用多种表达形式,例见P.104。 同样,基址—变址—相对寻址也不允许同时使用两个基址寄存器或两个变址寄存器。

3.2.8 隐含寻址

有些指令的操作不仅指明了进行何种操作,还隐含了部分操作数的地址。如乘除指令,指令中只给出乘数(或除数)的地址,而被乘数(或被除数)的地址是隐含(且固定)的。这种将一个操作数隐含在指令码中的寻址方式称为隐含寻址。

例见P.105例3-11。

3.3 8086指令系统

在讨论各种指令的特点、用途和功能,先介绍本节所用到的各种符号: OPRD 泛指各种类型操作数 Mem 存储器操作数 acc 累加器操作数 dest 目标操作数 src 源操作数

disp 8位或16位偏移量(可用符号地址表示) DATA 8位或16位立即数

port 输入输出端口(可用数字或表达式表示) ( ) 表示寄存器的内容 [ ] 表示存储器的内容

26

3.3.1 数据传送类指令

数据传送类指令是程序中使用频度最高的一类指令。数据传送类指令绝大多数不会对标志寄存器FLAGS产生影响。

数据传送类指令按功能又可分为4小类:

·通用数据传送指令 ·目标地址传送指令 ·标志传送指令 ·输入输出指令 1.通用数据传送指令

通用数据传送指令由包括一般传送指令MOV、堆栈操作指令PUSH和POP、交换指令XCHG、查表指令XLAT及字位扩展指令,下分别介绍:

1)一般传送指令MOV(move) 指令格式及操作功能

MOV dest,src ;(dest)←(src)

指令中dest表示目标操作数,src表示源操作数,指令功能是将一个操作数由源地址送到目标地址,而源地址中的操作数保持不变。

注意:在汇编语言中,规定凡具有双操作数的指令,目标操作数写在前面,源操作数写在后面,两者之间用一个逗号隔开。

MOV指令有以下特点:

·既可一次传送一个字节操作数(8位),也可一次传送一个字操作数(16位),具体取决于指令中涉及的寄存器或立即数的位数。 ·可用上节讲过的各种寻址方式。 ·可实现下述各种传送:

(1)寄存器与寄存器之间的数据传送

16位数据的传送指令,例如: MOV BX,SI ;变址寄存器SI中的内容送到基址寄存器BX MOV DS,AX ;累加器AX的内容送到段寄存器DS MOV AX,CS ;段寄存器CS的内容送到累加器AX 8位数据的传送指令,例如: MOV MOV

AL,CL DL,CH

;通用寄存器CL中的内容送AL ;通用寄存器CH中的内容送DL

如(CX)= 2233H,上两条指令执行后(AL)= 33H,(DL)= 22H (2)寄存器与存储器之间的传送

可以是8位数据传送,也可以是16位数据传送,可以是寄存器到存储器的传送,也可以是存储器到寄存器的传送。例如:

MOV

CL,[BP][DI]

;SS段偏移地址为(BP)+(DI)的存储单元内容送CL。

如(SS)= 8000H, (BP)= 1020H,(DI)= 0383H,(813A3H)= 44H,则上指令执行后,

(CL)= 44H。

当传送16位数据(字操作数)时,这时对连续两个存储器单元进行存取,且寄存器的低8位对应存储器的低地址单元,寄存器的高8位对应存储器的高地址单元,例如: MOV [BX],AX ;将AX的内容送连续两个存储器单元 如(DS)= 6000H,(BX)= 1200H,(AX)= 1234H,则上指令执行后,(61200H)= 34H,(61201H)= 12H。

27

(3)立即数到寄存器的传送

MOV AL,5 ;将立即数05H送累加器AL MOV BX,3078H ;将立即数3078H送寄存器BX (4)立即数到存储器的传送

MOV BYTE PTR[BP+SI],5 ;将立即数05H送到SS段偏移量为(BP)+(SI)的单

MOV

;元中

WORD PTR[BX],1005H ;将立即数1005H分送DS段偏移地址为(BX)和

;(BX)+ 1的两个存储单元 (5)存储器与段寄存器之间的传送 MOV

DS,[1000H] [BX],ES

;将DS段偏移地址为1000H和1001H的两个存储单元的 ;内容送段寄存器DS

;将段寄存器ES的内容分送DS段偏移地址为(BX)和

MOV

;(BX)+ 1的两个存储单元 如上两指令执行前(DS)= 8000H,(ES)= 4000H,(BX)= 1200H,(81000H)= 00H,

(81001H)= 20H,执行后(DS)= 2000H,(21200H)= 00H,(21201H)= 40H。 用MOV指令进行数据传送必须注意以下几点:

①MOV指令的两个操作数类型必须相同。 下列指令为错误指令: MOV AX,BL

②不能两个操作数同为存储器操作数。 下列指令为错误指令:

MOV [BX],[SI]

③不能用立即数给段寄存器赋值(需通过两条指令) 下列指令为错误指令: MOV DS,1234H

④不能在段寄存器间直接传送数据(需通过两条指令) 下列指令为错误指令:

MOV DS,ES

⑤一般情况下,IP和CS的内容不能通过MOV指令修改。IP、CS不能作目标操作数,只能作源操作数。

⑥FLAGS内容不能通过MOV指令作修改。 MOV传送指令举例:

例:把内存中首地址为MEM1的200个字节的数据送到首地址为MEM2的区域中。 解:程序如下(部分指令尚未学到):

MOV MOV MOV

SI,OFFSET MEM1 ;源数据块首地址(偏移地址)送SI DI,OFFSET MEM2 ;目标数据块首地址(偏移地址)送DI CX,200 AL,[SI] [DI],AL SI DI CX NEXT

;数据块长度送CX(设循环次数) ;源数据块(各单元)内容送AL ;AL内容送目标地址 ;SI指向下一个单元 ;DI指向下一个单元 ;CX减1(修改循环次数) ;若循环没到200次,则继续 ;若已到200次,停止

NEXT: MOV MOV

INC INC DEC JNZ HLT

28

2)堆栈操作指令PUSH(push onto the stack)和POP(pop from the stack) (1)堆栈

堆栈是内存中一个特定的区域,用以存放各种必须保存的数据(举例说明,如用于保护断口地址,见P.109子程序调用示意图,又如对寄存器内容进行保护,见P.112)它在内存中所处的段称为堆栈段,其段基址放在堆栈段寄存器SS中。堆栈操作必须遵循以下原则:

·堆栈的存取每次必须是一个字。

·向堆栈中存放数据,是从高地址向低地址方向增长(与内存中其他段不同),从堆栈取数据时正好相反(见P.109图3-8)。 ·堆栈操作指令中的操作数只能是寄存器操作数或存储器操作数,而不能是立即数。 ·堆栈段在内存中的位置由堆栈段寄存器SS决定。堆栈指针SP总是指向栈顶,即SP的内容为当前栈顶偏移地址。所谓栈顶是一个存储单元,堆栈操作时,栈顶不参与操作,而把栈顶地址减1和栈顶地址减2这两个单元作为操作对象。 ·堆栈操作遵循“后进先出(LIFO)”的原则。 (2)堆栈操作指令

堆栈操作指令有两条,分别为压栈指令PUSH和弹出指令POP. 指令格式为: PUSH src POP dest

该两条指令中的操作对象可为:

·寄存器(包括数据寄存器,地址指针寄存器和变址寄存器)

·段寄存器(CS除外,PUSH CS合法,而POP CS非法) ·存储器单元

注意操作数必须为16位(即一个字)。如为寄存器必须为16位寄存器。如为存储器,则应是两个连续的存储单元。例如:

PUSH AX PUSH BP

PUSH DATA[SI] POP DS POP

[BX]

;AX内容压入堆栈

;基址寄存器内容压入堆栈

;以DS内容为段基址,将以(SI)+ DATA为偏移地址及 ;(SI)+ DATA + 1为偏移地址的两个单元内容压入堆栈 ;堆栈顶部两单元内容弹回DS段寄存器

;堆栈顶部两单元内容弹回以DS内容为段基址,以(BX) ;为偏移地址及以(BX)+ 1为偏移地址的两个单元

(3)堆栈指令的执行过程

压栈指令PUSH OPRD 执行过程参见P.110图3-10。 OPRD高8位→((SP)- 1); OPRD低8位→((SP)- 2); (SP)→(SP)- 2。

即PUSH指令将一个字的源操作数送到堆栈的顶部。 出栈指令POP OPRD 执行过程参见P.110图3-11。 ((SP))→OPRD低8位; ((SP)+ 1)→OPRD高8位;

(SP)+ 2→(SP)。

POP指令将栈顶两个单元的内容(一个字)送到目标地址中。

在程序中PUSH和POP指令一般成对出现,且执行次序相反,从而保证数据合理返回。

29

堆栈操作指令应用举例:

例:执行下列程序,分析堆栈区的变化情况。 MOV AX,9000H MOV SS,AX MOV SP,0E200H MOV PUSH PUSH ┆ POP POP

DX,38FFH DX AX DX AX

执行结果如P.111图3-12所示。

本例程序中,由于没遵循“后进先出”的原则,结果出栈后,AX和DX的内容没保持压 栈前的状态,而是AX和DX的内容进行了互换。

3)交换指令XCHG(exchange) 指令格式为:

XCHG OPRD1,OPRD2 ;(OPRD1)←→(OPRD2)

指令的操作功能是使源操作数和目标操作数的内容进行互换。 交换指令对操作数有如下要求:

·可以在寄存器与寄存器、寄存器与存储器之间进行数据交换,但不能在存储器与存储器之间进行数据交换。

·段寄存器内容不能参与交换。 ·两个操作数的字长必须相同。 例如:

XCHG AX,BX ;(AX)←→(BX) XCHG CL,DL

XCHG指令应用举例:

;(CL)←→(DL)

例:设(DS)= 2000H,(SI)= 0230H,(DL)= 88H,(20230H)= 44H,试析执行指令

XCHG [SI],DL后的结果。

解:执行后:(DL)= 44H,(20230H)= 88H。

即DL的内容与20230H单元的内容进行了交换。 4)查表转换指令XLAT(translate) 指令格式为: XLAT

或XLAT src table XLAT指令应用举例:

;(AL)←((BX)+(AL)) ;(src table为表的首地址)

例:在内存的数据段中存有一个数字符0~9的ASCII码转换表(见P112图3-13),首地址为Hex table,试编程,求数字符8的ASCII码。

程序如下:

LEA MOV

BX, Hex table AL,8

;表首偏移地址送BX ;8送AL

XLAT Hex table ;查表转换,结果在AL中 执行结果:(AL)= 38H

需要指出的是:由于要查找元素的序号规定放在AL中,所以表格的最大长度不会越过

30

256个字节。

5)字位扩展指令

字位扩展指令完成操作数的扩展,一种是将一个字节的数扩展为字,另一种是将一个字的数扩展为双字,以满足各种特殊需要(以后要用到)。

(1)CBW(convert byte to word)指令

指令格式为: CBW

CBW指令将一个字节操作数扩展为一个字长的数,源操作数隐含在AL中,目标操作数隐含在AX中。当(AL)<80H时,(AH)= 00H;否则(AH)= FFH,即为有符号数的扩展。

CBW指令应用举例:

例:把字节数8EH扩展为字。 程序如下: MOV

CBW

AL,8EH

执行结果:(AX)= FF8EH。

(2)CWD(convert word to double word)指令

CWD指令将一个字操作数扩展为双字,源操作数隐含在AX中,目标操作数隐含在DX和AX中。当(AX)<8000H时,(DX)= 0000H;否则(DX)= FFFFH,也为有符号数的扩展。

CWD指令应用举例:

例:把字43FFH扩展为双字。 程序如下:

MOV AX,43FFH CWD

执行结果:(DX):(AX)= 000043FFH

2.输入输出(I/O)指令

(I/O)指令是专门用于向输入输出端口进行读写操作的指令。有IN和OUT两条指令。需要特别指出的是只有累加器AL(或AX)才能与I/O端口进行数据传送,所以这两条指令也称为累加器专用传送指令。

8088系统可连接多个外设端口。在8088的I/O指令中,只允许用两种寻址方式:

·直接寻址方式:指令中包含一个8位的由立即数提供的I/O端口地址。允许寻址256个端口,端口地址范围为00H~FFH。 ·寄存器间接寻址方式:端口地址规定由DX寄存器指定,可寻址64K个端口(地址范围为0000H~FFFFH)。 (1)输出指令IN(input) 指令格式为: IN

acc,port

;直接寻址,port为8位立即数表示的端口地址

IN acc,DX ;间接寻址,DX的内容为16位端口地址

上述指令从端口输入一个字节到AL或输入一个字到AX中,具体有以下四种形式。 IN IN 个

IN

AL,DATA AX,DATA

AL,DX

;端口地址8位,输入一个字节到AL

;端口地址8位,由DATA和DATA + 1两个端口输入一;字到AX中

;端口地址16位,由(DX)端口输入一个字节到AL中

31

IN

AX,DX ;端口地址16位,由(DX)和(DX)+ 1两个端口输入

;一个字节到AX中 输入指令IN应用举例。

例:从地址为03B0H的端口输入一个字节到AL。 程序如下: MOV IN

DX,03B0H AL,DX

;将16位端口地址送DX

;从地址为03B0H的端口输入一个字节到AL(说明)

(2)输出指令OUT(output) 指令格式为: OUT OUT OUT OUT

OUT OUT 1

port,acc DX,acc DATA,AL DATA,AX

DX,AL DX,AX

;直接寻址,port为8位立即数表示的端口地址 ;间接寻址,DX的内容为16位端口地址

;端口地址8位,由AL输出一个字节到DATA端口

;端口地址8位,由AX输出一个字到DATA和DATA + 1 ;两个端口

;端口地址16位,由AL输出一个字节到(DX)端口 ;端口地址16位,由AX输出一个字到(DX)和(DX)+ ;两个端口

上述指令把AL(或AX)的内容输出到指定的端口,具体有以下四种形式:

输出指令OUT应用举例。

例:将AX的内容从地址为0043H和0044H的两个端口输出。 程序如下:

MOV DX,0043H OUT DX,AX

3.地址传送指令

8088/8086指令系统提供3条用于传送地址的指令:LEA、LDS、LES。 (1)取偏移地址指令LEA(load effective address) 指令格式为: LEA reg16,mem

LEA指令将存储器的16位偏移地址送到指定的寄存器,这里源操作数必须是存储器操作数,而且传送的是偏移地址。目标操作数是16位通用寄存器,而该寄存器用来作地址指针。

LEA指令应用举例。

例:将内存单元BUFFER和BUFFER + 1两个单元的内容送AX。 程序如下: LEA MOV MOV

BX,BUFFER AL,[BX]

AH,[BX + 1]

;将内存单元BUFFER的偏移地址送BX ;BUFFER单元内容送AL

;BUFFER + 1单元内容送AH

;端口地址0043H送DX

;将AX的内容从地址为0043H和0044H的两个端口输出

上2、3条指令也可合为MOV AX,[BX]。

又例:设(BX)= 1000H,(DS)= 6000H,(61050H)= 33H,(61051H)= 44H。试述执行下述两条指令后的结果。

LEA BX,[BX + 50H] MOV BX,[BX + 50H]

32

解:第一条指令执行后(BX)= 1050H;

第二条指令执行后(BX)= 4433H(见P.115图3-14) 从此例可以说明MOV指令和LEA指令的不同之处。 (2)指令LDS(load point into DS) 指令格式为 LDS

reg16,mem32

;(reg16)←(mem32 + 1):(mem32) ;(DS)←(mem32 + 3): (mem32 + 2)

LDS指令源操作数mem32为存储器操作数,给出的是内存中4个连续单元的首地址,目

标操作单元有两个。一个为reg16,是BX、BP、SI、DI四个间址寄存器之一,存放上述4个存储单元的前两个单元内容作偏移地址。另一个操作单元为隐含的DS,存放上述4个存储单元的后两个单元内容作段基址。

LDS指令应用举例:

例:设(DS)= 6OOOH,内存地址为60348H开始的4个单元存放了一个32位的远指针98011H(作解释),如P.116图3-15所示。试析执行下两条指令的结果。

LDS

MOV

SI,[0348H] AX,[SI]

执行结果:(SI)= 8011H,(DS)= 9000H,(AX)= 3412H。 (3)指令LES(load point into ES) 指令格式为: LES

reg16,mem32

;(reg16)←(mem32 + 1):(mem32) ;(ES)←(mem32 + 3): (mem32 + 2)

LES指令和LDS指令相仿,仅将DS换成ES而已。例见P.116。

4.标志传送指令

标志传送指令共有4条:LAHF、SAAHF、PUSHF、POPF。 (1)LAHF(load AH with flag)指令 指令格式为:

LAHF

该指令把标志寄存器低8位(含SF、ZF、AF、PF、CF五个标志位)传送到AH的对应位,如P.116图3-16所示。指令执行对标志位无影响。

(2)SAHF(store AH into flag)指令 指令格式为:

SAHF

SAHF指令与LAHF指令执行相反的操作,即将AH中的7、6、4、2、0位内容传送到标志寄存器的SF、ZF、AF、PF、CF位,以改变对应标志位的状态,但其它标志位不受影响。

LAHF指令和SAHF指令一般配对使用。

(3)PUSHF和POPF指令

该两条指令实质上为堆栈操作指令,只不过其操作数为标志寄存器FLAGS而已,操作功能类同堆栈操作指令。

PUSHF和POPF指令用于过程调用时保护标志位的状态。PUSHF和POPF指令一般配对使用。

3.3.2算术运算指令

算术运算指令包括加、减、乘、除四组。可实现字节或字,无符号数和有符号数运算。

33

指令有单操作数(如乘、除指令)的,也有双操作数的。单操作数不允许使用立即数,而双操作数中,立即数也只能作为源操作数。此外,也不允许两个操作数都为存储器操作数。

算术运算可能涉及到超出数的表示范围的问题,对无符号数和有符号数分别可由CF和OF标志来判断。

除四组二进制算术运算指令外,为使运算结果为十进制数(为BCD码),8088指令系统还提供了四类十进制调整指令。

算术运算指令大多会对标志位产生影响。 1.加法运算指令

加法运算指令有三条:不带进位位的加法指令ADD、带进位位的加法指令ADC及加1指令INC。

(1)不带进位位的加法指令ADD(add) 指令格式为:

ADD OPRD1,OPRD2

;(OPRD1)←(OPRD1)+(OPRD2)

ADD指令用于两个操作数相加(目标操作数加源操作数),和置于目标操作单元。

源操作数和目标操作数均可为8位或16位的寄存器操作数或存储器操作数,源操作数还可为立即数。两操作数可为无符号数,也可为带符号数。

需要注意的是:两操作数不能同时为存储器操作数。另外不能对段寄存器进行运算。 ADD指令的执行会对6个状态标志位产生影响。

例如:

ADD CL,20H

;(CL)←(CL)+ 20H

ADD AX,SI ;(AX)←(AX)+(SI)

ADD DATA[BX],AL ;((BX)+ DATA)←((BX)+ DATA)+(AL) ADD DX,[BX+SI] ;(DX)←(DX)+((BX)+(SI)+ 1):((BX)+(SI)) 上述指令均为合法的ADD指令,而下列ADD指令则是非法的: ADD ADD

[SI],[BX] DS,AX

;不允许两操作数均为存储器操作数 ;不允许段寄存器进行运算

ADD指令应用举例:

例:试析执行下列指令后,各标志位的状态。 MOV AL,7EH ;(AL)←7EH ADD

AL,5BH 01111110

;(AL)←7EH + 5BH

+ 01011011

11011001

执行后:AF = 1,CF = 0,OF = 1,PF = 0,SF = 1,ZF = 0

(AL)= D9H

若为无符号数,运算结果未超出8位二进制数的表示范围(CF = 0); 若为有符号数,运算结果已超出8位二进制数的表示范围(OF = 1)。 (2)带进位的加法指令ADC(add with carry) 指令格式为:

ADD OPRD1,OPRD2

;(OPRD1)←(OPRD1)+(OPRD2)+ CF

ADD指令在格式、功能及对标志位影响上都与ADD指令类同,只是标志位CF的值也参

与加法运算,常用于多字节加法运算。

ADC指令应用举例:

34

例:求两个4字节无符号数0107A379H + 10067E4FH之和。 程序如下:

MOV DX,0107H MOV AX,0A379H MOV BX,1006H MOV ADD

CX,7E4FH AX,CX

;第1个数的高位送DX ;第1个数的低位送AX ;第2个数的高位送BX ;第2个数的低位送CX ;两数低16位相加

ADC DX,BX ;两数高16位相加,并加上低16位相加中的进位位 执行结果:(DX)= 110EH (AX)= 21C8H CF = 0

即两数之和为110E21C8H

上程序可简化如下: MOV ADD MOV

AX,0A379H AX,7E4FH DX,0107H

ADC DX,1006H

执行结果与上程序相同。

(3)加1指令INC(increment) 指令格式为: INC OPRD ;(OPRD)←(OPRD)+ 1

INC指令将指定的操作数内容加1,后再送回该操作数。操作数可以是寄存器或存储器操作数。但不能是段寄存器,也不能为立即数。操作数可以是8位,也可为16位。 INC指令不影响CF标志位,但对AF、OF、PF、SF及ZF会产生影响。它通常在循环程序中用于修改地址指针及循环次数等。

例如: INC AX ;(AX)←(AX)+ 1

INC INC

BL

BYTE PTR[SI]

;(BL)←(BL)+ 1

;将SI所指向的存储单元内容加1,并送回该单元

2.减法指令

8088/8086共有5条减法指令。包括:不考虑借位的减法指令SUB,考虑借位的减法指令SBB,减1指令DEC,求补指令NEG以及比较指令CMP。

(1)不考虑借位的减法指令SUB(subtract)

指令格式为:

SUB OPRD1,OPRD2

;(OPRD1)←(OPRD1)-(OPRD2)

SUB指令用于两个数相减(目标操作数减去源操作数),结果置于目标操作单元。

该指令对操作数的要求及对标志位的影响与ADD指令完全相同。 例如: SUB SUB

BL,30H

AL,[BP + SI]

;(BL)←(BL)- 30H

;AL的内容减去SS段中偏移地址为(BP)+ (SI)单元的

;内容,结果送AL

(2)考虑借位的减法指令SBB(subtract with borrow)

指令格式为:

SBB OPRD1,OPRD2 ;(OPRD1)←(OPRD1)-(OPRD2)- CF

SBB指令在格式、功能及对标志位的影响上与SUB指令类同,只是标志位CF的值也参

35

与减法运算,常用于多字节减法运算。

例如:

SBB BL,30H ;(BL)←(BL)- 30H - CF SBB WORD PTR[SI],1034H ;(SI)+ 1和(SI)的两个单元的值减去立即数1034H ;及CF的值,结果送回(SI)+ 1及(SI)两个单元 (3)减1指令DEC(decrement) 指令格式为:

DEC OPRD ;(OPRD)←(OPRD)- 1

DEC指令将指定的操作数内容减1,后再送回该操作数。它对操作数的要求及对标志位的影响均与INC指令相同。

它也常在循环程序中用于修改地址指针及循环次数等。 例如: DEC DEC DEC 减

DEC指令应用举例:

例:编写一个延时程序。 MOV NEXT: DEC

CX,OFFFFH CX

;1,后送回该单元

AX BL

BYTE PTR[DI]

;(AX)←(AX)- 1 ;(BL)←(BL)- 1

;以ES内容为基址,以DI内容为偏移地址单元的内容

;送计数初值到CX

;计数值(CX内容)减1

JNZ NEXT ;若(CX)≠0,则转NEXT HLT ;停止

上程序延时时间可通过查表找到各条指令执行的时钟周期,后通过计算得到。 (4)求补指令NEG(negate) 指令格式为: NEG OPRD

;(OPRD)← 0 -(OPRD)

NEG指令的功能是对操作数求补。即用0减去操作数内容,并将结果送回该操作数。

NEG指令对6个状态标志位都有影响,并需注意以下两点:

①执行NEG指令后,除操作数位0外,一般情况下,都会使CF为1。

②当指定的操作数为80H(-128)或位8000H(-32768),则执行NEG指令后,结果不变,但此时OF置1,其它情况下OF均置0,

NEG指令应用举例:

例:设(DS)= 6000H,(BX)= 0010H,(60010H)= 47H。 试析执行NEG [BX]指令的结果。

解:执行上指令时,CPU将进行如下减法运算:

00000000 - 01000111 10111001

故执行后(60010H)= B9H,相当于对-47H求补。 (5)比较指令CMP(compare)

指令格式为:

CMP OPRD1,OPRD2 ;(OPRD1)-(OPRD2) CMP指令对两个操作数进行比较(相减),相减结果不送目标操作数,而根据相减的结

36

果影响标志位。指令对操作数的要求及对标志为的影响与SUB指令完全相同。

例如:

CMP BX,2100H CMP CL,DH

CMP AX,[BX+SI+4] 响

;(BX)- 2100H, 影响标志位

;(CL)-(DH), 影响标志位 ;(AX)-((BX)+(SI)+5):((BX)+(SI)+4)),影;标志位

比较指令主要用来比较两个数的大小关系。可在指令执行后,根据标志位的状态判断

两个操作数的大小,或是否相等。判断方法如下:

·相等关系:根据ZF状态判断。如ZF = 1,两个操作数相等。否则,不等。 ·大小关系:分无符号数和有符号数两种情况:

(1)对两个无符号数,可据CF状态来判断。如CF = 0,则被减数大于减数;如CF = 1, 则减数大于被减数。

(2)对两个有符号数,需考虑两个数是同号还是异号。

①对两个同符号数,相减不会产生溢出,即OF = 0。有: 若SF = 0,则被减数大于减数。

若SF = 1,则减数大于被减数。

②对两个不同符号数,相减可能产生溢出,也可能不产生溢出。 若OF = 0,(无溢出),则: 如被减数大于减数 SF = 0 如减数大于被减数 SF = 1

若OF = 1,(有溢出),则:

如被减数大于减数 SF = 1(例7FH - 82H = FDH) 如减数大于被减数 SF = 0(例82H - 7FH = 03H)

对上结果进行归纳,可得出判两个有符号数大小的方法是:

当OF⊕SF = 0时,被减数大于减数 当OF⊕SF = 1时,减数大于被减数

编程时,一般都在CMP指令后紧跟一条条件转移指令,以根据比较结果决定程序走向。

3.乘法指令

8088的乘法指令包括无符号数乘法指令(MUL)和有符号数乘法指令(IMUL)两种。采用隐含寻址方式,源操作数由指令给出,目标操作数隐含。当字节与字节相乘时,乘积为16位,规定存放在AX中;当字与字相乘时,乘积为32位,规定高16位存放在DX中,低16位存放在AX中。

(1)无符号数的乘法指令MUL(unsigned mutiple) 指令格式为: MUL

OPRD

指令操作分两种情况: 字节相乘:(AX)←(OPRD)×(AL)

字相乘:(DX):(AX)←(OPRD)×(AX)

指令中源操作数OPRD可为8位或16位寄存器操作数或存储器操作数,但不能为立即数。

例如: MUL BX

;(DX):(AX)←(AX)×(BX)

37

MUL BYTE PTR[SI] ;(AX)←(AL)×((SI))

MUL DL ;(AX)←(AL)×(DL)

MUL WORD PTR[DI] ;(DX):(AX)←(AX)×((DI) + 1):((DI)) MUL指令对CF及OF标志有影响,当乘积的高半部(在字节相乘时为AH,在字相乘时为DX)不为零,则CF = OF = 1,否则CF = OF = 0。对其它标志位无定义。

乘法指令执行时间较长,在某些场合下,可用左移指令来代替,以加快运行速度,待在移位指令中再作介绍。

(2)带符号数的乘法指令IMUL(signed mutiple) 指令格式为: IMUL OPRD

IMUL指令功能与MUL指令类似,仅有以下几点差别: ·两乘数都为有符号数。

·若乘积的高半部分是低半部分的扩展,则CF = OF = 0;否则,CF = OF = 1 ·指令中给出的源操作数应在带符号数的表示范围内。(作解释,如操作数为表达式) IMUL指令应用举例:

例:设(AL)= FEH,(CL)= 11H,求两数的乘积。

若将两数看作无符号数,则应使用指令: MUL CL 执行后结果:(AX)= 10DEH(解释:即0FE0H + FEH = 10DEH), 且CF = OF = 1(∵AH内容不为0)。 若将两数看作带符号数,则应使用指令:

IMUL CL 执行后结果:(AX)= FFDEH(解释:相当于-2×11H = -22H,即为FFDEH), 且CF = OF = 0(∵AH内容为AL内容符号位的扩展)。

4.除法指令

8088的除法指令也包括无符号除法指令(DIV)和有符号除法指令(IDIV)两种,也采用隐含寻址方式。除数由指令给出(不能为立即数)。

除法指令要求被除数的字长必须为除数的2倍(如不够要用字位扩展指令来扩展)。当除数为8位,则被除数为16位,规定放在AX中;当除数为16位,则被除数为32位,规定放在DX(高16位)和AX(低16位)中。

(1)无符号数的除法指令DIV(unsigned divide)

指令格式为: DIV OPRD

指令操作数OPRD可为8位或16位,寄存器或存储器操作数,但不可为立即数。 字节除法:(AL)←(AX)/(OPRD) (AH)←(AX)%(OPRD) (%为取余操作)

即AX中的16位无符号数除以OPRD的内容。得到8位的商放AL中,8位的余数放AH中。

字除法:(AX)←((DX):(AX))/(OPRD) (DX)←((DX):(AX))%(OPRD) (%为取余操作)

即以DX和AX中的32位无符号数除以OPRD的内容。得到16位的商放在AX中,16位的余数放在DX中。

若除法运算的结果大于寄存器可保存的最大值,即超出8位或16位无符号数可表示的

38

范围,则在CPU内部会产生1个类型0中断(以后再讲)。

例如:

DIV BL

DIV WORD PTR[SI]

;(AX)除以(BL),商放在AL,余数放在AH

;(DX):(AX)除以((SI) + 1):((SI)),商放在AX, ;余数放在DX

DIV指令应用举例:

例:用除法指令及所7FA2H÷03DDH。 程序如下:

MOV AX,7FA2H MOV CWD DIV

BX,03DDH BX

;(AX)= 7FA2H ;(BX)= 03DDH

;(DX):(AX)= 00007FA2H

;(AX)= 0021H(商),(DX)= 0025H(余数)

(2)有符号数的除法指令IDIV(singned divide)

指令格式为:

IDIV OPRD

IDIV指令与DIV在功能上类似,唯操作对象和结果均为有符号数。 例如: IDIV CX

IDIV BYTE PTR[BX] 商

;在AX中,余数在DX中

IDIV指令执行的结果,商和余数均为带符号数,但规定余数符号与被除数相同。以保证除法的结果为唯一(作说明,例见P.124)。

无符号除法和有符号除法对六个标志位均无影响。

5.BCD码(十进制数)运算调整指令

为实现十进制(BCD码)运算,8088提供了6条用于BCD码运算和调整指令。均采用隐含寻址方式,隐含操作数为AL(或AL和AH)。这些指令与加、减、乘、除指令配合,实现BCD码的算术运算。

1)加法的十进制调整指令

BCD码存放有压缩和非压缩两种形式,故加法的十进制调整也包括压缩和非压缩两种。 (1)压缩BCD码加法的十进制调整指令DAA(desimal adjust for addition) 指令格式为

DAA

DAA指令用于对两个压缩BCD码相加之和(结果在AL中)进行调整,以产生正确的压缩BCD码运算结果。调整方法为:

①若(AL)中低4位>9或AF = 1,则(AL)←(AL)+ 06H,并使AF = 1。 ②若(AL)中高4位>9或CF = 1,则(AL)←(AL)+ 60H,并使CF = 1。 DAA指令应用举例:

例:试编程,计算48 + 27 = ?(要求计算结果为压缩BCD码) 程序如下: MOV AL,48H ADD AL,27H

;DX和AX中的32位数除以(CX),商在AX中,余数在 ;DX中

;(AX)除以DS段以(BX)为偏移地址单元中的内容,

39

DAA

上第二条指令的计算过程为:

01001000 + 00100111 01101111 DAA指令调整过程为:

01101111

+ 00000110

01110101 (注意,如调整中出现半进位或进位,不再调整) 结果:(AL)= 75H,AF = 1,CF = 0。

DAA指令影响除OF以外的其余5个状态标志。

(2)非压缩BCD码加法的十进制调整指令AAA(ASCII adjust for addition) 指令格式为: AAA

AAA指令用于对两个非压缩BCD码数相加之和(结果在AL中)进行调整,形成一个正确的扩展BCD码,调整后,结果和的低位在AL中,高位在AH中。调整步骤为:

①若(AL)中低4位>9或AF = 1,则(AL)←(AL)+ 06H,(AH)+ 1,并使AF = 1。 ②屏蔽掉(AL)中的高4位,即(AL)←(AL)∧0FH。 ③CF←AF

AAA指令应用举例::

例:试编程,计算9 + 4 = ?(要求计算结果为非压缩BCD码) 程序如下: MOV AL,09H MOV BL,04H ADD AL,BL AAA

;BCD码数9送AL ;BCD码数4送BL ;(AL)= 09H + 04H = 0DH

;调整后,(AL)= 03H(即0DH + 06H)∧0FH = 03H,(AH)= 1, ;CF = 1

AAA指令只影响AF和CF标志。

注意:DAA和AAA指令都必须紧跟在ADD指令或ADC指令后执行,且ADD或ADC指令的执行结果都必须放在AL中。

2)减法的十进制调整指令

减法的十进制调整也分为压缩BCD码和非压缩BCD码两种。

(1)压缩BCD码减法的十进制调整指令DAS(desimal adjust for subtraction) 指令格式为

DAS

DAS指令用于对两个压缩BCD码数相减后的结果(在AL中)进行调整。产生正确的压缩BCD码运算结果。调整方法如下:

①若(AL)中低4位>9或AF = 1,则(AL)←(AL)- 06H,并使AF = 1。 ②若(AL)中高4位>9或CF = 1,则(AL)←(AL)- 60H,并使CF = 1。 DAS指令对标志位的影响与DAA指令相同。

(2)非压缩BCD码减法的十进制调整指令AAS(ASCII adjust for subtraction) 指令格式为 AAS

AAS指令用于对两个非压缩BCD码数相减后的结果(在AL中)进行调整。形成一个正

40

本文来源:https://www.bwwdw.com/article/7lb7.html

Top