You are on page 1of 259

微型计算机原理与接口技术

主编:杜诚、郭荣佐、李琳琳

副主编:王勇、肖健平、陈亦鲜、王术群、

郑海春、鄢田云、刘敏贤
内容简介
《微型计算机原理与接口技术》课程需要讲授的内容分为包括原理部
分,汇编部分、接口三部分内容,内容多,知识点多 ,学习方式不同,针对不
同内容,利用不同的模式教学。硬件部分和指令部分由于知识点众多采用案例
模式编写;软件部分采用实践模式,通过编程实践使学生掌握汇编语言的指令
和编程特点;接口部分可采取接口实验及仿真实验,提高学生在微机系统及综
合应用方面的能力。
本书共 9 章,内容包括计算机基础知识,CPU 内部体系结构,工作原理,
指令系统,汇编程序,存储器,常用接口芯片 8253,8255,AD0809, DAC0832 等。
本书可以作为普通高校本、专科科院校非计算机专业本科生教材,也可供
参加计算机等级考试人员学习使用。
前 言
《微型计算机原理与接口技术》是工科计算机及其相关专业的一门重要
的专业技术基础课程。 本课程帮助学生掌握微型计算机的硬件组成及使用;
学会运用汇编语言进行程序设计;树立起计算机体系结构的基本概念;为后
继的软、硬件课程做好铺垫。《微型计算机原理与接口技术》已成为工科专
业最重要的知识之一,是工科非计算机专业学生学习很多专业后续课程、开
展毕业设计和今后工作的重要技术基础课程。该课程的特点是教学内容多、
信息量大,对基础性、先进性和前沿性都有很高的要求,具有很强的工程实
践性。本书结构合理,思路清晰,理论与实际结合。
本书由长期从事该课程教学一线教师编写。第 1、3 章由杜诚编写,第
2 章由王勇编写,第 4 章由郭荣佐编写,第 5 章由陈亦鲜编写,第 6、7 章由
肖健平编写,第 8 章由王术群、李琳琳、郑海春编写,第 9 章由杜诚、李琳
琳、郑海春编写。在该书编写过程中刘敏贤修订第 1、2 章,鄢田云修订第 3、
9 章,郑海春老师修订第 4-8 章。全书由杜诚统稿审阅。
该书的出版得到西南民族大学,成都理工大学,桂林电子科技大学,
四川师范大学,西华大学,宜宾学院,成都信息工程学院,四川师范大学电
影电视学院,四川电影电视职业学院的大力支持,在此一并感谢。
本书由于出书时间紧促,书中难免有不妥之处,望广大读者多多提出宝
贵意见。
目 录
第 1 章 微型计算机的系统结构 .....................................................................................................5
1.1 概述 ...................................................................................................................................5
1.1.1 微型计算机的发展概况 .....................................................................................5
1.1.2 微型计算机的主要性能指标 ...............................................................................6
1.2.1 微型计算机的系统层次结构 ................................................................................7
1.2.2 微计算机系统的组成 ...........................................................................................8
1.2.3 冯·诺依曼型计算机原理 .......................................................................................9
1.3 微型计算机的基本数据类型 .......................................................................................10
1.3.1 数据存储 ................................................................................................................10
1.3.2 原码、反码和补码 ................................................................................................ 11
第 2 章 微处理器的结构 ...............................................................................................................14
2.1 8086 微处理器的结构 ................................................................................................14
2.1.1 8086 的内部功能结构 ........................................................................................14
2.1.2 8086 的寄存器结构 ..........................................................................................17
2.1.3 存储器的结构及访问 ..........................................................................................20
2.2 8086 的引脚信号及工作模式 ........................................................................................21
2.2.1 8086 CPU 的工作模式 .....................................................................................21
2.2.2. 8086 两种工作模式下共同引脚说明如下: ...................................................21
2.2.3 最小模式下引脚 ..................................................................................................23
2.2.4 最大模式和系统组成 .......................................................................................25
2.3 8088 和 8086 的比较 ......................................................................................................26
2.3.1 外部数据总线位数的差别: ...........................................................................27
2.3.2 指令队列容量的差别: ...................................................................................27
2.3.3 引脚特性的差别: ...........................................................................................27
2.4 典型时序分析 ..................................................................................................................27
第 3 章 8086 CPU 指令系统 ...........................................................................................................32
3.1 指令格式与寻址方式 .....................................................................................................32
3.1.1 指令格式 .............................................................................................................32
3.1.2 寻址方式 .............................................................................................................32
3.2 8086/8088CPU 指令系统 ................................................................................................36
3.2.1 数据传送类指令 ..................................................................................................36
3.3.2 算术运算类指令 .................................................................................................38
3.3.3 位操作类指令 ......................................................................................................43
3.3.4 程序控制指令 .......................................................................................................46
第 4 章 汇编语言程序设计 ..........................................................................................................51
4.1 汇编语言语句 ..................................................................................................................51
4.1.1 汇编语言语句的种类 .........................................................................................51
4.1.2 汇编语言的语句格式 ...........................................................................................51
4.1.3 指令语句的操作数组成 .......................................................................................52
4.1.4 指令语句中的运算符和操作符 ...........................................................................53
4.2 伪指令 ..............................................................................................................................56
4.2.1 数据定义伪指令 ...................................................................................................56
4.2.2 符号定义伪指令 ...................................................................................................57
4.2.3 段定义伪指令 .......................................................................................................58
4.2.4 模块定义与连接伪指令 .......................................................................................61
4.2.5 过程定义伪指令 ...................................................................................................62
4.3 汇编语言程序的结构 ......................................................................................................63
4.3.1 汇编语言程序的结构 ...........................................................................................63
4.3.2 程序正常返回 DOS 的方法 ................................................................................63
4.4 基本结构程序设计 ..........................................................................................................64
4.4.1 顺序程序设计 .......................................................................................................66
4.4.2 分支程序设计 .......................................................................................................66
4.4.3 循环程序设计 .......................................................................................................68
4.4.4 子程序设计 ...........................................................................................................75
4.5 DOS/BIOS 功能调用 .......................................................................................................78
4.5.1 DOS 系统功能调用 ..............................................................................................79
第 5 章 存储器 ...............................................................................................................................84
5.1 概述 ...................................................................................................................................84
5.1 存储器的分类 ...........................................................................................................84
5.1.2 半导体存储器的组成 ............................................................................................88
5.1.3 存储器的基本性能指标 ........................................................................................91
5.1.4 存储系统的层次结构 ............................................................................................93
5.2 随机存储器(RAM) ..........................................................................................................94
5.2.1 静态随机存储器(SRAM) ......................................................................................94
5.2.2 动态随机存储器(DRAM) .....................................................................................99
5.2.3 内存条 .................................................................................................................. 103
5.3 只读存储器(ROM) ................................................................................................ 104
5.3.1 掩膜 ROM .................................................................................................................... 105
5.3.2 可编程只读存储器(PROM) ................................................................................ 106
5.3.3 可擦可编程只读存储器(Erasable PROM) ......................................................... 107
5.3.4 电可擦除可编程只读存储器(E2PROM) ............................................................ 113
5.3.5 Flash 存储器 ........................................................................................................ 116
5.4 存储器的扩展 ................................................................................................................. 118
5.4.1 存储容量的位扩展 .............................................................................................. 118
5.4.2 存储容量的字扩展 .............................................................................................. 120
5.4.3 存储容量的字/位扩展 ......................................................................................... 123
5.5 新型的存储器 ................................................................................................................ 126
5.5.1 多体交叉存储器 .................................................................................................. 126
5.5.2 闪速存储器 .......................................................................................................... 127
5.5.3 高速缓冲存储器 Cache ....................................................................................... 127
5.5.4 虚拟存储器 .......................................................................................................... 128
第 6 章 中断 ................................................................................................... 错误!未定义书签。
6.1 概述 .................................................................................................... 错误!未定义书签。
6.1.1 中断的基本概念 ..................................................................... 错误!未定义书签。
6.1.2 中断处理过程 ......................................................................... 错误!未定义书签。
6.1.3 中断优先级 .............................................................................. 错误!未定义书签。
6.1.4 中断嵌套 .................................................................................. 错误!未定义书签。
6.2 8086/8088 CPU 中断系统 .................................................................. 错误!未定义书签。
6.2.1 中断分类 .................................................................................. 错误!未定义书签。
6.2.2 中断向量表 ........................................................................... 错误!未定义书签。
6.2.3 中断向量表的建立与修改 ...................................................... 错误!未定义书签。
6.2.4 中断响应过程 .......................................................................... 错误!未定义书签。
6.3 可编程中断控制器 8259A ................................................................ 错误!未定义书签。
6.3.1 8259A 的内部结构与引脚 ................................................... 错误!未定义书签。
6.3.2 8259A 的中断响应过程 .......................................................... 错误!未定义书签。
6.3.3 8259 的工作方式 ..................................................................... 错误!未定义书签。
6.3.4 8259A 的编程 .......................................................................... 错误!未定义书签。
6.3.5 8259A 应用举例 ...................................................................... 错误!未定义书签。
6.3.6 中断程序设计 ......................................................................... 错误!未定义书签。
第 7 章 输入输出 ............................................................................................. 错误!未定义书签。
7.1 概述 .................................................................................................... 错误!未定义书签。
7.1.1 CPU 与外设交换的信息 ......................................................... 错误!未定义书签。
7.1.2 接口的功能 .............................................................................. 错误!未定义书签。
7.1.3 接口的基本结构 ...................................................................... 错误!未定义书签。
7.2 I/O 端口 ........................................................................................... 错误!未定义书签。
7.2.1 I/O 端口的编址方法 ................................................................ 错误!未定义书签。
7.2.2 I/O 端口地址分配与地址译码 ............................................. 错误!未定义书签。
7.2.3 I/O 端口地址译码 ................................................................ 错误!未定义书签。
7.3 CPU 和外设之间数据传送的方式.................................................... 错误!未定义书签。
7.3.1 程序控制方式 .......................................................................... 错误!未定义书签。
7.3.2 中断方式 ................................................................................. 错误!未定义书签。
第 8 章 常用接口芯片 ..................................................................................... 错误!未定义书签。
8.1 8253 可编程定时器/计数器 ............................................................ 错误!未定义书签。
8.1.1 8253 的基本功能和内部结构 ............................................ 错误!未定义书签。
8.1.2 8253 的工作方式 ................................................................ 错误!未定义书签。
8.2 可编程并行 I/O 接口芯片 8255A ................................................ 错误!未定义书签。
8.2.1 可编程并行接口 8255A ........................................................ 错误!未定义书签。
8.2.2 8255A 的控制字及其工作方式 .......................................... 错误!未定义书签。
8.2.3 8255A 的编程 ...................................................................... 错误!未定义书签。
第 9 章 实 验 ............................................................................................................................. 231
第一部分 软件实验 ........................................................................................................... 231
快速掌握 Emu8086 ...................................................................................................... 231
实验一 简单指令实验 ........................................................................................... 237
实验二 寻址方法实验 ............................................................................................. 238
实验三 算术运算指令实验 ................................................................................... 239
实验四 查表程序设计 ........................................................................................... 240
第二部分 硬件实验部分 ................................................................................................... 241
快速掌握 PROTEUS .................................................................................................... 241
实验一 开关状态显示实验 ................................................................................... 250
实验二 定时器/计数器实验 .................................................................................... 251
实验三 综合实验 ................................................................................................... 253
第 1 章 微型计算机的系统结构
1.1 概述

1.1.1 微型计算机的发展概况

计算机是一种能对数字化信息进行自动调整运算的通用处理装置。计算机科学与技
术是第二次世界大战以来发展最快、影响最深远的新兴学科之一。计算机产业已在世界
范围内发展成为一种极富生命力的战略产业。

1.计算机的产生

世界上第一台现代意义的电子计算机是 1946 年由美国宾夕法尼亚大学物理学家约


翰.莫克利和工程师莫普斯伯.埃克特共同设计制造的 ENIAC。其最早研制的目的是为
了代替人类求解数学方程之类的数学运算,故而取名为“计算机”。它的主要特点:

图 1.1 世界上第一台电子数字计算机
1) 18000 多个电子管
2) 重量 30 吨
3) 占地约 170 平方米
4)运算速度 5000 次/秒加法和 300 次/秒乘法

2.计算机的发展

美国数学家冯.诺依曼于 1945 年提出了著名的“冯.诺依曼体系结构”理论,被西方


人誉为“计算机之父”。而它的结构体系主要内容为:
1) 计算机包括运算器、控制器、存储器和输入输出设备。
2) 计算机内采用二进制表示信息。
3) 程序存储:把计算步骤(程序)先存入内存,计算机不需要人的干预,会自动
执行所存入的程序。
上述这些概念奠定了现代计算机的基本结构思想。到目前为止,绝大多数计算机仍
沿用这一体系结构。
计算机的发展根据电子元器件不同可分为五代,其中,第五代计算机还没有真正意
义上问世。
第一代(1946 年至 1958 年)—— 电子管,几千次/秒,处理信息的位数4位
第二代(1958 年至 1964 年)—— 晶体管, 几十万次/秒,处理信息的位数8位
第三代(1964 年至 1972 年)—— 小规模集成电路,几百万次/秒,处理信息的位数
16 位
第四代(1972 年代中期以后)——大规模、超大规模集电路,上亿次/秒,处理信息
的位数 32 位
第五代(1980 年代中期以后)——智能计算机,把信息采集、存储、处理、通信和人
工智能结合在一起,具有形式推理、联想、学习和解释能力。它的体系结构将突破传统
的冯.诺依曼体系,实现高度的并行处理。

3.计算机的发展趋势

1) 多极化: 微型化和巨型化。如现在的医院、国防、气象部门所用的计算机都
是巨型机。而家庭个人所用的笔记本电脑、掌上电脑等属于微型计算机。(如图 1-1)
2) 网络化: 单机—>网络,计算机网络是现代通信技术与计算机技术相结合的产
物,它已在现代企业管理中发挥着越来越重要的作用,如银行系统、商业系统、交通运
输系统等。
3) 多媒体化:文本、图形、声音、图象等信息的载体。如现在推行的多媒体教学,
以及电影电视中的特技动画都把计算机多媒体化体现得淋漓尽致。
4) 智能化: 具有人的某些智能处理,进行“看”、“听” 、“说”、 “想”、 “做”,具
有逻辑推理、学习与证明的能力。智能化研究领域很多,其中最有代表性的领域是专家
系统和机器人。
5) 嵌入化: 在汽车电脑、智能电话等移动环境以及 INTERNET TV、SET-TOP BOX
等家庭环境中的应用。

1.1.2 微型计算机的主要性能指标

一台微型计算机功能的强弱和性能的好坏,不是单由某项指标来决定的,而是由它
的系统结构、指令系统、硬件组成、软件配置等多方面的因素综合决定。但对于大多数
普通用户来说,微处理器的性能指标基本上确定了其功能。描述微处理器的性能,通常
用到下面的一些概念。
1.CPU 类型
CPU 类型是指微机系统所采用的 CPU 芯片型号,它决定了微机系统的档次。
2.字长
字长是指 CPU 一次最多可同时传送和处理的二进制位数,字长直接影响到计算
机的功能、用途和应用范围。如 Pentium 是 64 位字长的微处理器,即数据位数是 64 位,
而它的寻址位数是 32 位。
3.时钟频率和机器周期
时钟频率又称主频,它是指 CPU 内部晶振的频率,常用单位为兆(MHz),它反映
了 CPU 的基本工作节拍。一个机器周期由若干个时钟周期组成,在机器语言中,使用
执行一条指令所需要的机器周期数来说明指令执行的速度。一般使用 CPU 类型和时钟
频率来说明计算机的档次。如 Pentium III 500 等。
4.运算速度
处理器完成一件具体任务所需的指令叫做程序。执行程序所花的时间就是完成该任
务的时间指标。时间愈短.机器速度愈高。为了衡量微处理器的速度,选用实现同一操
作的指令寄存器的加法指令作为基本指令,它的运行时间就作是基本指令执行时间,基
本指令执行时间由时钟周期及所用时钟周期数决定。单位有 MIPS(每秒百万条指令)、
MFLOPS(秒百万条浮点指令)
5.存取速度
是指存储器完成一次读取或写存操作所需的时间,称为存储器的存取时间或访问时
间。而连续启动两次写操作所需间隔的最短时间,称为存储周期。对于半导体存储器来
说,存取周期大约为几十到几百毫秒之间。它的快慢会影响到计算机的速度。内、外存
储器容量是指储存器能够存储信息的字节数。外存储器是可将程序和数据永久保存的存
储介质,可以说其容量是无限的。如硬盘、光盘已是微机系统中不可缺少的外部设备。
迄今为止,所有的计算机系统都是基于冯·诺依曼存储程序的原理。内、外存容量越大,
所能运行的软件功能就越丰富。CPU 的高速度和外存储器的低速度是微机系统工作过
程中的主要瓶颈现象,不过由于硬盘的存取速度不断提高,目前这种现象已有所改善。
6.访存空间
访存空间是指由微处理器构成的系统所能访问(Access)的存储单元数。此单元数是
由传送地址信息的地址总线条数决定。八位微处理器有 1 6 条地址线.能编出的地址码
16
有 2 =65536 种,即是由它决定的存储空间就有 65536 个单元。计算机中常称 1 024B

为 1K,因此把 65536 简称为 64K 单元。十六位微处理器有 20 条地址线。访存空间为:


20
2 =1048576≈1024K,比八位机大 16 倍。

1.2 计算机的基本结构和工作原理

1.2.1 微型计算机的系统层次结构
微计算机系统包括硬件系统和软件系统两大部件。硬件系统是指组成计算机的物质
基础,包括主机和外围设备,又称为机器系统。软件系统则是指为了方便用户使用和充
分发挥计算机效能的各种程序的总称,又称为程序系统,属于信息性质的东西,是计算
机组成的上层建筑。
1.微处理器(Microprocessor)
微处理器也称微处理机,它是微型计算机的核心部件,是原来体积很大的中央处理
器 CPU 的复杂电路,包括运算器、控制器、寄存器组和内部总线等部件,这种微缩的
CPU 大规模集成电路称为微处理器或微处理机。
2.微型计算机(Microcomputer)
微计算机就是以微处理器为核心,配上大规模集成电路的随机存储器 RAM、只读存
储器 ROM、输入/输出接口以及相应的辅助电路而构成的微型化的计算机装置。
3.微型计算机系统(Microcomputer System)
微计算机由于是由大规模集成电路构成,用户则可以根据不同用途,选购某种微处
理器和相应数量的大规模集成电路,自行设计装配满足需要的特殊微计算机系统;用户
也可先选购厂家生产的微型计算机,再自行设计特殊需要的部分以构成某种特殊用途的
系统。我们称这种以微处理器为核心构成的某种特殊用途的系统为微型计算机系统。

1.2.2 微计算机系统的组成

计算机的基本组成部分是:运算器、控制器、存储器、输入设备和输出设备等五个
部分.系统总线是各部件之间传送信息的公共通道,包括地址总线 AB、数据总线 DB 和
控制总线 CB。

图 1.2 计算机基本结构图
1.控制器:控制器是计算机的指挥中心, 是实现计算机运行过程的部件。它的作
用是从存储器中取出指令,然后分析指令,发出由该指令特定的一系列操作命令,完成指
令的功能。
2.运算器: 运算器又称算术逻辑单元(Arithmetic and Logical Unit,ALU),是将
二进制进行算术运算和逻辑运算的部件,是计算机对各种数据进行运算,对各种信息进
行加工处理的部件。运算器的功能和速度对计算机来说至关重要。
3.存储器:存放各种数据,信息和执行程序的部件,它存储的信息包括原始数据,
中间结果,最终结果,以及运算加工指令代码。 它又分为主存储器(内存)和辅助存
储器(外存)。没特别说明这里讲的存储器是指内存储器(内存),它用来存放计算机的
指令和数据。其中内存可分为随机存储器(Random Access Memory RAM)和只读存储器
(Read Only Memory ROM) 两大类。
4.输入设备
用来完成原始数据和程序输入的装置,它将数据,文字,声音,图像和程序转化
为二进制代码。常用的输入设备有键盘、鼠标、扫描仪、摄像机等。
5.输出设备
计算机将各种数据运算的结果,各种信息加工处理的结果以人们可识别的信息方式
输出。常用的输出设备有显示器、打印机、绘图仪等。
6.系统总线(bus)
CPU 是微型计算机的核心,这个核心靠 3 组总线将系统其他部件,存储器,I/O 接
口连接起来。这 3 组总线分别是数据总线,地址总线,控制总线。总线是指一组信号线
的集合,是在计算机系统各部件之间传输地址、数据和控制信息的公共通路,从物理结构
来看,它由一组导线和相关的控制驱动电路组成。
微型计算机采用了总线结构,CPU 通过总线读取指令并通过它与内存和外设之间进
行数据交换。在 CPU、存储器、I/O 接口之间传输信息的总线称为系统总线。系统总线
包括地址总线、数据总线、控制总线三部分。
(1)地址总线(address bus,AB)
AB 是单向总线, 用于传送地址信息的一组通信线,是微处理器用来寻址存储器单
元用的总线。16 根地址线可以确定 65536 个不同地址。
(2)数据总线(data bus,DB)
DB 是双向的,传输数据或代码的一组通信线,其条数与处理器字长相等。
(3)控制总线(control bus,CB)
CB 用于传送控制信号、时序信号和状态信号等。CPU 向内存或外设发出的控制信息、
内存或外设向 CPU 发出的状态信息均可通过它来传送。可见作为一个整体而言,CB 是双
向的,而对 CB 中的每一根线来说,它是单向的。

1.2.3 冯·诺依曼型计算机原理

电子计算机共同遵循的计算机结构原理和程序存储及程序控制的原理由冯·诺依曼
于 1945 年提出,故称为冯·诺依曼型计算机原理。
冯·诺依曼设计思想可以简要地概括为以下三点:
① 计算机应包括运算器、存储器、控制器、输入和输出设备五大基本部件。
② 计算机内部应采用二进制来表示指令和数据。每条指令一般具有一个操作码和
一个地址码。其中,操作码表示运算性质,地址码指出操作数在存储器的位置。
③ 将编好的程序和原始数据送入内存储器中,然后启动计算机工作,计算机应在
不需操作人员干预的情况下,自动逐条取出指令和执行任务。
冯·诺依曼设计思想最重要之处在于他明确地提出了“程序存储”的概念。他的全
部设计思想,实际上是对“程序存储”要领的具体化。
计算机的工作过程,就是执行程序的过程。怎样组织存储程序,涉及到计算机体系
结构问题。现在的计算机都是基于“程序存储”概念设计制造出来的。
了解了“程序存储”,再去理解计算机工作过程变得十分容易。如果想叫计算机工
作,就得先把程序编出来,然后通过输入设备送到存储器保存起来,即程序存储。下面
就是执行程序的问题。根据冯·诺依曼的设计,计算机应能自动执行程序,而执行程序
又归结为逐条执行指令。执行一条指令又可分为以下 4 个基本操作:
① 取出指令:从存储器某个地址中取出要执行的指令送到 CPU 内部的指令寄存器
暂存。
② 分析指令:把保存在指令寄存器中的指令送到指令译码器,译出该指令对应的
微操作。
③ 执行指令:根据指令译码,向各个部件发出相应控制信号,完成指令规定的各
种操作。
④ 为执行下一条指令作好准备,即取出下一条指令地址。

1.3 微型计算机的数据存储和表示
内存由许多存储单元组成,每个内存单元可存放一组二进制数。在微机中规定每个
内存单元可存放 8 位二进制数,即一个内存单元存放一个字节的内容。每个存储单元有
一个唯一的地址。尽管存储器是按字节编址的,但实际操作中一个操作数可以是字节、
字、双字、四字等各种形式。

1.3.1 数据存储

位(bit)是计算机所能表示的最小最基本的数据单位,它指的是取值只能为 0 或
1 的一个二进制数值位。位作为单位时记作 b
字节(byte)是指相邻的 8 个二进制位。计算机中存储器单元的容量(内容)用字节
表示。 字节作为单位时记作 B
字:通常微机的字长有 8 位、16 位、32 位、64 位,所以数据的存放所占内存单元
的个数也不一样。例如 8086 中,一个字数据(16 位)占 2 个单元。
双字:即 2 个字(Double Word),如 8086 的字长为 16 位,则双字数据的大小为
32 位(4 个字节),在内存中存放需 4 个单元。
四字:即 4 个字的长度,以 8086 为例,4 字的大小为 16×4=64 位,即 8 个字节,
在内存中存放占 8 个单元。
存放内容
地址 二进制表示 十六进制表示

00000H 11000010 C2H

00001H 00011000 18H

…… …… ……

00008H 00010010 12H

00009H 00110100 34H

…… …… ……

FFFFFH 01110000 70H

图 1.2 内存单元的地址和内容示意图

1 Byte = 8 Bits
1 Word = 2 Bytes
1 Doubleword = 2 Words = 4 Bytes
1 Quardword = 4 Words = 8 Bytes

数据在计算机中存放的原则:低地址放低字节,高地址放高字节。

1.3.2 计算机中数的表示

计算机中的数是用二进制来表示的,数的符号也是用二进制表示的。把一个数连同
其符号位一起数码化的数,称为机器数。一般用最高位来表示符号,正数用 0 表示,负
数用 1 表示;使用正负号加其绝对值的表示方法,称为该数的真值。
在计算机中对带符号数的表示方法有原码、反码和补码三种形式。
1.原码
符号位用数码 0 表示正号,用数码 1 表示负号,数值部分按一般二进制形式表示其
绝对数值,这种数的表示法称为原码表示法。
X = +5,[X]原 =0 0000101
X = -5,[X]原 =1 0000101
2.反码
对于正数其反码形式与其原码相同,最高位 0 表示正数,其余位为数值位。
如:
X = +5 , [X]原 = [X]反 = 0 0000101
对于负数将其原码除符号位以外,其余各位按位取反,即可得到其反码表示形式。
如:
X = – 5 , [X]原 = 1 0000101 , [X]反 = 1 1111010
3.补码
正数的补码与其原码具有相同的表现形式,最高位为符号位,其余为数值位。
如:
X = +5 , [X]补 =0 0000101
负数的补码即为它的反码在最低位加上 1 。
如:
X =– 5 , [X]原 = 1 0000101 , [X]反 = 1 1111010 , [X]补 = 1 1111011
4. 补码转换
(1) 已知[X]原,如何求[X]补?
解:若为正数, [X]原 = [X]补。
若为负数,已知[X]原 ,则先求[X]反,再求[X]补。
(2) 已知[X]补,如何求[X]原?
解:若为正数, [X]原 = [X]补。
若为负数,[[X]补]补= [X]原。
(3) 已知[X]补,如何求[-X]补?
解:将[X]补连同符号位一同按位取反后末位加 1。
5. 结论
(1) 原码、反码、补码最高位都是符号位;
(2) 正数的原码、反码、补码相同;
(3) 原码、反码、补码的表示范围不同;
(4) 编程时不涉及码制,由硬件自动完成;
(5) 采用不同的码制,运算器和控制器的结构不同。
习题 1
1-1 计算机的主要性能指标有哪些?
1-2 什么叫微处理器?什么叫微型计算机?什么叫微型计算机系统?
1-3 简述微型计算机的硬件结构并说明各部件的主要功能。
第 2 章 微处理器的结构
8086微处理器(Microprocessor)简称μP,又称中央处理器(Central Processing Unit,
CPU),是采用大规模或超大规模集成电路(LSI/VLSI)技术做成的半导体芯片,主要完成
各种算术及逻辑运算,并控制计算机各部件协调地工作,是微机的核心部件。

2.18086 微处理器的结构

2.1.1 8086 的内部功能结构

16 位微处理器(图中为 8086 微处理器)可分成两个部分,一部分是执行部件(EU),


即执行指令的部分;另一部分是总线接口部件(BIU),与 8086 总线联系,执行从存储器
取指令的操作。微处理器分成 EU 和 BIU 后,可使取指令和执行指令的操作重叠进行。
EU 部分有一个寄存器堆,由 8 个 16 位的寄存器组成,可用以存放数据、变址和堆栈指
针、算术运算逻辑单元 (ALU)执行算术运算和逻辑操作,标志寄存器寄存这些操作结
果的条件。执行部件中的这些部件是通过数据总线传送数据的。总线接口部件也有一个
寄存器堆,其中 CS、DS、SS 和 ES 是存储空间分段的分段寄存器。IP 是指令指针。内
部通信寄存器也是暂时存放数据的寄存器。指令队列是把预先取来的指令流存放起来。
总线接口部件还有一个地址加法器,把分段寄存器值和偏置值相加,取得 20 位的物理
地址。数据和地址通过总线控制逻辑与外面的 8086 系统总线相联系。8086 CPU 的内
部从编程结构看是由总线接口部件 BIU(BusInterface Unit)和执行部件 EU(Execution Unit)
构成。
1.执行部件 EU
执行部件的功能就是负责从指令队列取指令并执行。从编程结构图可见,执行部件
由下列几个部分组成:
(1)算术逻辑单元 ALU
(2)标志寄存器 FLAG;
(3)数据暂存寄存器;
(4)通用寄存器组:包括 4 个 16 位位数据寄存器 AX、BX、CX、DX;4 个 16 位地
址指针与变址寄存器 SP, BP, SI, DI。
(5)EU 控制电路
2.总线接口部件 (BIU)
总线接口部件根据执行部件的请求,负责与存储器、I/O 端口传送数据。由下列各
部分组成:
(1)4 个段地址寄存器;
CS——16 位的代码段寄存器;
DS——16 位的数据段寄存器;
ES——16 位的扩展段寄存器;
SS——16 位的堆栈段寄存器;
(2)16 位的指令指针寄存器 IP;
(3)20 位的地址加法器;
(4)6 字节的指令队列缓冲器

图2.1所示为8086CPU 内部结构。


图 2.1
2.1 所示为 8086CPU
8086CPU 的功能结构内部结构
1.总线接口部件 BIU
功能:负责与 M、I/O 端口传送数据。
总线接口部件要从内存取指令送到指令队列;CPU 执行指令时,要配合执行部件
从指定的内存单元或者外设端口中取数据,将数据传送给执行部件;或把执行部件的操
作结果传送给指定的 M 或 I/O 口。总线接口部件 BIU 是 8086 与存储器或 I/O 口数据交
流的接口,通过 16 位双向数据总线和 20 位地址总线实现数据交流。
BIU 主要由下列各部分组成:
4 个 16 位段地址寄存器:代码段寄存器 CS,数据段寄存器 DS,附加段寄存器 ES
和堆栈段寄存器 SS。
16 位指令指针 IP:IP 用于存放下一条要执行指令的有效地址 EA(即偏移地址)。
20 位物理地址加法器:加法器用于将逻辑地址变换成读/写存储器所需的 20 位物
理地址,即完成地址加法操作。
6 字节的指令队列:当执行单元 EU 正在执行指令中,且不需要占用总线时,BIU
会自动进行预取下一条或几条指令的操作,并按先后次序存入指令队列中排队,由 EU
按顺序取来执行。
总线控制逻辑:总线控制逻辑用于产生并发出总线控制信号,以实现对存储器和
IO 端口的读/写控制。它将 CPU 的内部总线与 16 位的外部总线相连,是 CPU 与外部打
交道(读/写操作)必不可少的路径。
BIU的工作原理:
当 CPU 执行指令时,BIU 根据指令的寻址方式通过地址加法器将来自于段寄存器
的 16 位地址左移 4 位后与来自于 IP 寄存器或指令执行部件(EU)提供的 16 位偏移地址
(“段首地址:偏移地址”称为逻辑地址)相加形成指令在存储器中的一个 20 位的实际
地址(又称为物理地址),然后访问该物理地址所对应的存储单元,从中取出指令代码送
到指令队列缓冲器中等待执行。
2.执行部件EU
功能:负责指令执行。EU 不与系统总线相连于外界,只负责指令的执行。
执行的指令和数据从 BIU 的指令队列缓冲器取得,执行指令的结果或执行指令所
需的数据,都由 EU 向 BIU 发出请求,由 BIU 对存储器或外部设备存入或读取。通常
指令顺序执行,EU 从 BIU 指令队列缓冲器中取得执行的指令,连续执行指令 。
EU 包括下列几个部分:
4 个数据寄存器:AX、BX、CX、DX;4 个专用寄存器:BP、SP、SI、DI;1 个
标志寄存器(PSW);算术逻辑单元;EU 控制系统。
算术逻辑单元 ALU: 完成 16 位或 8 位的二进制数的算术逻辑运算,16 位加法器,
用于对寄存器和指令操作数进行算术或逻辑运算;计算 16 位的偏移地址 EA。经 ALU 处
理后,运算结果可通过内部总线送入通用寄存器或由 BIU 存入存储器。
标志寄存器 PSW:反映 ALU 执行运算后其结果的状态(不是结果本身);控制 CPU
的特定操作。9 个标志位,6 位状态标志位:OF、SF、ZF、AF、PF、CF;3 位控制标
志位:DF、IF、TF。
数据寄存器:用来暂存计算过程中所用到的操作数,结果或地址。可以用 16 位的
访问;可以用字节(8 位)形式访问, 它们的高 8 位记作 :AH 、 BH 、 CH 、 DH 。
它们的低 8 位记作: AL 、BL 、CL 、DL 。
专用寄存器:SP、BP、SI、DI 四个 16 位寄存器。只能按 1 6 位进行存取操作。对
存储器操作数寻址时,作为形成 20 位物理地址的偏移地址部分。段地址:只取段起始
地址高 16 位值。偏移地址:指在段内某内存单元物理地址相对段起始地址的偏移值。
EU 控制器:接受从总线接口单元的指令队列中取来的指令代码,经过指令译码形
成各种定时控制信号,协调执行指令规定的操作,以完成每条指令所规定的操作。
“流水线”结构
总线接口部件 BIU 和执行部件 EU 并不是同步工作的,两者的动作管理遵循如下
原则:
每当 8086 的指令队列中有 2 个空字节,BIU 就会自动把指令取到指令队列中。而
同时 EU 从指令队列取出一条指令,并用几个时钟周期去分析、执行指令。当指令队列
已满,而且 EU 对 BIU 又无总线访问请求时,BIU 便进入空闲状态。在执行转移、调用
和返回指令时,指令队列中的原有内容被自动清除,并要求 BIU 从新的地址重新开始
取指令,新取的第一条指令将直接经指令队列送到 EU 去执行,随后取来的指令将填入
指令队列缓冲器。

2.1.2 8086 的寄存器结构

8086 内部共有 14 个寄存器,其中 13 个 16 位的寄存器和一个 16 位的标志寄存器


PSW。可以分为 8 个通用寄存器,4 个段寄存器组,1 个标志,1 个 IP。8086CPU 的寄存
器结构如图 2.2 所示。
1.通用寄存器
通用寄存器可以分为两组:4 个数据寄存器和 2 个地址指针与 2 个变址寄存器。
(1) 数据寄存器
数据寄存器包括 AX、BX、CX、DX 等 4 个 16 位寄存器,数据寄存器 AX、BX、CX、
DX 均为 16 位的寄存器,它们中的每一个又可分为高字节 H 和低字节 L。即 AH、BH、CH、
DH 及 AL、BL、CL、DL 可作为单独的 8 位寄存器使用。

AH AL AX
BH BL BX
数据寄存器
CH CL CX
DH DL DX
通 用
堆栈指针 寄存器
SP 指针寄存器
BP 基数指针
SI 源变址 指针寄存器
DI 目的变址
IP 指令指针
控制寄存器
FLAG 状态标志
CS 代码段
DS 数据段 段寄存器
SS 堆栈段
ES 附加段

图 2.2 8086CPU 的寄存器结构

① AX(accumulator)称为累加器,常用于存放算术逻辑运算中的操作数。
② BX(base)称为基址寄存器,常用来存放访问内存时的基地址。
③ CX(count)称为计数寄存器,在循环和串操作指令中用作计数器。
④ DX(data)称为数据寄存器,在寄存器间接寻址的I/O指令中存放I/O接口的地
址。
(2) 地址指针和变址寄存器
指针寄存器和变址寄存器 SP、BP、SI、DI。这组寄存器在功能上的共同点是在对
寄存器的操作数寻址时,用以形成 20 位物理地址中的偏移地址。在任何情况下,它们
都不能独立地形成访问内存的地址码。
① SP(Stack Pointer)称为堆栈指示器,用来存放当前堆栈段中栈顶的偏移地址,
指示在堆栈段中栈顶的位置。段地址则由段寄存器 SS 提供。永远指向堆栈的栈顶。
② BP(Base Pointer)称为基址指针寄存器,是堆栈操作时的基址寄存器。指示在堆
栈段中一个数据区的基址位置。专门用于访问堆栈段中的某个数据。
③SI 称为源变址寄存器,用于源字符串操作数存放在数据段 DS 中的偏移量。
④DI 称为目的变址寄存器,用作存放目的字符串操作数在附加段 ES 中的偏移量。
以上 8 个 16 位通用寄存器在一般情况下都具有通用性,但是,某些通用寄存器又
规定了专门的用途。例如,在字符串处理指令中约定必须用 CX 作为计数器存放串的长
度。
2.段寄存器组
4个16位段寄存器CS、DS、SS、ES。用来识别当前可寻址的四个段。8086有20根地
址线,但内部寄存器最多可表示16位地址,无法实现lMB寻址。为了对全部1MB(20位)
空间寻址,8086对存储器进行逻辑分段,每个段最大64KB(16位),各段由段寄存器指
示。在 8088/8086 中的4个逻辑段:代码段、数据段、附加段和堆栈段的位置可由用户
指派,它们可以彼此分离,也可以首尾相连,还可以重叠或部分重叠。
(1) 代码段(Code Segment):存放当前执行程序所在段的基地址。其段地址和偏移
地址分别由段寄存器CS 和指令指示器IP 给出,形成下一条指令的实际物理地址。
(2) 数据段(Data Segment):存放当前数据段的起始地址。
(3) ES(Extra Segment):附加段是在进行字符串操作时作为目的区地址使用的一个
附加数据段。串操作时,系统默认源操作数和目的操作数分别位于数据段和附加段。
(4) SS(Stack Segment):堆栈操作所处理的操作数常存放在当前堆栈段中。操作数
的存放地址是由SS的内容左移四位再加上SP的内容而形成的。所谓“堆栈”是指这样
一段指定的内存区域:其存取原则是“先进后出”(First In Last Out,FILO)或“后进先
出”(Last In First Out,LIFO)。
3.控制寄存器
(1)指令指针 IP
作用是用 IP 指向当前需要取出的指令地址的偏移量。程序运行中,IP 的内容自动
做加 1 修改,使 IP 始终指向下一条将要执行的指令地址。注意: 程序员不能直接访问
IP 的内容。
(2)标志寄存器 PSW
标志寄存器 FR 也称程序状态字寄存器(简写为 PSW),16 位寄存器。由状态标志
FLAG、控制标志构成。只用了其中 9 位, 6 位状态标志, 3 位控制标志。标志寄存器的
具体格式如图 2.3 所示。
15 0

OF DF IF TF SF ZF AF PF CF

图 2.3 标志寄存器
状态标志位用来反映EU执行算术或逻辑运算的结果特征,6 个状态位如下:
CF(Carry Flag)进位标志。当加法运算有进位,减法运算有借位时,CF=1,否则CF=0。
AF(Auxiliary Carry Flag)辅助进位标志。在字节操作时,低4位向高4位有进位(加
法)或有借位(减法);在字操作时,低字节向高字节有进位(加法)或有借位(减法)时,
则AF=1,否则AF=0。
PF(Parity Flag)奇偶标志。当运算结果低8位“1”的个数为偶数时,PF=1,否则
PF=0。
ZF(Zero Flag)零标志。当运算结果为0时,ZF=1,否则ZF=0。
OF(Overflow Flag)溢出标志。在加或减运算中结果超出8位或l6位有符号数所能表
示的数值范围 (-128~+127或-32768~+32767)时,产生溢出,OF=1,否则OF=0。具
体讲,对于加运算,如果次高位(数值部分最高位)形成进位加入最高位,而最高位(符
号位)相加时(包括次高位的进位) 却没有进位输出;或者反过来,次高位没有进位加入
最高位,但最高位却有进位输出,都将发生溢出。因为这两种情况分别是;两正数相加,
结果超出了范围,形式上变成负数;两个负数相加,结果超出了范围,形式上变成了正
数。对于减运算,当次高位不需从最高位借位,但最高位却需借位(正数减负数,差超
出范围);或反过来,次高位需从最高位借位,但最高位不需借位(负数减正数,差超出
范围),也会溢出。溢出和进位是两个性质不同的标志,千万不能混淆。
SF(Sign Flag)符号标志。在进行符号数的算术运算时,当运算结果为负时,SF=1,
否则SF=0。
下面举例说明加减运算对状态标志的影响。
例如,假设前一条指令执行加法:
0010 O011 0100 0101
+ 0101 0010 0001 1001
-------------------------
0111 0101 0101 1110
那么,执行完这条指令后各标志是:SF=0,ZF=0,PF=0,AF=0,CF=0,OF=0。
假如前一条指令执行加法:
0101 0100 0011 1001
+ 0100 0111 0110 10lO
------------------------
1001 1011 1010 0011
那么,执行完这条指令后各标志是:SF=1,ZF=0,PF=1,AF=1,CF=0,OF=1。
假如前一条指令执行减法:
0101 0100 00ll 1010
- 1111 1110 OO00 0000
------------------------
0101 0110 O011 1010
那么,执行完这条指令后各标志是:SF=0,ZF=0,PF=1,AF=0,CF=1,OF=0。
例2-1:2个数相加后,分析各标志位的值

0 1 1 0 0 0 1 1 0 1 0 0 1 1 0 1

0 0 1 1 0 0 1 0 0 0 0 1 1 0 0 1
+
1 0 0 1 0 1 0 1 0 1 1 0 0 1 1 0

运算结果最高位为1 ∴SF=1
运算结果本身≠0 ∴ZF=0;
低8位中1的个数为偶数 ∴PF=1;
最高位没有进位 ∴CF=0;
第三位向第四位有进位 ∴AF=1;
次高位向最高位有进位 ,最高位向前没有进位,
∴OF = 1 ⊕ 0 = 1

控制标志有:
DF(Direction Flag)方向标志。可用指令预置。字符串操作指令执行时受它的控制。
当DF=0时,执行串操作指令,变址寄存器地址自动递增;当DF=1时,则变址寄存器地
址自动递减。即该标志位可控制地址朝增大的方向或减小的方向改变。
IF(Interrupt Enable Flag)中断允许标志。可用指令预置。当IF=1,CPU可响应
可屏蔽中断请求;若IF=0,CPU不响应可屏蔽中断请求。
TF(Trap Flag)陷阱标志。若TF=1,则CPU处于单步执行指令工作方式。每执行一
条指令就自动产生一次类型1的内部中断。IBM PC系统中,用系统调试程序DEBUG时,T
命令就是利用这种中断,服务子程序的功能是显示所有寄存器的当前值和将要执行的下
一条指令。
2.1.3 存储器的结构及访问
8086 CPU有20位地址线。计算机中存储信息的基本单位是1个二进制位,它可存储
信息0 或1。每8 个二进制位1 组,称为1 字节(Byte)。在存储器中是以字节为单位进
行存储信息的。存储器按字节组织,每个字节用唯一的地址码表示。存储器按字节组织,
每个字节用唯一的地址码表示。存放的信息若是八位的字节,将按顺序排列存放;当存
放的数为一个字时,则将字的高位字节放在高地址中,将低位字节存放在低地址中。
00020H开始的一个字单元的内容是43ABH。

地址 内容
00020H 0ABH
00021H 43H
00022H 65H
00023H 89H
00024H 0DCH

图 2.4 内存示意图

2.2 8086 的引脚信号及工作模式


8086 CPU 是Intel 公司的第三代微处理器,时钟频率有三种,5MHz 的8086,8MHz
的8086-1、10MHz 的8086-2。8086CPU采用40个引脚的双列直插式封装形式。8086 CPU
的引脚如图2.5所示。

2.2.1 8086 CPU 的工作模式


8086 有两种工作模式:最小模式和最大模式。8086CPU芯片的引脚在最小/最大工
作模式下的功能和作用有很大区别。最小模式系统中只有8086一个微处理器,总线控制
信号由8086产生。最大模式是指系统包含两个或多个微处理器,其中主处理器是8086,
其它为协处理器。数值运算协处理器8087 专门用于数值
运算,能实现多种类型的数值操作。输入输出处理器8089
的主要工作是数据的输入输出和数据格式转换,它有用
于输入/输出操作的指令系统,能够为指令输入/输出设
备工作, 8086 不再承担I/O 任务,提高了主处理器的
效率。
2.2.2 8086 两种工作模式下共同引脚说明
(1) AD15~AD0:CPU访问一次存储器或I/O端口称
完成一次总线操作,或执行一次总线周期。一个总线周
期通常包括T1 、T2 、T3 、T4 四个T状态。在每个状态CPU
将发出不同的信号。ADl5 ~ AD0 作为复用引脚,在总
线周期的 T1 状态,CPU 在这些引脚上输出要访问的存
储器或 I/0 端口的地址, T2 ~ T3 状态,如果是读
周期,则处于浮空 ( 高阻 ) 状态,如果是写周期,则
为传送数据。在中断响应及系统总线处于“保持响应”周
图 2.5 8086 的引脚

期时, ADl5 ~ AD0 都被浮置为高阻抗状态。
(2) A19/S6~A16/S3:分时复用的地址/状态线,具有输出、三态功能。
这4根引脚也是分时复用引脚。在总线周期的T1状态,用来输出地址的最高4位,
在总线周期的其他状态(T2 ,T3 和T4状态),用来输出状态信息。
其中,S6总是为0,表示8086CPU当前与总线相连。
S5 表明中断允许标志的当前设置。如果IF=l,则S5 =1,表示当前允许可屏蔽
中断;如果IF=0,则S5 =0,表示当前禁止一切可屏蔽中断。
S4 和S3 状态的组合指出当前正使用哪个段寄存器,具体规定如表2.1所示。
当系统总线处于“保持响应”周期时, A19/S6 ~ Al6/S3 被置为高阻状态。

表 2.1 S4 和 S3 的组合及对应含义
S4 S3 当前正使用的段寄存器

0 0 附加段寄存器

0 1 堆栈段寄存器

1 0 代码段寄存器或未使用任何段寄存器

1 1 数据段寄存器
(3) BHE /S7(Bus High Enable/Status):高8位数据总线允许/状态复用引脚,三
态输出,低电平有效。
BHE =0 表示数据总线高8位AD15~AD8 有效,低8位数据线AD7~AD0为高阻态;若
BHE =1,则8086 使用了低8位数据线(AD7~AD0),而高8 位AD15~AD8 数据线为高阻态。
与最低位数据线AD0配合共同表示数据总线的使用情况,见表2.2。

表 2.2 BHE 和 AD0 的组合及对应含义


BHE AD0 当前正使用的段寄存器

0 0 16 位数据总线有效,传送一个字

0 1 高 8 位数据总线有效,传送一个字节

1 0 低 8 位数据总线有效,传送一个字节

1 1 无效

(4)RD:当RD 为低电平有效时,表示当前CPU 正在对存储器或I/O 端口进行读操


作。具体是读存储器还是I/O 端口,则要看M/ IO 信号的状态,若其为高电平,表示读
存储器;若其为低电平,表示读I/O 端口。
(5) READY:准备就绪信号,输入,高电平有效。
READY=1 时,表示CPU 访问的存储器或I/O 端口已准备好传送数据,马上可以
进行读/写操作。CPU 在总线周期的T3状态检测READY 信号,若发现其无效,CPU 自
动插入一个或多个等待状态TW,直到READY信号变为高电平为止。
(6) TEST :测试信号,输入,低电平有效。
当CPU 执行WAIT 指令时,每隔5 个时钟周期对TEST 进行一次测试,若测试到
TEST 无效,则CPU 处于空闲等待状态,直到TEST变为有效的低电平,CPU 才结束
等待状态继续执行后续指令。TEST 引脚用于多处理器系统中,实现8086 与协处理器
间的同步。
(7) INTR(Interrupt Request):高电平有效。当INTR信号变为高电平时,表示外
部设备有中断请求,CPU在每个指令周期的最后一个T状态检测此引脚,一旦测得此引脚
为高电平,并且中断允许标志位IF=1,则CPU在当前指令周期结束后,转入中断响应周
期。
(8) NMI(No-Maskable Interrupt): 该信号边沿触发,上升沿有效。此类中断请
求不受中断允许标志IF的影响,也不能用软件进行屏蔽。所以该引脚上由低到高的变化,
就会在当前指令结束后引起中断。NMI中断经常由电源掉电等紧急情况引起。
(9) RESET:高电平有效,至少要保持 4个时钟周期的高电平,才能停止CPU的现行
操作,完成内部的复位过程。在复位状态,CPU内部的寄存器初始化,除CS=FFFFH外,
包括IP在内的其余各寄存器的值均为0。故复位后将从FFFF:0000H的逻辑地址,即物理
地址FFFF0H处开始执行程序。一般在该地址放置一条转移指令,以转到程序真正的入口
地址。
(10) CLK(Clock):主时钟信号,输入。CLK 输入时钟为微处理器提供基本的定时
脉冲,该脉冲最好具有33%的占空比。CPU 可使用的时钟频率随芯片型号不同而异,8086
为5MHz,8086-1 为10MHz,8086-2 为8MHz,8088 为4.77MHz。
(11) MN/MX(Minimum/Maximum):工作方式选择信号,输入。MN/MX=1,CPU 工
作在最小模式下;MN/MX=0,CPU 工作在最大模式下。
(12) 电源线Vcc 和地线GND:8086 只需单一的(+5±0.1)V 电源,由Vcc 端输入,
GND是接地端。
2.2.3 最小模式下引脚
为尽可能适应各种使用场合,在设计 8086CPU 芯片时,使它们可以在两种不同的
模式下工作,即最大模式和最小模式。所谓最小模式,就是微型计算机系统中只有 8086
或 8088 一个微处理器。在这个系统中,所有的总线控制信号直接由 CPU 提供。要使 8086

工作在最小模式下,只需将 8086CPU 的 MN/ 引脚接+5V。

MN/MX 端接+5V, CPU 工作在最小模式。需要一片 8284A,作为时钟信号发生器;


需要三片 8282 或 74LS273,用来作为地址信号的锁存器;需用 2 片 8286/8287 作为总
线收发器,增加数据总线的驱动能力。
图 2.6 8086 最小模式下的典型配置
第 24~31 脚在最小模式下含义如下:

(1) M/ IO (Memory/Input and Output) 存储器或 I/O 端口选择信号,三态输出。

这是 CPU 工作时会自动产生的输出信号,用来区分 CPU 当前是访问存储器还是访


问端口。当 为高电平时,表示 CPU 当前访问存储器;当 为低电平时,表示
当前 CPU 访问 IO 端口。 信号一般在前一个总线周期的 T4 状态就可以产生有效
电平,在新总线周期中, 一直保持有效直至本周期的 T4 状态为止。在 DMA 方式
时, 为高阻状态。

(2) WR (Write) 写信号,三态、输出。

在最小模式下作为写信号, WR =0 低电平有效时,表示 CPU 当前正在对存储器或 I

/O 端口进行写操作,由 M/ IO 来区分是写存储器还是写 I/O 端口。对任何总线“写”

周期, WR 只在 T2,T3,TW 期间有效。在 DMA 方式时, WR 被置成高阻状态。

(3) INTA (Interrupt Acknowledge):中断响应信号,输出,低电平有效。

在最小模式下, INTA 是CPU响应可屏蔽中断后发给请求中断的设备的回答信号,


是对中断请求信号INTR的响应。CPU的中断响应周期共占据两个连续的总线周期,在

中断响应的每个总线周期的T2、T3和TW期间 INTA 引脚变为有效低电平。第一个 INTA 负

脉冲通知申请中断的外设,其中断请求已得到CPU响应;第二个负脉冲用来作为读取中
断类型码的选通信号。外设接口利用这个信号向数据总线上送中断类型码。这个信号是
CPU 对外设发来的INTR 信号的响应信号。
(4) ALE(Address Latch Enable) 地址锁存允许信号,输出,高电平有效。
在最小模式下,是 8086CPU 提供给地址锁存器 8282/8283 的控制信号,在任何一
个总线周期的 T1 状态,ALE 输出有效电平(实际是一个正脉冲),以表示当前地址/数据、
地址/状态复用总线上输出的是地址信息,并利用它的下降沿将地址锁存到锁存器。ALE
信号不能浮空。

(5) DT/ R (Data Transmit/Receive) 数据发送/接收控制信号,三态输出。

此信号用于控制数据收发器的传送方向。在使用8286/8287作为数据总线收发器时,

8286/8287的数据传送方向由DT/ R 控制。DT/ R =1时,数据发送;DT/ R =0时,

数据接收。在DMA方式时,DT/ R 为高阻状态。此信号只用于最小模式。

(6) DEN (Data Enable) 数据允许信号,三态输出,低电平有效。

作为双向数据总线收发器8286/8287的选通信号。它在每一次存储器访问或I/O访
问或中断响应周期有效。此信号只用于最小模式。在DMA 方式时, DEN 为悬空状态。
(7) HOLD(Hold Request):总线保持请求信号,输入,高电平有效。
该信号是最小模式系统中除主 CPU(8086/8088)以外的其他总线控制器,如 DMA 控
制器申请使用系统总线请求信号。
(8) HLDA(Hold Acknowledge):总线请求响应信号,输出,高电平有效。
该信号是对HOLD的响应信号。当CPU测得总线请求信号HOLD引脚为高电平,如
果CPU又允许让出总线,则在当前总线周期结束时,T4状态期间发出HLDA信号,表示
CPU放弃对总线的控制权,并立即使三条总线(地址总线、数据总线、控制总线,即所
有的三态线)都置为高阻抗状态,表示让出总线使用权。
2.2.4 最大模式和系统组成

所谓最大模式,就是微型计算机系统中包含有两个或多个微处理器,其中一个主处
理器是 8086 或 8088 微处理器,其它处理器称为协处理器,它们协助主处理器工作。
常用的协处理器有 8087 协处理器和 8089 协处理器。前者是专用于数值运算的处理器;
后者是专用于控制输入/输出操作的协处理器。要使 8086CPU 按最大模式工作,只需 将

MN/ 引脚接地即可。
图 2.7 是 8086 系统在最大模式下的典型配置。

图 2.7 8086 在最大模式下的典型配置


从图 2.7 可以看到,在最大模式下,除了 8282 锁存器和 8286 数据收发器外,还增
加了 8288 总线控制器。8288 对 CPU 发出的控制信号进行变换和组合,以获得对存储器
和 I/O 端口的读/写信号及对锁存器 8282 和总线收发器 8286 的控制信号。

2.3 8088 和 8086 的比较


8088 是 Intel 公司继 8086 之后推
GND 1 40 VCC
A 14 2 39 A 15 出的简化版。IBM 公司采用 8088CPU 于
A 13 3 38 A 16 /S3 1981 年推出了 IBM PC 机,由此开创了
A 12 4 37 A 17 /S4
个人计算机的新时代,因此可以说个人
A 11 5 36 A 18 /S5
A 10 6 35 A 19 /S6 计算机的第一代 CPU 是从 8088CPU 开始
A9 7 34 SSO(HIGH) 的。准十六位的 8088 CPU 是继 8086 之
A8 8 33 MN/MX
AD7 9 32 RD
后推出的,它与 8086 CPU 具有类似的
AD6 10 31 HOLD (RQ/GT0 ) 体系结构。两者的执行部件 EU 完全相
AD5 11 30 HLDA (RQ/GT1 ) 同,其指令系统,寻址能力及程序设计
AD4 12 29 WR(LOCK)
AD3 13 28 IO/M(S2 ) 方法都相同,所以两种 CPU 完全兼容。
AD2 14 27 DT/R(S1 ) 这两种 CPU 的主要区别,归纳起来有以
AD1 15 26 DEN(S0 )
下几方面:
AD0 16 25 ALE(QS0)
NMI 17 24 INTA(QS1)
INTR 18 23 TEST
CLK 19 22 READY
GND 20 21 RESET

图 2.8 8088 的引脚


2.3.1 外部数据总线位数的差别

8086 CPU 的外部数据总线有 16 位,在一个总线周期内可输入/输出一个字(16 位


数据),便系统处理数据和对中断响应的速度得以加快;而 8088 CPU 的外部数据总线为
8 位,在一个总线周期内只能输入/输出一个字节(8 位数据)。

2.3.2 指令队列容量的差别

8086 CPU 的指令队列可容纳 6 个字节,且在每个总线周期中从存储器中取出 2 个


字节的指令代码填入指令队列,这可提高取指操怍和其它操作的并行率,从而提高系统
工作速度。而 8088 CPU 的指令队列只能容纳 4 个字节,且在每个总线周期中只能取一
个字节的指令代码,从而增长了总线取指令的时间,在一定条件下可能影响取指令操作
和其它操作的并行率。

2.3.3 引脚特性的差别

两种 CPU 的引脚功能是相同的,但有以下几点不同:
(1)AD15~AD0 的定义不同:
在 8086 中都定义为地址/数据复用总线;而在 8088 中,由于只需用 8 条数据总线,
因此,对应于 8086 的 AD15~AD8 这 8 条引脚定义为 A15~A8,只作地址线使用。
(2)34 号引脚的定义不同:
在 8086 中定义为 BHE/-信号而在 8088 中定义为 SS0/-,它与 DT/R/-,IO/M/-
一起用作最小方式下的周期状态信号。
(3)28 号引脚的相位不同:
在 8086 中为 M/IO/-而在 8088 中被倒相,改为 IO/M/-,以便与 8080/8085 系
统的总线结构兼容。

2.4 时序概念

时序是计算机操作运行的时间顺序。微机系统的工作,必须严格按照一定的时
间关系来进行,CPU 定时所用的周期有三种,即指令周期、总线周期和时钟周期。
1.指令周期
一条指令从其代码被从内存单元中取出到其所规定的操作执行完毕,所用的时
间,称为相应指令的指令周期。由于指令的类型、功能不同,因此,不同指令所要完成
的操作也不同,相应地,其所需的时间也不相同。也就是说,指令周期的长度因指令的
不同而不同。
2.总线周期
(1).微处理器是在时钟信号 CLK 控制下按节拍工作的。8086/8088 系统的时钟
频率为 4.77MHz,每个时钟周期约为 200ns。
(2).由于存储器和 I/O 端口是挂接在总线上的,CPU 对存贮器和 I/O 接口的访问,
是通过总线实现的。通常把 CPU 通过总线对微处理器外部(存贮器或 I/O 接口)进行一
次访问所需时间称为一个总线周期。一个总线周期一般包含 4 个时钟周期,这 4 个时钟
周期分别称 4 个状态即 T1 状态、T2 状态、T3 状态和 T4 状态,必要时,可在 T3、T4
间插入一个至数个 Tw。
T1 状态 ——输出存储器地址或 I/O 地址。
T2 状态 ——输出控制信号。
T3 和 Tw 状态 ——总线操作持续,并检测 READY 以决定是否延长时序。
T4 状态 ——完成数据传送
总线周期:总线周期通常指的是 CPU 完成一次访问 MEM 或 I/O 端口操作所需要的时
间。一个总线周期由几个时钟周期组成。
3.时钟周期
时钟周期是微机系统工作的最小时间单元,它取决于系统的主频率,系统完成任何
操作所需要的时间,均是时钟周期的整数倍。时钟周期又称为 T 状态。时钟周期是基本
定时脉冲的两个沿之间的时间间隔,而基本定时脉冲是由外部振荡器产生的,通过 CPU
的 CLK 输入端输入,基本定时脉冲的频率,我们称之为系统的主频率。例如 8088CPU
的主频率是 5MHz,其时钟周期为 200ns。一个基本的总线周期由 4 个 T 状态组成,我们

分别称为 4 个状态,在每个 T 状态下,CPU 完成不同的动作。

2.5 8086CPU 最小方式时的总线周期时序分析

1.读总线周期时序
在读总线周期内,8086CPU 可以完成取指令码或读存储器或读 I/O 端口数据的操
作。
在读总线周期的 T1 状态期间,CPU 输出 20 位地址信号、BHE 信号(访问 I/O
端口时,输出低 16 位地址;若为 8088CPU,BHE/S7 引脚输出 SS 信号)和 ALE 信
号。在 ALE 的后沿(下降沿),地址 A0~A19 以及 BHE 已在 CPU 的局部总线上稳定
可用。ALE 的后沿将地址信息和 BHE 信号锁存入地址锁存器 8282。对 8086CPU,BHE
和 A0 用来指示只读数据总线高字节、低字节或同时读数据总线高、低字节。
从 T1 至 T4,M/IO(对 8088CPU 为 IO/M)用来指示是读存储操作还是读 I/O
端口操作,而 DT/R 始终为低电平,它被用来控制 8286 的传送方向。在 T2 状态,CPU
撤消地址输出,
AD16~AD0 处于高阻状态,而 A19/S6~A16/S3,BHE/S7 输出状态信息 S7~
S3;同时 RD 和 DEN 信号变为有效(低电平),RD 用于指示被寻址的单元或端口将数
据送入数据总线,而 DEN 信号用来使 8286 处于允许数据传送状态,如果存储器或 I/
O 可立即完成数据传送,即能够于 T3 期间将数据放到总线上,而无需 CPU 进入等待状
态。
CPU 是在 T4 状态开始时从 AD15~AD0(对 8088 是从 AD7~AD0)读入数据的,
并在 T4 期间使 RD 和 DEN 信号处于无效状态。随着 RD 信号无效,被寻址单元或端口
终止数据输出。
最小模式下存储器读周期时序如图 2.9 所示。
图 2.9 最小模式下存储器读周期时序

2.写总线周期时序
8086CPU 写总线周期与读总线周期有许多类似之处。对于写总线周期来说,在
AD15~AD0 上不存在输出地址方式与输入数据方式转换的过渡时间。在撤消地址后,
立即可把数据送上 AD15~AD0,而且,必须给出写信号 WR 代替读信号 RD。因此,
WR 信号在 T2 状态变成有效低电平。由于是写操作,DT/R 应为高电平,DEN 为低电
平,8286 处于正向传送。如果存储器或 I/O 接口可以完成操作写入而不需要等待状态
CPU 在 T4 状态前期使 WR 变为无效,并撤消输出的数据信号。不管是读总线周期,还
是写总线周期,DEN 在 T4 状态都变为无效,从而关闭收发器 8286。
在读总线周期或写总线周期中,若所使用的存储器或外设的工作速度较慢,不能满
足上述的基本时序的要求,则可利用 READY 信号产生电路产生 READY 信号,并经
8284 同步后加到 CPU 的 READY 线上,使 CPU 在 T3 和 T4 之间插入一个或几个 TW
状态,来解决 CPU 与存储器或外设之间的时间配合。8086 在 T3 状态的开始测试 READY
线,若发现 READY 信号为有效高电平,T3 状态之后即进入 T4 状态;若发现 READY
信号为低电平,则在 T3 状态结束后不进入 T4 状态,而插入一个 TW 状态。以后在每
一个 TW 状态的开始,都测试 READY 线,只有发现它为有效高电平时,才在这个 TW
状态结束后进入 T4 状态。
最小模式下存储器写周期时序如图 2.10 所示。
图 2.10 最小模式下存储器写周期时序
习题 2

2-1 8086/8088 CPU 中有哪些寄存器?其主要作用是什么?


2-2 解释逻辑地址、偏移地址、有效地址、物理地址的含义,8086 存储器的物理地址是
如何形成的?怎样进行计算?
2-3 8086CPU 与 8088CPU 的主要区别?
2-4 有两个 16 位的字 31DAH、5E7FH,它们在 8086 系统存储器中的地址为 00130H 和
00135H,试画出它们的存储器示意图。
2-5 什么是段基值?什么是位移量?它们之间有何联系?
2-6 若 CS 为 0A000H,试说明现行代码段可寻址物理空间的范围。
2-7 8086CPU 的 FLAG 寄存器中,状态标志和控制标志有何不同?程序中是怎样利用这
两类标志的?
2-8 某指令对应当前段寄存器 CS=FFFFH,指令指针寄存器 IP=FF00H,此时,该指令
的物理地址为多少?指向这一物理地址的 CS 值和 IP 值是唯一的吗?试举例说明
2-9 设现行数据段位于存储器 0B0000H~0BFFFFH 单元,DS 段寄存器内容为多少?
2-10 在 8086CPU 中,已知 CS 寄存器和 IP 寄存器的内容分别为如下所示,试确定其物理
地址. CS=1000H IP=2000H
第 3 章 8086 CPU 指令系统
8086到双核芯片,这些CPU内部的微体系结构变化很大,但这些芯片的指令都是在
8086的指令系统基础上形成,保持808686指令系统的兼容性,成为8086的的母集,这就
形成了,兼容的指令系统。

3.1 指令格式与寻址方式

3.1.1 指令格式
微机指令系统通常由几十种或百余种指令组成。8086的指令长度可在1~6字节的范
围。其中第一个和第二个为基本字节,第三到六个字节将根据不同指令作相应的安排。
每种指令主要由操作码和操作数两部分组成。操作码是核心部分,它规定了计算机将要
执行的操作;操作数指明了命令执行的对象本身或对象所在的地址。
1.操作码字段
该字段指示计算机所要执行的操作类型,由一组二进制代码表示,在汇编语言中又
用助记符代表。
2.操作数字段
该字段是指出指令执行的操作所需的操作数。在操作数字段中,可以是操作数本身,
或是操作数地址或是操作数地址的计算方法。

3.1.2 寻址方式
8086 的寻址方式:说明操作数的来源以及存储器操作数地址构成的方法,根据指
令中操作数所存放位置的不同,8086 CPU 的寻址方式有两类:数据寻址方式和转移地
址寻址方式。根据操作数据存放于计算机不同位置可以分为:存放于 CPU 内部的寄存
器中;存放于存储器单元内;来自 I/O 端口;由操作码隐含地指定;由指令直接给出操
作数等。
1.数据的寻址方式
1.立即数寻址
所谓立即数是指具有固定数值的操作数,即常数。它可以是字节或字( 8 位或 16
位)存放时,该操作数跟随指令操作码一起存放在指令区,故又称为指令区操作数。
例如:MOV AX,3000H
例3-1:
MOV AL,0CBH ;执行后,(AL)=0CBH。
MOV BX ,1314H ;执行后,(BX)=1314H,其中:(BH)=13H,(BL)=14H。
这种寻址方式只能用于源操作数,且因操作数是直接从指令中取得,不执行总线周
期,所以这种寻址方式的显著特点是执行速度快,主要用来给寄存器赋初值。

2.寄存器寻址
操作数包含在CPU的内部寄存器中,寄存器操作数既可作为源操作数,又可作为目标
操作数。
对于16 位操作数,寄存器可以是AX、BX、CX、DX、SI、DI、SP 或BP;
对于8 位操作数,寄存器可以是AL、AH、BL、BH、CL、CH、DL或DH
例如:MOV DS,AX
MOV AL,BH

例3-2:
指令执行前:(AX)=33B4H,(BX)=1234H MOV BX,AX
指令执行后:(BX)=33B4H (AX)保持不变。
这种寻址方式因为操作数在寄存器中,不需要访问存储器的运算速度较高。

3.存储器寻址方式
在存储器寻址方式中,用存储器寻址的指令,其操作数一般位于代码段,堆栈段,
附加段的存储器中,指令中给出的是存储器单元的地址或产生存储器单元地址的信息。
操作数存放在存储单元中,因此,在指令中可以直接或间接地微机原理与接口技术给出
存放操作数的有效地址EA,以达到访问操作数的目的。
3.1 直接寻址
在操作码后面直接给出操作数的 16 位偏移地址。这个偏移地址也称为有效地址
(EA)。它于指令操作码一起,存在内存的代码段。直接寻址,是在指令的操作码后面
直接给出操作数的 16 位偏移地址,所以直接寻址是对存储器进行访问时可采用的最简
单的方式。
8086 执行某种操作时,预先规定了采用的段和段寄存器,即有基本的段约定,如
果要改变默认的段约定(即段超越),则需要在指令中明确指出来
例如: MOV AX,DS:[2000H];
MOV AX,[2000H] ;数据段
MOV BX,ES:[3000H] ;段超越,操作数在附加段,
即绝对地址=(ES)*16+3000H

例3-3:
MOV AX , [3344H ] ;将DS段中3344H单元内容送至AX
MOV AX , ES:[7788H ] ;将ES段中7788H单元内容送至AX
注意:
①直接寻址方式适用于处理单个变量。
②直接寻址方式隐含的段寄存器是 DS, 8086/8088允许段跨越,即允许使用 CS
SS ES作为段寄存器,这时,必须在指令中特别标明。
在汇编语言中,有时也用一个符号来代替数值以表示操作数的偏移地址,一般将这
个符号称为符号地址,上例中若用 DATA 代替偏移地址 3400H ,则该指令可写成:
MOV BX , ES : DATA
其中 DATA 字母是符号地址, DATA 必须在程序的开始处予以定义。

3.2 寄存器间接寻址
在寄存器间接寻址方式中,操作数在存储器中,操作数地址的16位偏移量包含在BP、
BX、SI、DI寄存器中。操作数存放在存储区中,其有效地址EA为一个由指令规定的基
址寄存器(BP、BX)或变址寄存器(SI、DI)的内容。
例如: MOV AX, [SI] 操作数地址是:(DS)*16+(SI)
① 若选择SI、DI、BX作为间接寻址
操作数一般在现行数据段区域中,用(DS)作为段地址,则通常操作数在现行数据段
区域中,即数据段寄存器(DS)*16加上SI、DI、BX中的16位偏移量,为操作数的地址,
例如: MOV AX, [SI] 操作数地址是:(DS)*16+(SI)

② 以寄存器BP间接寻址,则操作数在堆栈段区域中,用SS寄存器的内容作为段地址。
即堆栈段寄存器(SS)*16与BP的内容相加作为操作数的地址,
例如:MOV AX,[BP] 操作数地址是:(SS)*16+(BP)

③ 若在指令中规定是段超越的,指令中可以指定段跨越前缀来取得其他段中的数据。
例如: MOV AX,DS:[BP] 操作数地址是:(DS)*16+(BP)

例3-4: MOV ES:[DI], AX


MOV DX, DS:[BP]
例3-5: MOV BX , [ SI] ;将[SI]为有效地址的存储器单元中的操作数送至BX,;默认
DS为当前段基寄存器;MOV [ BP ] , AX ;将AX的内容送至以[BP]为有效地址的存储
器单元中;默认SS为当前段基寄存器
例3-6:
已知: MOV BX,[DI] (DS)=6000H (DI)=2300H (62300H)
=51A2H
则: PA=62200H (BX)=51A2H
3.3 寄存器相对寻址
寄存器相对寻址( Register Relative Addressing )的特点是,操作数的有效地址 EA
(即偏移量)是一个基址或变址寄存器的内容加上指令中指定的 8 位或 16 位位移量。
当使用 BX 时,缺省的段寄存器为 DS ;当使用 BP 时,缺省的段寄存器为 SS ,当
然也允许使用段跨越前缀的方式寻址。。
例 3-7: MOV AX, COUNT [BP]
或 MOV AX, [COUNT+BP]
或 MOV AX, COUNT+[BP]
COUNT 为 16 位位移量。
指令执行前: (SS)=5500H,
(BP)=3200H,
COUNT=2000H,
(AX)=6734H
(5A200)=5548H
指令执行后:EA=5200H
PA=5A200H
(AX)=5548H

3.4 基址变址寻址
把BX和BP看成是基址寄存器,把SI、DI看着是变址寄存器,把一个基址寄存器(BX
或BP)的内容加上一个变址寄存器(SI或DI)的内容,再加上指令中指定的8位或16位
偏移量(当然要以一个段寄存器作为地址基准)作为操作数的偏移地址,这种寻址方式
中操作数的有效地址EA等于其偏移地址由(基址寄存器)+(变址寄存器)+相对偏移
量形成。
例如:MOV AX,[BX][SI] 或 MOV AX,[BX+SI]
例3-8 :MOV AX, [BX][SI]或 MOV AX, [BX+SI]
执行指令前: (DS)=3800H, (BX)=1456H, (SI) =1234H (3A68AH)=4567H
执行指令后: EA=268AH PA=3A68AH (AX)=4567H
注意,该寻址方式的基址寄存器只能是BX 或BP,而变址寄存器只能是SI或DI。
3.5 基址变址相对寻址
这种寻址方式中操作数的有效地址是一个基址寄存器和一个变址寄存器的内容和
8 位或 16 位位移量这三者之和。有效地址EA是由一个基址寄存器(BX 或BP)与一个
变址寄存器(SI或DI)的内容之和,与一个由指令中指定的位移量相加后得到的。当使
用基址寄存器 BX 时,缺省的段寄存器是 DS ;当使用基址寄存器 BP 时,缺省的段寄
存器是 SS 。
基址变址相对寻址方式的操作数在汇编语言中的书写可采用多种形式。
例如:MOV AX , [BX+SI+0080H] ,
即将 BX 与 SI 中的内容与 0080H 相加作有效地址。
例3-9: MOV AX, MASK[BX][DI]
或MOV AX, MASK [BX+DI]
或MOV AX,[MASX+BX+DI]
执行指令前:(DS)=3500H (BX)=5346H (DI)=1500H MASK=1234H (32A7AH)=4455H
执行指令后:EA=6846H PA=3B846H (AX)= 4455H
例 3-10
设 BX=2233H, DI=1000H ,DS=2200H ,默认 DS 作为操作数对应的段寄存器
( 假定没使用段前缀 ) ,试指出下列指令的寻址方式,并写出其操作数的有效地址和
物理地址。
(1) MOV AX , [3A3BH]
(2) MOV AX , [BX]
(3) MOV AX , [BX+3A3BH]
(4) MOV AX , [BX+DI]
(5) MOV AX , [BX+DI+3A3BH]
解:
(1)直接寻址
有效地址 =3A3BH , 物理地址 =22000H+3A3BH=25A3BH
(2)寄存器间接寻址
有效地址 =2233H ,物理地址 =22000H+2233H=24233H
(3)寄存器相对寻址
有效地址 =2233H+3A3BH=5C6EH ,物理地址 =22000H+5C6EH=26C6EH
(4)基址变址寻址
有效地址 =2233H+1000H=1123H ,物理地址 =22000H+3233H=25233H
(5)相对基址变址寻址
有效地址 =2233H+1000H+3A3BH=6C6EH ,物理地址 =22000H+6C6EH=28C6EH

3.2 8086/8088CPU 指令系统


3.2.1 数据传送类指令
这类指令用以实现CPU的内部寄存器之间、CPU内部寄存器和存储器之间、CPU累加
器AX或AL和I/O端口之间的数据传送。
1.通用数据传送指令
(1)传送指令 MOV
指令格式:MOV 目的操作数 , 源操作数
功能:它表示把源操作数,传送给目的操作数,源操作数不变,目的操作数被源操
作数所替换。传送指令每次可以传送一个字节或一个字,它可以实现 CPU 的内部寄存
器之间的数据传送、寄存器和内存之间的数据传送,还可以将立即数送给内存单元或者
CPU 内部的寄存器。
实现:寄存器 ↔ 寄存器/存储器之间;
立即数→寄存器/存储器
段寄存器↔寄存器/存储器之间的数据传送。
①CPU内部通用寄存器及段寄存器之间的数据传送(除了码段寄存器CS和指令指针
IP以外)。通用寄存器之间任意传送,段寄存器之间不能传送。
例: MOV DL,CH ; 8位寄存器→ 8位寄存器
MOV AX,DX ; 16位寄存器→ 16位寄存器
②立即数传送至CPU内部通用寄存器组(AX、BX、CX、DX、BP、SP、SI、DI)。 用
于给寄存器赋初值。不能直接给段寄存器赋值
例:MOV CL,24H ;立即数→8位寄存器
MOV AX,A3FFH ;立即数→16位寄存器
③CPU内部通用寄存器及段寄存器(除CS和IP外)与存储器(所有寻址方式)之间
数据传送。可以实现一字节或一个字的传送。 段寄存器,存储单元之间不能直接传送
例:MOV MEM , AX ; 累加器→存储器,直接寻址
MOV MEM ,DS ;段寄存器→存储器,直接寻址
MOV DISP[BX] ,CX ;寄存器→存储器,变址寻址
【注1】两个mem之间不能直接进行数据传送或其他操作。
【注2】立即数不能做目的操作数,段寄存器CS不能做目的操作数。
【注3】当源操作数为段寄存器时,不能用立即数做目的操作数。
(2)交换指令XCHG
指令格式:XCHG 操作数1 ,操作数2
功能:这是—条交换指令,把一个字节或一个字的源操作数与目的操作数相交换。
交换能在通用寄存器与累加器之间、通用寄存器之间、通用寄存器与存储器之间进行。
但段寄存器和立即数不能作为一个操作数,不能在累加器之间进行。
实现: 寄存器之间
寄存器和存储器之间
示例:例如: XCHG AL,CL
XCHG AX,DI
XCHG DATA[SI],DH
XCHG [BX],[DI] (错)
XCHG DS, AX (错)
例 设原CX=26FFH,AX=0780H。执行指令XCHG AX,CX后,CX = 0780H ,AX = 26FFH 。
【注1】立即数不能做XCHG指令的操作数。
【注2】该指令不能同时为存储器操作数。
【注3】该指令不能使用段寄存器操作数。
(3)堆栈操作指令PUSH/POP
指令格式:
PUSH 源操作数 ;SP ←(SP)-2 ,(SP)+1: (SP) ←(源操作数)
源操作数可以是CPU内部的16位通用寄存器、段寄存器(CS除外)和内存操作数(所有
寻址方式)。入栈操作对象必须是16位数。
例如:PUSH AX。
若给定(SP)=0BE8H,(SS)=2500H,(AX)=552BH,
则指令执行后(SP)=0BE6H,(25BE6H)=552BH。
POP 目的操作数 ;目的操作数 ←[(SP) +1: (SP)],SP ←(SP) + 2
功能:将数据弹出堆栈对指令执行的要求同入栈指令。
例如:POP AX
POP [BX]
这类指令格式简单.但使用时有几点必须注意:
【注1】堆栈操作指令中,有一个操作数是隐含的。该操作数就是(SP)指示的栈顶存储单
元;
【注2】8086堆栈都是字操作,而不允许对字节操作。因此PUSH AL是错误的;
【注3】 PUSH CS 是合法指令,可 POP CS 却是非法指令,执行 POP CS 将改变代码
段寄存器 CS 的内容,会导致 CPU 从一个与程序无关的新段中去取下一条指令,从而
使程序错误地运行。

2.地址传送指令
8086 /8088 提供三条:地址指针写入指定寄存器或寄存器对指令。
(1)装入有效地址LEA
指令格式:LEA reg16 , mem16
功 能:把源操作数的地址偏移量传送至目的操作数。指令的源操作数必须是存储器操
作数,目的操作数必须是寄存器操作数。
例如:设(BX)=010CH,(SI)=0330H LEA BX,[BX+SI+0F62H]
执行指令后: EA=(BX)+(SI)+0F62H=010CH+0330H+0F62H=139EH (BX)=139EH
LEA 指令中的目标寄存器必须是16位的通用寄存器,源操作数必须是一个存储器
注意:
设 BX=2000H , DS=5000H , [52050H]=66H , [61051H]=77H .
LEA BX , [BX+80H] ;(BX)=2080H
MOV BX , [BX+80H] ; (BX)=7766H
设 (DS)=2000H BUFFER=2000H (31000H)=3345H
LEA BX , BUFFER ; (BX)=1000H
MOV BX , OFFSET BUFFER ; (BX)=1000H

(2)装入远地址指针LDS/LES
指令格式:LDS reg 16, mem32
LES reg16 , mem32
功 能:完成一个地址指针的传送。地址指针包括段地址部分和偏移量部分。指令将段
地址送入DS或ES,偏移量部分送入一个16位的指针寄存器或变址寄存器。
例如: 假设: (DS)=2000H (22A30)=AB1FH (22A32)=2F00H
指令: LDS SI, [2A30H] 执行指令后: (SI)=AB1FH (DS)=2F00H
指令: LES BX, [2A30H] 执行指令后: (BX)=AB1FH (ES)=2F00H
3.3.2 算术运算类指令
8086/8088CPU的算术运算指令支持加、减、乘、除4 种基本运算。8086CPU 的算
术运算指令的执行结果都影响标志位。这些标志中的绝大多数可由跟在算术运算指令后
的条件转移指令进行测试,以改变程序的流程。因而掌握指令执行结果对标志的影响,
对编程有着重要的意义。
(1)加/减法指令
指令格式:ADD 目的操作数 , 源操作数 ;目的操作数  (目的操作数) + (源操作数)
SUB 目的操作数 , 源操作数 ;目的操作数  (目的操作数) − (源操作数)
功能:完成两个操作数加/减,结果送至目的操作数。目的操作数可以是累加器,任一
通用寄存器以及存储器操作数。指令按定义影响标志位: AF、CF、OF、PF、SF、ZF标志。
操作数和目标操作数不能同时为存储器,不能为段寄存器。
例:ADD DI,SI
ADD AX,[BX+2000H]
ADD [BX+DI],CX

SUB AX,BX
SUB SI,[DI+100H]
SUB AL,30H

例 MOV AX, 4453H ;(AX)= 4453H


ADD AX, 0FAFBH ;(AX)= 4453H+0FAFBH=3F4EH (13F4EH 其中的1进位到CF)
(2)带进位、借位的加/减法指令
指令格式:ADC 目的操作数 , 源操作数 ;目的操作数  (目的操作数) + (源操作数) +
(CF)
SBB 目的操作数 , 源操作数 ;目的操作数  (目的操作数) − (源操作数)
− (CF)
功能:完成两个操作数的带进位的加减运算,结果返回目标操作数。该指令常用
于多字节(即长度为两个或两个以上字)数据的加减法运算。指令按定义影响标志位:
AF、CF、OF、PF、SF、ZF标志。
(3)加“1”、减“1”指令
指令格式:INC 目的操作数 ;目的操作数  (目的操作数) + 1
DEC 目的操作数 ;目的操作数  (目的操作数)  1
功能:完成对指定的操作数加1,然后返回此操作数。此指令主要用于在循环程序中修
改地址指针和循环次数等。目的操作数可以是任意一个8位或16 位通用寄存器或存储单
元,但不能是立即数,且把操作数看作是无符号二进制数。指令执行的结果将影响PF、
AF、ZF、SF和OF,但不影响CF。操作数类型:可以是寄存器,存储器。不能是段寄
存器。
例如: INC SI ;修改地址指针
INC CX
DEC BYTE PTR [BX+100H]
DEC WORD PTR [DI]
INC DS ; 错
(3)求补指令
指令格式: NEG 目的操作数 ;
功 能:把操作数按位求反后末位+1。此指令影响标志 AF、CF、OF、PF、SF 和 ZF。CF:
操作数为 0 时求补,CF=0;一般使 CF=1. 若在字节操作时对-128,或在字操作时对
-32768 取补,则操作数没变化,但标志 OF 置位。
(目的操作数) ← 0FFFFH -(目的操作数)+1
例如: NEG AL
NEG MULRE
例: 已知 (AL)=67H,
则执行 NEG AL后:
(AL)=99H, CF=1
对一个操作数取补码相当于用0减去此操作数,故利用NEG指令可得到负数的绝对值。
例:若(AL)=0FEH,则执行 NEG AL后,
(AL)=02H,CF=1
(4)比较指令
指令格式:CMP 目的操作数 , 源操作数 ;(源操作数)-(目的操作数)
功 能:比较两个数之间的大小,但运算结果不返回目标操作数,而只将比较结果反映
在状态标志上。影响标志:AF、CF、OF、PF、SF、ZF。
例: CMP AX, AREA1
CMP [BX+5], SI
CMP WORD PTR [1234H],100H
比较指令主要用于比较两个数之间的关系。在比较指令之后,根据 ZF 标志即可判断两
者是否相等。
①若两者相等,相减以后结果为零,ZF 标志为 1,否则为 0。
②若两者不相等,则可在比较指令之后利用其它标志位的状态来确定两者的大小。
大小的比较:
如果是两个无符号数(如 CMP AX,BX)进行比较,则可以根据 CF 标志的状态判断两
数大小。若结果没有产生借位(CF=0),显然 AX≥BX;若产生了借位(即 CF=1),则 AX
<BX。

比较指令在使用时,一般在其后紧跟一条条件转移指令,判断比较结果的转向。
举例:比较AL、BL、CL中带符号数的大小,将
最小数放在AL中。
程序:
CMP AL,BL ;AL和BL比较
JNG BG ;若AL≤BL,则转
XCHG AL,BL ;若AL>BL,则交换
BG: CMP AL,CL ;AL和CL比较
JNG CG ;若AL≤CL,则转
XCHG AL,CL ;若AL>CL,则交换
CG: HLT

(5)乘法指令
进行乘法时: 8位*8位→16位乘积
16位*16位→32位乘积
指令格式: MUL 源操作数 ;AX   (源操作数) ×(AL) (字节乘法)
;DX:AX   (源操作数) ×(AX) (字乘法)
IMUL 源操作数 ;与MUL指令格式相同
功 能:指令MUL 和IMUL 分别用于无符号数的乘法和带符号数的乘法运算。它
们都只有一个源操作数,而目标操作数是隐含规定的:位数相乘,结果为16位数,放在
AX中;16位数相乘结果为32位数,高16位放在DX,低16位放在AX中。注意:源操作数不
能为立即数。
MUL指令例子:
MUL BL ;(AL)×(BL),乘积在AX中
MUL CX ;(AX)×(CX),乘积在DX,AX中
MUL WORD PTR [SI]
指令MUL 对标志位CF、OF 有影响,而对SF、ZF、AF、PF 不确定, 如果运算
结果的高半部分(在AH或DX中)为零,则CF=OF= 0,表示在AH 或DX 中所存的结果为有
效数字;否则CF=OF= 1,表示在AH 或DX 中结果为无效数字。
例:(AL) = 85H,(BL) = 3BH
MUL BL ; (AX) ← (AL)×(BL)
; 85H×3BH= 1EA7H
; (AX) = 1EA7H
; CF=OF=1
MUL指令例子:
IMUL CL ;(AX)←(AL)×(CL)
IMUL AX ; (DX,AX)←(AX)×(AX)
IMUL BYTE PTR[BX] ;(AX)←(AL)×([BX])
IMUL 指令要求两乘数都为有符号数(补码),且乘积也是补码表示的数,若乘
积的高半部分是低半部分的符号位的扩展(所谓符号位扩展,指结果为正时高半部分全
部扩展为 0 ,或结果为负时高半部分全部扩展为 1 ),则 OF=CF=0 ;否则 OF=CF=1 。
例:(AL) = 85H ,(BL) = 3BH
IMUL BL ; (AX)← (AL)×(BL)
; 85H=10000101B=-123D, 2AH=00101010B=59D
; (AX) =( -123D )× 59D= -7257D= =-1C59=E3A7H
; 由于 AH=E3H ≠ FFH,所以标志位CF=OF=1
(6)除法指令
指令格式: DIV 源操作数 ;AL   (AX) / (源操作数) 的商
;AH   (AX) / (源操作数) 的余数(字节除法)
;AX   (DX:AX) / (源操作数) 的商
;DX   (DX:AX) / (源操作数) 的余数(字除法)
IDIV 源操作数 ;与DIV指令格式相同
功 能:指令DIV和IDIV分别用于无符号数的除法和带符号数的除法运算。它们都
只有一个源操作数,而目标操作数是隐含规定的:在除法运算中如果除数是 8 位的,
则要求被除数是 16 位;如果除数是 16 位的,则要求被除数是 32 位。
指令例子:
DIV CL
DIV WORD PTR [DI]
若 AX=0B67H , DX=0000H , CX=0210H 。则执行指令 DIV CX 之后,将商放在 AX 中,
余数存于 DX ,即 AX=0005H, DX=0117H

IDIV CX
IDIV BYTE PTR [DI]
注:若除数为零或AL中商大于FFH(或AX中商大于FFFFH),则CPU产生一个类型0的内部中
断。

(7)符号扩展指令
指令格式1: CBW
指令格式2: CWD
功 能:指令功能是将 AX 中的符号扩展到 DX 中,即若 AX < 8000H ,则扩展后
DX=0 ,若 AX ≥ 8000H 扩展后 DX=FFFFH 。CBW 与 CWD 指令常用于在两数相
除之前,使被除数的长度增为原来的两倍。两指令都不影响位标志。
【例】将字节数据扩展成字数据。
MOV AL,0 B4H ;(AL)=0B4H
CBW ;(AX)=0FFB4H
【例】将字数据扩展成双字数据。
MOV DX, 0 ;(DX)=0
MOV AX, 0FFEDH ;(AX)=0FFEDH
CWD ;(DX)=0FFFFH (AX)=0FFEDH

例 3-11
设两个有符号数,被除数存放在内存( 1000H )单元,除数存放在内存( 1001H )
单元,编程实现有符号除法,将商存在( 1002H )单元,余数放( 1003H )单元。
实现上述要求的程序片段为:
MOV DI , 1000H
MOV AL , [DI]
MOV BL , [DI+1]
CBW
IDIV BL
MOV [DI+2] , AL
MOV [DI+3], AH

3.3.3 位操作类指令
1.逻辑运算指令
(1)逻辑“与”指令AND
指令格式: AND 目的操作数 , 源操作数 ;目的操作数 ←(目的操作数)∩(源操作数)
功能:对两个操作数进行按位的逻辑“与”运算,结果送回目的操作数。其中目的操作
数可以是累加器、任一通用寄存器,或内存操作数(所有寻址方式)。源操作数可以是立
即数、寄存器,也可以是内存操作数(所有寻址方式)。影响条件码:CF=0, OF=0,AF
未定义,SF,ZF,PF按定义影响。“与”指令中操作数不能同时为存储器.
操作类型举例:
AND AL,0FH ;寄存器 ∧ 立即数
AND DX, [BX+SI] ; 寄存器 ∧存储器
例: 若(AL)=0A4H ,AND AL, 0FH; (AL)=04H, (AL)0-3不变;(AL)4-7=00H,屏蔽高
4位。

(2)逻辑“或”指令OR
指令格式: OR 目的操作数 , 源操作数 ;目的操作数 ←(目的操作数)∪(源操作数)
功能:将目标操作数和源操作数按位进行逻辑“或”运算,并将运算结果送回目标操作
数。
执行操作: 进行按位“或”运算 两位操作数中任一位为1(或都为1),则该位(结果)
=1,否则为0。影响条件码:CF=0 , OF=0,AF未定义,SF,ZF,PF按定义影响。“或”
指令中操作数不能同时为存储器。
操作类型举例:
OR AX,0F0H ; 寄存器 立即数
OR AL,AH ; 寄存器 寄存器
OR CL ,BETA[BX][DI] ; 寄存器 存储器
例:将两个操作数信息组合。 若(AL)=06H , OR AL,60H;(AL)=66H

(3)逻辑“异或”指令XOR
指令格式: XOR 目的操作数 , 源操作数 ;目的操作数 ←(目的操作数) ⊕ (源操作数)
功能:将目标操作数和源操作数按位进行逻辑“异或”运算,并将运算结果送回
目标操作数。“或”指令中操作数不能同时为存储器; 影响条件码:CF=0F=0,AF未定
义,SF,ZF,PF按定义影响。
操作类型举例:
XOR CX , CX ; 寄存器 ⊕ 寄存器
XOR byte ptr TABLE[BP][SI], 3DH ; 存储器 ⊕ 立即数
例:XOR CL,0FH ;使低4位取反,高4位不变

(4)逻辑“非”指令NOT
指令格式: NOT 目的操作数 ;目的操作数   0FFFFH – (目的操作数) (字取反)
功 能:对操作数求反,然后送回原处,操作数可以是寄存器或存储器内容。影响标志
位:对标志位无影响。
操作类型举例:
NOT BX ;16位寄存器求反
NOT BYTE PTR [1000H] ;8位存储器求反

(5)测试指令TEST
指令格式: TEST 目的操作数 , 源操作数 ;(目的操作数)∩(源操作数)
功能:将目标操作数和源操作数按位进行逻辑“与”运算,但运算结果不送回目
标操作数。
操作类型举例:
TEST BH, 18H ; 寄存器 ∧ 立即数
TEST SI , BP ;寄存器 ∧ 寄存器
TEST word ptr [BX][DI], 6ACEH ;存储器 ∧ 立即数
例:TEST AL , 09H ;若 AL 中 D3 、 D0 位均为 0 ,则 ZF=1 ;否则 ZF=0

2.移位/循环移位类指令
(1)SHL/SAL 逻辑左移/算术左移指令
格式:SHL 目的操作数 ,cnt;逻辑左移指令, B/W
SAL 目的操作数 ,cnt ;算术左移指令, B/W
目的操作数 :寄存器、存储器寻址方式。
cnt :表示移位次数;
cnt=1,1可写在指令中。
cnt>1,用CL存放移位次数 。
执行操作:相当于无符号数的×2功能。

指令格式举例: SAL DX, 1


SAL AL,CL
SAL WORD PTR [BX+5] ,1 图 3-1 移位指令示意图
SHL AH,1
(2)SHR (Shift logical right ) 逻辑右移指令
格式:SHR 目的操作数 ,cnt ;逻辑右移指令, B/W
执行操作:相当于无符号数的÷2功能。
目的操作数 : 寄存器、存储器寻址方式。
cnt :表示移位次数
cnt=1,1可写在指令中。
cnt>1,用CL存放移位次数 。
指令格式举例:
SHR BL , 1
SHR AX , CL
SHR BYTE PTR [DI+BP],1

(3)SAR (Shift arithmetic right)算术右移指令


格式:SAR 目的操作数 ,cnt ;算术右移指令, B/W
操作: 相当于带符号数的÷2功能,
指令格式举例:
SAR AL , 1
SHR DL , CL
SHR BYTE PTR STATUS ,CL

例 3-12 在数的输入输出过程中乘 10 的操作是经常要进行的。而 X*10=X*2+X*8,也


可以采用移位和相加的办法来实现*10。为保证结果完整,先将 AL 中的字节扩展为字。
MOV AH,0
SAL AX,1 ;X*2
MOV BX,AX ;移至 BX 中暂存
SAL AX,1 ;X*4
SAL AX,1 ;X*8
ADD AX,BX ;X*10

(4)循环移位指令
指令格式:ROL/ROR/RCL/RCR reg 或mem, 1或CL
循环移位分大循环(带进位标志CF循环移位)和小循环(不带进位标志CF循环移位)
两种。循环移位指令只影响CF 和OF 两个标志。其中,CF 总是等于目标操作数最后一
次影响后的结果。
图 3-2 循环移位指令示意图
指令格式举例:
ROR CX , 1 ;右循环移位
ROL BH , CL ;左循环移位
RCL OPRD,1 ;带进位左循环移位
RCR OPRD,CL ;带进位右循环移位

3.3.4 程序控制指令
1.条件转移指令

条件转移指令是根据执行该指令时 CPU 标志的状态而决定是否发生控制转移的指


令。如果满足条件则程序转移到指定的目标地址;如不满足转移条件,则继续执行该条
件转移指令的下一条指令。

表 3-1 条件转移指令表
汇编格式 操 作
标志位转移指令
JZ/JE/JNZ/JNE OPRD 结果为零/结果不为零转移
JS/JNS OPRD 结果为负数/结果为正数转移
JP/JPE/JNP/JPO OPRD 结果奇偶校验为偶/结果奇偶校验为奇转移
JO/JNO OPRD 结果溢出/结果不溢出转移
JC/JNC OPRD 结果有进位(借位)/结果无进位(借位)转移
不带符号数比较转移指令
JA/JNBE OPRD 高于或不低于等于转移
JAE/JNA OPRD 高于等于或不低于转移
JB/JNAE OPRD 小于或不大于等于转移
JBE/JNA OPRD 小于等于或不大于转移
带符号数比较转移指令
JG/JNLE OPRD 高于或不低于等于转移
JGE/JNL OPRD 高于等于或不低于转移
JL/JNGE OPRD 小于或不大于等于转移
JLE/JNG OPRD 小于等于或不大于转移
测试转移指令
JCXZ OPRD CX=0 时转移

2.循环控制指令
循环控制指令是段内短距离相对转移指令,可用来控制程序段的循环执行,循环指
令用 CX 寄存器作为计数器(循环次数都由 CX 的值指定),执行时它首先使 CX 减 1 ,
若减 1 后不为 0 ,则转移到目标地址;否则就执行 LOOP 指令之后的指令。

表 3-2 循环指令表
指令格式 执行操作
LOOP OPRD CX=CX-1;若 CX<>0,则循环
LOOPNZ/LOOPNE OPRD CX=CX-1,若 CX<>0 且 ZF=0,则循环
LOOPZ/LOOPE OPRD CX=CX-1,若 CX<>0 且 ZF=1,则循环
习 题 3
3-1 试分别说明下列各指令中源操作数和目的操作数使用的寻址方式。
1) MOV DS,2010H
2) MOV BX,[SI+DI]
3) MOV DI,[AX]
4) MOV AX,[BX+BP]
5) MOV DX, [SP]
6) MOV AX,ES:[BX]
7) MOV [BX+SI+8], BX
8) MOV BX,WORD PTR[2200H]

3-2、设 DS=2500H,SS=3000H, BX=1800H, BP=3010H,SI=0002H,指出下列各条


指令源操作数的寻址方式?,若为存储器寻址,其物理地址的值是多少?
(1) MOV BX,1000H
(2) MOV BX,[1000H]
(3) MOV AX,[BP]
(4) MOV AL,[BX+SI+1]

3-3 试分别指出下列各指令语句的语法是否有错,如有错,指明是什么错误。
1) MOV DS,2010H
2) MOV BX,[SI+DI]
3) MOV DI,[AX]
4) MOV AX,[BX+BP]
5) MOV DX, [SP]
6) MOV AX,ES:[BX]
7) PUSH AL
8) XCHG CL,CH
9) LDS CH,[DI]
10) LEA BX,1000H
11) LEA DX,DI
12) AAA CX
13) ADD [BP+DI],[1000H]
14) CBW BH
15) ADD 03ECH,AX
16) MUL AX,200H
17) SBB AX,[DX]
18) CMP [BX],[SI]
19) DIV 0010H
20) MUL 24H

3-4、源程序如下:
MOV CL,4
MOV AX,[2000H]
SHL AL,CL
SHR AX,CL
MOV [2000H],AX
试问:若程序执行前,数据段内(2000H)=09H,(2001H)=03H, 则执行后有
(2000H)=_____,(2001H)=______。

3-5、源程序如下:
MOV CX,9
MOV AL,01H
MOV SI,1000H
NEXT: MOV [SI],AL
INC SI
SHL AL,1
LOOP NEXT
试问:执行本程序后有:AL=_____;SI=______;CX=______;

3-6、源程序如下:
若 SS=1600H, SP=2000H, AX=1030H, BX=5544H,标志寄存器 FR=2115H,试说明执行
指令
PUSH AX
PUSH BX
PUSHF
POP CX
POP DX
之后,SP=__ SS=__ CX=__ DX=__.
3-7. 阅读以下程序段,回答问题:
MOV AL,0FH
XOR AL,0FFH
MOV CL,7
SHR AL,CL
上述程序段执行后,AL=___,CL=___。
3-8.设有关寄存器及存储单元的内容如下:
(DS)=2000H,(BX)=0100H,(SI)=0002H,(20100)=12H,(20101)=34H,(20102)=56H,(20103
)=78H,(21200)=2AH,(21201)=4CH,(21202)=0B7H,(21203)=65H,试说明下列各条指令执
行完后 AX 寄存器的内容.
1)MOV AX,1200H
2)MOV AX,[1200H]
3)MOV AX,1100[BX]
4)MOV AX,1100[BX][SI]

3-9.设:(DS)=2000H,(BX)=0100H,(SS)=1000H,
(BP)=0010H,TABLE 的物理地址
为 2000AH,(SI)=0002H。
求下列每条指令源操作数的存储单元地址:
MOV AX,[1234H]
MOV AX,[BX]
MOV AX,TABLE[BX]
MOV AX,[BP]
MOV AX,[BP][SI]
3-10.已知 SS=0FFA0H,SP=00B0H,先执行两条把 8057H 和 0F79H 分别进栈的 PUSH 指令,
再执行一条 POP 指令,试画出堆栈区和 SP 内容变化的过程示意图。(标出存储单元的地
址)
第 4 章 汇编语言程序设计
计算机必须在程序控制下才能有效的工作。为使用户与计算机之间能进行信息交
换,产生了多种程序设计语言。每种语言都有自己的特点、优势及运行环境,有自己的
应用领域和针对性。从用户角度看,计算机程序设计语言一般可分为机器语言、汇编语
言和高级语言三种不同层次的语言。
汇编语言是一种符号语言,但是,汇编语言有很多优点,比如用汇编语言编写程序
能够直接利用硬件系统的特性(如寄存器、标志、中断系统等)直接对位、字节、字寄
存器、存储单元、I/O 端口进行处理;也能直接使用 CPU 指令系统和指令系统提供的
各种寻址方式,编制出高质量的程序,而且程序占用内存空间少、执行速度快。汇编程
序是最早也是最成熟的一种系统软件。而汇编语言的应用是最早也是效率最高的一种语
言,应用汇编语言开发较早的系统软件和应用软件,比如 UNIX 操作系统,刚开始就完
全采用汇编语言开发的。
汇编语言也在不断向前发展,除基本汇编语言之外,还有宏汇编。因此,本章主要
讲解汇编语言伪指令与宏指令、汇编程序设计方法与技巧和汇编调用 BIOS/DOS 等方
面的内容。
4.1 汇编语言语句
4.1.1 汇编语言语句的种类
汇编语言源程序中语句的三种类型包括:指令语句、伪指令语句和宏指令语句。
(1) 指令语句是 CPU 可以执行的能完成特定功能的语句,它主要由 CPU 指令组
成并能产生目标代码。
(2) 伪指令语句只是告诉汇编程序在汇编过程中应如何汇编指令序列。例如,告
诉汇编程序已写出的汇编语言源程序有几个段、段的名字是什么、定义变量、定义过程、
给变量分配存储单元和给数字或表达式命名等。所以伪指令语句是为汇编程序在汇编时
用的,它不产生目标代码。
(3) 宏指令语句是一个指令序列,汇编时,都将用相应的指令序列的目标代码插
入凡有宏指令语句的地方。
4.1.2 汇编语言的语句格式
指令语句类似于伪指令语句的格式,接下来主要介绍这两种语句的格式,宏指令语
句的格式后面再作介绍。一般情况下,汇编语言的语句可以由 1~4 部分构成:[名字:]
助记符 [操作数] [;注释]
带方括号的部分表示任选项,可有可无。如:
LOOPER:MOV AL,DATA[SI] ;取一个字节数
DATAl DB 0F3H,68H,0A4H,7DH,3CH ;定义数组
第一条语句是指令语句,其中的“MOV”是 CPU 指令的助记符;第二条语句是伪指
令语句,其中的“DB”是伪指令定义符。下面对汇编语言中的各个组成部分进行讨论。
1. 名字
在汇编语言语句中名字是第一个组成部分。在指令语句中,名字可以是一个标号,
它实质上是指令的符号地址。但并不是每条指令都一定要有标号。如果指令前有标号,
程序的其他地方就可以引用它,但注意后面须有冒号。
标号有三种属性:段、类型、偏移量。
(1) 标号的段属性定义标号的程序段的段基值,该标号的段基值当程序中引用时
应在 CS 寄存器中。
(2) 标号的偏移量属性是一个 16 位无符号数,表示标号所在段的起始地址到定
义该标号的地址之间的字节数。
(3) 标号的类型属性有两种:NEAR 和 FAR。NEAR 可以在段内被引用,地址
指针为 2 个字节, 如果定义一个标号时后跟冒号,则汇编程序确认其类型为 NEAR;
FAR 可以在其他段被引用,地址指针为 4 个字节。
在伪指令语句中,名字可以是变量名、段名、过程名。伪指令语句中的名字并不总
是任选的,即不同的伪指令对于是否有名字有不同的规定。例如,有些伪指令规定前面
必须有名字,有些则不允许有名字,也有一些伪指令的名字是可选的。
伪指令语句中的名字大多数是变量名,变量名代表存储器中一个数据区的名字。
变量也有三种属性:段、偏移量和类型。
(1) 变量的段属性是变量所代表的数据区域所在段的段基值,由于数据区一般在
存储器的数据段,因此,变量的段基值通常在 DS 和 ES 中。
(2) 变量的偏移量属性是该变量所在段的起始地址与变量的地址之间的字节数。
(3) 变量的类型属性有 BYTE(字节)
、WORD( 字)、DWORD( 双字)、QWORD
(4 个字)、TBYTE(10 个字节)等,表示数据区中存取操作对象的大小。
伪指令语句与标号的明显区别在于名字后面不加冒号。
2. 助记符
伪指令语句中的第二部分是伪指令的定义符。将在 4.3 节详细讲解。
3. 操作数
汇编语言语句中的第三部分是操作数。指令语句中指令的操作数,有单操作数、双
操作数、多操作数,也可以没有操作数。当指令的操作数不止一个时,相互之间应用逗
号隔开。
4. 注释
汇编语言语句中的最后一部分是注释。它对汇编后生成的目标程序没有任何影响,
加上注释使程序的可读性增强。在对汇编语言进行注释时,前面必须加上分号,如果注
释的内容超过一行,则换行以后前面还要加上分号。
4.1.3 指令语句的操作数组成
操作数的类型:常量、寄存器、存储器、标号、变量和表达式。
1. 常量
常量是指令中的固定值,有数值常量和字符串常量两类,汇编语言用不同的后缀加
以区别。例如,立即数寻址时所用的立即数,直接寻址时所用的地址,ASCII 字符串
都是常量,常量除了自身的值以外,没有其他的属性。在源程序中,数值常量可用二进
制数、八进制数、十进制数、十六进制数等几种形式表示。
汇编语言中的数值常量第一位必须是 0~9 的数字,否则汇编时将被看作标识符。
例如常数 B7H,应写成 0B7H,FFH 应写成 0FFH。
字符串常量是由单引号‘’括起来的一串字符。例如‘ABCDEF’,‘123’。汇编时,单
引号内的字符均以 ASCII 码的形式存在。上述两个字符串的 ASCII 码分别是 41H,
42H,43H,44H,…,46H,31H,32H,33H。字符串最长可以有 255 个字符。汇编
语言规定:除用 DB 定义的字符串常量以外,单引号中 ASCII 字符的个数不得超过两
个。若只有一个,例如,DW‘C’就相当于 DW 0043H。
2. 寄存器
8086/8088 CPU 的寄存器可以作为指令的操作数,8 位寄存器:AH,AL,BH,
BL,CH,CL,DH,DL;16 位寄存器:AX,BX,CX,DX,SI,DI,BP,SP,DS,
ES,SS,CS。
3. 标号
标号代表一条指令的符号地址,可作为转移(无条件转移或条件转移)、过程访问
以及循环控制指令的操作数。
4. 变量
变量在存储器中是某个数据区的名字,在指令中可作为存储器操作数。
5. 表达式
汇编语言语句中的表达式,按其性质可分为数值表达式和地址表达式两种。
6. 存储器
计算机内存中存放的数据。
4.1.4 指令语句中的运算符和操作符
数值表达式只有大小,没有属性,只是一个数值结果。地址表达式不仅仅是一个单
纯的数值结果,而是一个表示存储器地址的变量或标号,它有三种属性:段、偏移量和
类型。表达式中常用的运算符有以下几种:
1.常用的算术运算符有:+、-、×、/和 MOD(即两个整数相除后取余数)等。
算术运算的结果是一个数值,可用于数值表达式。在地址表达式中通常只使用+和
-两种运算符。
2.逻辑运算符有:AND 逻辑与、OR 逻辑或、XOR 逻辑异或、NOT 逻辑非。逻辑运
算符只用于数值表达式中对数值进行按位逻辑运算,并得到一个数值结果。
3.关系运算符有:EQ 等于、NE 不等、LT 小于、GT 大于、LE 小于或等于、GE 大
于或等于。
参与关系运算的必须是两个数值或同一段中的两个存储单元地址,但运算结果只能
是两个特定的数值之一。当关系不成立(假)时:结果为 0(全 0);当关系成立(真)
时,结果为 0FFFFH(全 1)。例如:MOV AX, 4 EQ 3;关系不成立,故(AX)←0;
MOV AX, 4 NE 3;关系成立,故(AX)←00FFFFH。
4.分析运算符有:SEG、OFFSET 、TYPE、SIZE 和 LENGTH 等。它可以分解存储器
操作数为其组成部分,如它的段值、段内偏移量和类型,或取得它所定义的存储空间的
大小。
1) SEG 运算符:利用 SEG 运算符可以得到标号或变量的段基值。例如将 ARRAY
变量的段基值送 DS 寄存器。MOV AX,SEG ARRAY MOV DS,AX
2) OFFSET 运算符:利用 OFFSET 运算符可以得到标号或变量的偏移量。例:
MOV DI,OFFSET DATAl
3) TYPE 运算符:运算符 TYPE 的运算结果是个数值,这个数值与存储器操作
数类型属性的对应关系如表 4-1 所示。
表 4-1 TYPE 返回值与类型的关系
TYPE 返回值 存储器操作数的类型
1 BYTE
2 WORD
4 DWORD
-1 NEAR
-2 FAR
下面是使用 TYPE 运算符的语句例子:
VAR DW ? ;变量 VAR 的类型为字;
ARRAY DD 10DUP(?) ;变量 ARRAY 的类型为双字;
STR DB ‘THIS IS TEST’; 变量 STR 的类型为字节;
MOV AX,TYPE VAR ; (AX)←2 MOV BX,TYPE ARRAY ;
(BX)←4 MOV CX,
TYPE STR ;(CX)←1 程序中的 DW、DD、DB 等为伪指令定义符。
4)LENGTH 运算符:在一个变量已用重复操作符 DUP 说明变量的个数的情况下,
用它得到变量的个数。如果一个变量未用重复操作符 DUP 说明,则得到的结果总是 1。
如上面的例子中 ARRAY DD 10DUP(?) ,则 LENGTH ARRAY 的结果为 10。
5) SIZE 运算符:在一个变量已用重复操作符 DUP 说明的情况下,用它可得到
分配给该变量的字节总数。如果一个变量未用重复操作符 DUP 说明,则得到 TYPE 运
算的结果。ARRAY DD 10DUP(?),SIZE ARRAY=10×4=40。由此可知,SIZE 的运
算结果等于 LENGTH 的运算结果乘以 TYPE 的运算结果:SIZE ARRAY=(LENGTH
ARRAY)×(TYPE ARRAY)。
5. 合成运算符:有 PTR、THIS、SHORT 等。它可以用来建立或临时改变变量或标号的
类型或存储器操作数的存储单元类型。
1) PTR 运算符
运算符 PTR 可以指定或修改存储器操作数的类型,例如:
INC BYTE PTR [BX] [DI]
指令中利用 PTR 运算符明确规定了存储器操作数的类型是 BYTE(字节),因此,
本指令将一个 8 位存储器的内容加 l。利用 PTR 运算符可以建立一个新的存储器操作
数,这个操作数与原来的同名操作数具有相同的段和偏移量,但可以有不同的类型。不
过这个新类型只在当前语句中有效。例如:STUFF DD ?;定义 STUFF 为双字类型变量
MOV BX,WORD PTR STUFF;从 STUFF 中取一个字到 BX。
2) THIS 运算符
运算符 THIS 指定存储器操作数的类型。使用 THIS 运算符可以使标号或变量变得
灵活。例如要求对同一个数据区,既可以字节为单位,又可以字为单位进行存取,则可
用以下语句:
AREAW EQU THIS WORD AREAB DB 100 DUP(?)
上面 AREAW 和 AREAB 实际代表同一个数据区, 共有 100 个字节,但 AREAW 的
类型为字,AREAB 的类型为字节。
3) SHORT 运算符
运算符 SHORT 指定一个标号的类型为 SHORT(短标号),即标号到引用该标号的
字节距离在-128~+127 范围内。短标号可以用于转移指令中。使用短标号的指令比
使用默认的近程标号的指令少一个字节。
6. 其他运算符
1) 段超越运算符“:”紧跟在段寄存器名(DS、CS、SS、ES) 之后,表示段超
越,它不管原来隐含在什么段,都可以给存储器操作数指定一个段的属性。MOV AX,
ES:[SI]
2) 字节分离运算符
运算符 LOW 和 HIGH 分别得到一个数值或地址表达式的低位和高位字节。
STUFF EQU 0ABCDH
MOV AH,HIGH STUFF ;(AH)←0ABH
MOV AL,LOW STUFF ;(AL)←0CDH
以上介绍了表达式中使用的各种运算符,如果一个表达式同时具有多个运算符,则
按以下规则运算:
(1) 优先级按照从高到低的顺序运算。
(2) 优先级相同时,按表达式从左到右的顺序运算。
(3) 括号可以提高运算的优先级,括号内的运算总是在相邻的运算之前进行。各
种运算符的优先级顺序见表 4-2。表中同一行的运算符具有相等的优先级。
表 4-2 各种运算符的优先级顺序
优先级(从高到低) 运算符
1 LENGTH,SIZE,WIDTH,MASK,(),[],〈〉,. (结构变量名后面的运算
符)
2 :(段超越运算符)
3 PTR,OFFSET,SEG,TYPE,THIS
4 HIGH,LOW
5 +,-(一元运算符)
6 *,/,MOD,SHL,SHR
7 +,-(二元运算符)
8 EQ,NE,LT,LE,GT,GE
9 NOT
10 AND
11 OR,XOR
12 SHORT

4.2 伪指令
伪指令在表现形式和其在语句中所处的位置这两方面相似于 CPU 指令,但也有重
要区别。首先,CPU 指令是给 CPU 的命令,在运行时由 CPU 执行,每条指令对应
CPU 的一种特定操作;而伪指令是给汇编程序的命令,在汇编过程中由汇编程序进行
处理。其次,汇编以后,每条 CPU 指令产生一一对应的目标代码;而伪指令则不会产
生。
根据伪指令的功能,大致分成以下几类:
(1) 数据定义伪指令。
(2) 符号定义伪指令。
(3) 段定义伪指令。
(4) 过程定义伪指令。
(5) 宏处理伪指令。
(6) 模块定义与连接伪指令。
(7) 处理器方式伪指令。
(8) 条件伪指令。
(9) 列表伪指令。
(10) 其他伪指令。
4.2.1 数据定义伪指令
数据定义伪指令的用途是定义一个变量的类型,给存储器赋初值,或给变量分配存
储单元。常用的数据定义伪指令有 DB、DD、DW 等。数据定义伪指令的一般格式为:
[变量名] 伪指令操作数[,操作数…] ,方括号中的变量名为任选项。变量名后面不跟
冒号。伪操作后面的操作数可以不止一个,如有多个操作数,互相之间应该用逗号分开。
1. DB(Define byte)
定义变量的类型为 BYTE,给变量分配字节或字节串。DB 伪操作后面的每一个操
作数占有 1 个字节。
2. DW(Define word)
定义变量的类型为 WORD。DW 伪操作后面的操作数每个占有 1 个字,即 2 个字
节。在内存中存放时,低位字节在前,高位字节在后。
3. DD(Define double word)
定义变量的类型为 DWORD 。DD 后面的操作数每个占有 2 个字,即 4 个字节。
在内存中存放时,低位字在前,高位字在后。
数据定义伪操作后面的操作数可以是常数、表达式或字符串,但每项操作数的值不
能超过由伪操作所定义的数据类型限定的范围。例如,DB 伪指令定义数据的类型为字
节,则其范围为无符号数 0~255 ;带符号数−128~+127 等。字符串必须放在单引号
中。另外,超过两个字符的字符串只能用 DB 伪指令定义。例如:
DATA DB 100,0FFH ;存入 64H,FFH
EX DB 2*3+7 ;存入 0DH
STR DB ‘WELCOME!’ ;存入 8 个字符
AB DB ‘AB’ ;存入 41H,42H
BA DW ‘AB’ ;存入 4142H
AD DD ‘AB’ ;存入 00004142H
AQ DD ‘AB’ ;存入 AB 的偏移地址
AF DW TABLE,TABLE-5,TABLE+10 ;存入 3 个偏移地址
TOTAL DW TABLE,TABLE-5 ;存入 TABLE 偏移地址
TOTAL DD TABLE ;再存入 TABLE 的段基址
以上第一和第二语句中,分别将常数和表达式的值赋给一个变量。第三句的操作数
是包含 8 个字符的字符串(只能用 DB)。在第四、五、六句,注意伪指令 DB、DW 和
DD 的区别,虽然操作数均为“AB”两个字符,但存入变量的内容各不相同。第七句的
操作数是变量 AB,而不是字符串,此句将 AB 的 16 位偏移地址存入变量 AQ。第八
句存入三个等距的偏移地址,共占 6 个字节。第九句中的 DD 伪操作将 TABLE 的偏
移地址和段地址顺序存入变量 TOTAL,共占 2 个字。
数据定义伪指令的操作数除了常数、表达式和字符串外,问号“?”也可以作为,此
时仅给变量保留相应的存储单元,而不赋给变量某个确定的初值。当同样的操作数重复
多次时,可用重复操作符“DUP”表示,其形式为:n DUP (初值[初值…])
圆括号中为重复的内容,n 为重复次数。如果用“n DUP(?)”作为数据定义伪指
令的唯一操作数,则汇编程序产生一个相应的数据区,但不赋任何初值。重复操作符
“DUP” 可以嵌套。
FILLER DB ? SUM DW ?
DB ?,?,? BUFFER DB 10 DUP(?) ZERO DW 30 DUP(0) MASK DB 5 DUP
(‘OK!’) ARRAY DB 100 DUP (3 DUP(8),6)
其中第一、第二句分别给字节变量 FILLER 和字变量 SUM 分配存储单元,但不
赋给特定的值。第三句给一个没有名称的字节变量分配 3 个单元。第四句给变量
BUFFER 分配 10 个字节的存储空间。第五句给变量 ZERO 分配一个数据区,共 30 个
字(即 60 个字节),每个字的内容均为零。第六句定义一个数据区,其中有 5 个重复
的字符串“OK!”,共占 15 个字节。最后一句将变量 ARRAY 定义一个数据区,其中
包含重复 100 次的内容:8,8, 8,6,共占 400 个字节。
下面列出几个错误的数据定义伪指令语句。
ERRl: DW 99 ;变量名后有冒号
ERR2 DB 25*60 ;DB 的操作数超过 255
FRR3 DD 'ABCD' ;DD 的操作数是超过 2 个字符的字符串
4.2.2 符号定义伪指令
符号定义伪指令的作用是重新命名一个符号,或定义新的类型属性等。上述符号包
括汇编语言的变量名、标号名、过程名,寄存器名以及指令助记符等。
常用的符号定义伪指令有:EQU、=(等号)和 LABLE。
1. EQU
格式:名字 EQU 表达式
EQU 伪指令是将表达式的值赋给名字,以后可用它来代替表达式。格式中的表达
式可以是一个常数、符号、数值表达式或地址表达式。
CR EQU ODH ;常数
LF EQU 0AH
A EQU ASCII-TABLE ;变量
STR EQU 64*1024 ;数值表达式
ADR EQU ES:[BP+DI+5] ;地址表达式
CBD EQU AAM ;指令助记符
利用 EQU 伪指令,数值可以用名字代替,较长的名字可以用简短的名字代替。
如果源程序需多次引用某一表达式,则可以利用 EQU 伪操作给其赋一个名字,从
而使程序更加简洁,便于阅读。如果改变表达式的值,也只需修改一处,操作简单,程
序容易维护。注意:EQU 伪指令不能对同一符号重复定义。
2. =(等号)
格式:
名字= 表达式
=(等号)伪指令功能与 EQU 相似,主要区别在于=(等号)可以对同一符号重复
定义。例:COUNT=10 MOV CX ,COUNT ; (CX)←10 COUNT= COUNT-1 MOV
BX ,COUNT ;(BX)←9
3. LABLE
LABLE 伪指令是定义标号或变量的类型,它和下一条指令共享存储器单元。格式
为:名字 LABLE 类型
标号的类型可以是 NEAR 和 FAR,变量的类型可以是 BYTE( 字节)、WORD
( 字) 、DWORD(双字)。 利用 LABLE 伪指令可以使同一个数据区兼有两种属性 BYTE
(字节)和 WORD(字),可以在以后的程序中根据不同的需要以字节或字为单位存取
其中的数据。
ARW LABLE WORD ;变量 ARW 类型为 WORD ARB DB 100 DUP (?) ;变量
ARB 类型为 BYTE …MOV ARW , AX ;AX 送第 1,2 字节中…MOV ARB[49],AL ;
AL 送第 50 个字节中
LABLE 伪指令也可以将一个属性已经定义为 NEAR 或者后面跟有冒号(隐含属
性为 NEAR)的标号再定义为 FAR。AGF LABLE FAR ;定义标号的属性为 FAR AG:
PUSH AX ;标号 AG 的属性为 NEAR
4.2.3 段定义伪指令
段定义伪指令的用途是在汇编语言源程序中定义逻辑段,常用段定义伪指令有
SEGMENT、ENDS、ASSUME 等。
1. SEGMENT/ENDS
格式:段名 SEGMENT [ 定位类型][组合类型][‘类别’] …段名 ENDS
一个逻辑段以 SEGMENT 伪指令开始,以 ENDS 伪指令作为一个逻辑段的结束。
它们总是成对出现,前面的段名必须保持一致。该逻辑段的内容在两者之间。SEGMENT
伪指令用于定义一个逻辑段,给逻辑段赋予一个段名,并以后面的任选项(定位类型、
组合类型、类别)规定该逻辑段的其他特性。例如,对于代码段,其中主要有 CPU 指
令及其他伪指令。对于数据段和附加段,主要有定义数据区的伪指令等。一个源程序中
不同逻辑段的段名可以各不相同,但也允许相同。
在上面的格式中,三个任选项都放在方括号内,可有可无。如果有,三者的顺序必
须按照格式中的规定。这些任选项是给汇编程序和连接程序(LINK)的命令。
SEGMENT 伪指令后面的任选项告诉汇编程序和连接程序,如何确定段的边界,
以及如何组合几个不同的段等。下面分别进行讨论:
1)定位类型共有以下四种:
(1) BYTE。表示逻辑段从字节的边界开始,即可以从任何地址开始。此时本
段的起始地址紧接在前一段后边。
(2) WORD。表示逻辑段从字的边界开始。2 个字节为 1 个字,此时本段的的
起始地址必须是偶数。
(3) PARA 。表示逻辑段从节(PARAGRAPH) 的边界开始,通常 16 个字节
称为一个节,故本段的开始地址(十六进制)应为××××0H。如果省略定位类型选项,
则默认值为 PARA。
(4) PAGE。表示逻辑段从页的边界开始,通常 256 个字节称为一个页,故本段
的开始地址(十六进制)应为×××00H。
STACK SEGMENT STACK ;STACK 段,定位类型无
DB 100 DUP(?) ;长度为 100 字节 STACK ENDS ;STACK 段结束 DATAl
SEGMENT BYTE ;DATAl 段,定位类型 BYTE STRING DB ‘This is an example’ ;长
度为 18 字节 DATAl ENDS ;DTATl 段结束 DATA2 SEGMENT WORD ;DATA2 段,
定位类型 WORD BUFFER DW 40 DUP(0);长度为 40 个字, 即 80 字节 DATA2 ENDS ;
DATA2 段结束 CODEl SEGMENT PAGE ;CODEl 段,定位类型 PAGE
… CODEl ENDS ;CODEl 段结束 CODE2 SEGMENT ;CODE2 段,定位类型无
… START: MOV AX ,STACK MOV SS,AX … CODEl ENDS ;CODE2 段结
束 END START ;源程序结束
本例的源程序中共有 5 个逻辑段,它们的段名和定位类型分别为:
STACK 段 PARA DATAl 段 BYTE DATA2 段 WORD CODEl 段 PAGE CODE2 段
PARA
已经知道其中 STACK 段的长度为 100 字节(64H),DATAl 段的长度为 19 字节
(12H), DATA2 段的长度为 40 个字,即 80 字节(50H) 。假设 CODEl 段占用
13 字节(0DH),CODE2 段占用 52 字节(34H) 。
如果将以上进行汇编和连接,然后再来观察各逻辑段的目标代码或数据装入存储器
的情况。由表 4-3 可清楚地看出,当 SEGMENT 伪指令的定位类型不同时,对段起始
边界规定也不相同。
2) 组合类型(Combine) :SEGMENT 伪指令的第二个任选项是组合类型,它
告诉汇编程序装入存储器后,各个逻辑段如何进行组合。组合类型共有 6 种:
(1) NONE。
如果 SEGMENT 伪指令的组合类型任选项默认,则汇编程序认为这个逻辑段是不
组合的。也就是说,不同程序中的逻辑段,即使具有相同的类别名,也分别作为不同的
逻辑段装入内存,不进行组合。
表 4-3 各逻辑段的起始地址和结束地址
段名 定位类型 字节数 起始地址 结束地址
STACK PARA 100 00000H 00063H
DATAl BYTE 18 00064H 00075H
DATA2 WORD 80 00078H 000C7H
CODEl PAGE 13 00100H 0010CH
CODE2 PARA 52 00110H 00143H
但是,对于组合类型任选项缺省的同名逻辑段,如果属于同一个程序模块,则被顺
序连接成为一个逻辑段。
(2) PUBLIC。
连接时对于不同程序模块的逻辑段,只要具有相同的类别名,就把这些段顺序连接
成为一个逻辑段装入内存。
(3) STACK。
组合类型为 STACK 时,其含意与 PUBLIC 基本一样,即不同程序中的逻辑段,
如果类别名相同,则顺序连接成为一个逻辑段。不过组合类型 STACK 仅限于堆栈区域
的逻辑段使用(顺便提一下,在执行程序(. EXE)中,堆栈指针 SP 设置在这个连接
以后的堆栈段(最终地址+1)处。
(4) COMMON。
连接时,对于不同程序中的逻辑段,如果具有相同的类别名,则都从同一个地址开
始装入,因而各个逻辑段将发生重叠。最后,连接以后的段的长度等于原来最长的逻辑
段的长度,重叠部分的内容是最后一个逻辑段的内容。
(5) MEMORY。
表示当几个逻辑段连接时,本逻辑段定位在地址最高的地方。如果被连接的逻辑段
中有多个段的组合类型都是 MEMORY ,则汇编程序只将首先遇到的段为 MEMORY
段,而其余的段均当作 COMMON 段处理。
(6) AT 表达式。这种组合类型表示本逻辑段根据表达式求值的结果定位段基址。
例:AT 8A00H ,表示本段的段基址为 8A00H ,则本段从存储器的物理地址 8A000H 开
始装入。
3) ‘类别’(‘CLASS’)
SEGMENT 伪指令的第三个任选项是类别,类别必须放在单引号之内。典型类别
如‘STACK’,‘CODE’。类别的主要作用是在连接时决定每个逻辑段的装入顺序。当几
个程序模块进行连接时,其中具有相同类别名的逻辑段被装入连续的内存区,类别名相
同的逻辑段,按出现的先后顺序排列。没有类别名的逻辑段,与其他没有类别名的逻辑
段一起,连续装入内存区。
2. ASSUME
格式: ASSUME 段寄存器名:段名[,段寄存器名:段名[,…]]
对于 8086/8088 CPU 而言,以上格式中的段寄存器名可以是 ES、CS、DS、SS。
段名是曾用 SEGMENT 伪操作定义过的某一个段名或者组名,以及在一个标号或变量
前面加上分析运算符 SEG 所构成的表达式,还可以是关键字 NOTHING。
ASSUME 伪指令告诉汇编程序,将某一个段寄存器设置为某一个逻辑段的段址,
即明确指出源程序中的逻辑段与物理段之间的关系。当汇编程序汇编一个逻辑段时,即
可利用相应的段寄存器寻址该逻辑段中的指令或数据。关键字 NOTHING 表示将前面
用 ASSUME 伪指令对这个段寄存器的设置取消。在一个源程序中,ASSUME 伪操作
应该放在可执行程序开始位置的前面。还需指出一点,ASSUME 伪指令并没有给段寄
存器赋予实际的初值,它只是通知汇编程序有关段寄存器与逻辑段的关系。例如:
CODE SEGMENT
ASSUME CS:CODE,DS:DATAl,SS:STACK
MOV AX,DATAl
MOV DS,AX
MOV AX,STACK
MOV SS,AX
CODE ENDS
4.2.4 模块定义与连接伪指令
如遇到规模较大的汇编语言程序时,可将整个程序划分成几个独立的源程序(或称
模块),然后分别汇编将各个模块生成各自的目标程序,然后将目标程序连接成为一个
完整的可执行程序。可以利用符号在各个模块间访问。也就是说,一个模块可以引用另
一个模块定义的符号。通常称这类符号为外部符号,而将那些在一个模块中定义的,只
在同一个模块中引用的符号称为局部符号。
为了进行连接和在这些将要连接在一起的模块之间实现互相的符号访问,以便进行
变量传送,常常使用以下伪指令:NAME、END、PUBLIC、EXTRN。
1. NAME
NAME 伪指令用于给源程序汇编以后得到的目标程序指定一个模块名,连接时需
要使用这个目标程序的模块名。格式为:NAME 模块名
NAME 的前面不允许再加上标号,例如,下面的表示方式是非法的:
BEGIN:NAME MODNAME
如果程序中没有 NAME 伪指令,则汇编程序将 TITLE 伪指令(TITLE 属于列表
伪指令) 后面“标题名”中的前六个字符作为模块名。如果源程序中既没有使用 NAME,
也没有使用 TITLE 伪指令,则汇编程序将源程序的文件名作为目标程序的模块名。
2. END
END 伪指令表示源程序到此结束,指示汇编程序停止汇编,对于 END 后边的指
令可以不予理会。格式为:END [标号]
END 伪指令后面的标号表示程序执行的启动地址。END 伪指令将标号的段基值
和偏移地址分别提供给 CS 和 IP 寄存器。方括号中的标号是任选项。如果有多个模块
连接在一起,则只有主模块的 END 语句使用标号。
3. PUBLIC
PUBLIC 伪指令说明本模块中的某些符号是公共的,即这些符号可以提供给将被
连接在一起的其他模块使用。格式为:PUBLIC 符号[,…]
其中的符号可以是本模块中定义的变量、标号或数值的名字,包括用 PROC 伪指
令定义的过程名等。PUBLIC 伪指令可以安排在源程序的任何地方。
4. EXTRN
EXTRN 伪指令说明本模块中所用的某些符号是外部的,即这些符号将被连接在一
起的其他模块定义(在这些模块中符号必须用 PUBLIC 定义)。格式为:EXTRN 名字:
类型[,…]
其中的名字必须是其他模块中定义的符号;上述格式中的类型必须与定义这些符号
的模块中的类型说明一致。如为变量,类型可以是 BYTE、WORD 或 DWORD 等;如
为标号和过程,类型可以是 NEAR 或 FAR。
4.2.5 过程定义伪指令
过程定义伪指令 PROC/ENDP
格式为:
过程名 PROC [NEAR]/FAR

RET

过程名 ENDP
其中 PROC 伪指令定义一个过程,赋予过程一个名字并指出该过程的属性为
NEAR 或 FAR。在没有特别指明时,默认过程的属性为 NEAR。伪指令 END 标志过
程结束。PROC/ENDP 伪指令前的过程名必须一致。
当一个程序段被定义为过程后,程序中其他地方就可以用 CALL 指令来调用这个
过程。调用的格式为:CALL 过程名
过程名实质上是过程入口的符号地址,它和标号一样,也有三种属性:段、偏移量
和类型。过程的类型属性可以是 NEAR 或 FAR。
一般来说,被定义为过程的程序段中应该有返回指令 RET,但不一定是最后一条
指令,也可以有不止一条 RET 指令。执行 RET 指令后,控制返回到原来调用指令的
下一条指令。过程的定义和调用均可嵌套。例如:
NA1 PROC FAR

CALL NA2 RET NA2 PROC NEAR

RET NA2 ENDP NA1 ENDP
上面过程 NAl 的定义中包含着另一个过程 NA2 的定义。NAl 本身是一个可以被
调用的过程,而它也可以再调用其他的过程。
4.3 汇编语言程序的结构
4.3.1 汇编语言程序的结构
在第 3 章所举出的若干程序段并不是规范的汇编语言源程序,下面举一个比较简
单,而比较规范的汇编语言源程序。
【例 4.1】要求将两个 4 字节十六进制数相加,可以编写出以下汇编语言源程序。
DATA SEGMENT ;定义数据段
DATA1 DB 0E8H,50H,0BCH,74H ;被加数
DATA2 DB 21H,22H,23H,24H ;加数
DATA ENDS ;数据段结束
CODE SEGMENT ;定义代码段
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX ;初始化 DS
MOV CX,4 ;循环次数 CX
MOV SI,0 ;置 SI 初值为 0
CLC ;清 CF 标志
LOOPER: MOV AL,DATA2[SI] ;取一个字节加数
ADC DATA1[SI],AL ;与被加数相加
INC SI ;SI 加 l
DEC CX ;CX 减 1
JNZ LOOPER ;若不等于 0,转
LOOPER
HLT ;停止
CODE ENDS ;代码段结束
END START ;源程序结束
由上面的例子可以看出,汇编语言源程序的结构是分段结构形式。一个汇编语言源
程序由若干逻辑段(SEGMENT)组成,每个逻辑段以 SEGMENT 语句开始,以 ENDS
语句结束,整个程序以 END 语句结束。
每个逻辑段内有若干行语句(STATEMENT) ,一个汇编语言源程序由一行一行
的语句组成。
4.3.2 程序正常返回 DOS 的方法
当我们编写的汇编语言源程序是在 PC-DOS 环境下运行时,必须了解汇编语言是
如何同操作系统接口的。
当用连接程序对其进行连接和定位时,操作系统为每一个用户程序建立了一长度为
256 个字节的程序段前缀区 PSP,主要是将所要执行程序的有关信息存放,同时也提供
了程序和操作系统的接口。操作系统在程序段前缀的开始处(偏移地址 0000H)安排了
一条 INT 20H 软中断指令。INT 20H 中断服务程序由 PC-DOS 提供,执行该服务程序
后,控制就转移到 DOS,即返回到 DOS 管理的状态。因此,用户在组织程序时,必须
使程序执行完后,能去执行存放于 PSP 开始处的 INT 20H 指令,这样便返回到 DOS,
否则就无法继续键入命令和程序。
PC-DOS 在建立了程序段前缀区 PSP 之后,就将要执行的程序从磁盘装入内存。
在定位程序时,DOS 将代码段置于 PSP 下方,代码段之后是数据段,最后放置堆栈段。
内存分配好之后,DOS 就设置段寄存器 DS 和 ES 的值,以使它们指向 PSP 的开始处,
即 INT 20H 的存放地址,同时将 CS 设置为 PSP 后面代码段的段基值,IP 设置为指
向代码段中第一条要执行的指令位置,把 SS 设置为指向堆栈的段基值,让 SP 指向堆
栈段的栈底(取决于堆栈的长度),然后系统开始执行用户程序。
为了保证用户程序执行完后,能回到 DOS,可使用如下两种方法:
1. 标准方法
首先将用户程序的主程序定义成一个 FAR 过程,其最后一条指令为 RET,然后在
代码段的主程序(即 FAR 过程)的开始部分,用如下三条指令将 PSP 中 INT 20H 指
令的段基值及偏移地址压入堆栈:
PUSH DS ;保护 PSP 段地址
MOV AX,0 ;保护偏移地址
PUSH AX
这样,当程序执行到主程序的最后一条指令 RET 时,由于该过程具有 FAR 属性,
故存在堆栈内的两个字就分别弹出到 CS 和 IP,便执行 INT 20H 指令,使控制返回到
DOS 状态。
此外,由于开始执行用户程序时,DS 并不设置在用户的数据段的起始处,ES 也
同样不设置在用户的附加段起始处,因而在主程序开始处,继上述三条指令之后,应该
重新装填 DS 和 ES 的值。
2. 非标准方法
也可在用户的程序中不定义过程段,只在代码段结束之前(即 CODE ENDS 之前) ,
增加两条语句:MOV AH,4CH INT 21H
则程序执行完后,也会自动返回 DOS 状态。
4.4 基本结构程序设计
1. 汇编语言程序设计的基本过程
汇编语言程序设计的基本过程的步骤:1)分析问题,明确要求分析问题就是深入
结合实际,对所要解决的问题进行全面认知和分析。一个实际问题往往比表面看起来复
杂得多,在深入分析的基础上,抓住主要矛盾,去除次要矛盾,看清问题的本质。明确
要求就是明确用户的要求,根据要求的条件和给出的数据,进行可行性分析。2) 建立
数学模型,在分析问题和明确要求的基础上,要建立数学模型,用数学形式表达一个工
作状态和物理过程。3) 确定算法和处理方案,建立数学模型后,必须确定算法。所谓
算法,是指解决问题的计算方法,不同的问题用不同的计算方法。根据问题的特点,优
化计算方法。若没有现成的方法,应实践,找到解决问题的方法后要注意总结规律。4)
画流程图,流程图使解题的思路清晰,有利于理解、阅读和编制程序,还有利于调试、
修改程序和减少错误等。因为程序算法的图形描述把解决问题的先后顺序和程序的逻辑
结构用图形的方式直观、形象地描述出了。5) 编制程序,在编制程序时,应当先分配
好存储空间和工作单元及 CPU 内部的寄存器,然后根据流程图和确定的算法逐条语句
编写程序。6) 上机调试程序编好后,必须上机调试,特别是对于复杂的问题,往往要
分解成若干个子问题,由几个人编写,而形成若干个程序模块,最后把它们组装在一起,
形成总体程序。一般来说,问题和错误在调试程序时通常都可以发现,然后进行修改,
再调试,再修改,直到所有的问题解决为止。7) 试运行和分析结果,试运行和分析结
果是为了检验程序是否满足用户提出的需求,所确定的设计方案是否可行。若不满足用
户的需求,就必须从分析问题开始检查修正原有的设计方案,直到符合设计要求和满足
用户需求为止。8) 整理资料,投入运行,在试运行满足要求之后,应当系统地整理材
料,有关资料要及时提交用户,以便正常投入运行。
2. 程序结构化的概念
在计算机发展的初期,由于硬件贵、内存容量小和运算速度低等问题,要求程序运
行时间尽可能短,占用内存尽可能少。这也成为衡量程序质量好坏的主要标准。为了达
到这一目的,人们挖空心思寻找技巧,由于程序实际没有统一的规范,很难理解和消化
这种程序,造成人力和时间的严重浪费。
随着电子技术的迅速发展,特别是大规模和超大规模集成电路技术的兴起,计算机
硬件价格大幅度下降,内存容量不断扩大,运算速度飞速提高。因此,运行时间短和节
省内存已不是主要矛盾,更重要的是使程序具有良好的结构、清晰的层次、容易阅读和
理解、容易修改和查错,这就对以前的传统设计方法提出了挑战,从而产生了结构化程
序设计方法,又称为系统化程序设计方法。在这个方法中,首先把一个大型程序分解成
几个主要的模块;最高
层次部分对整个程序概述,说明这些模块之间的关系以及它们的功能。而每个主要的模
块再分解成几个较小的模块,然后继续分解成更小的模块,直到每个模块内的操作步骤
都很清楚、很容易理解为止,最后把一个模块或几个模块分配给每个程序设计师编写。
这种称为“自上而下”的程序设计方法。
与上述方法相对应的还有“自下而上”的程序设计方法,在这个方法中,每个程序
设计师从低层次的模块开始编写并且期望这些模块最后能组合在一起。如果组合完成,
和“自上而下”的设计方法产生相同结果。现在许多程序设计都是混合使用这两种方法,
由上而下开始设计,然后由最小的模块开始编写,测试连接,再一直往上做,直到最终
完成为止。
按结构化程序设计方法编写出的程序,具有风格优美、结构优良、层次清晰、容易
阅读和理解、容易修改和验证等优点。
程序结构化的首要问题是程序的模块化。一个大型程序划分成若干个功能模块,其
中有一个模块称为主模块,由它选择和调用其他各个功能模块,被调用的各个模块称为
子模块。这种将一个复杂的大型程序按其功能划分为若干相对独立的模块进行程序设计
的方法称为程序的模块化。在汇编语言程序设计中,程序模块化是通过子程序(或过程)
的手段来实现的。
程序的基本结构包括顺序结构、分支结构、循环结构,下面分别阐述。
4.4.1 顺序程序设计
顺序结构是按语句实现的先后次序执行一系列的操作。顺序结构的程序一般是简单
程序。这种程序也叫直线程序。
【例 4.2】把非压缩的十进制数 DAT1 转化为压缩的十进制数。
完成上述功能的程序段为:
MOV AX, DAT1 ;例如 AX=0204H
MOV CL, 4
SAL AH, CL ;AH=20H,AX=2004H
ROL AX, CL ;AX=0042H
ROL AL, CL ;AL=24H,∴AX=0024H
MOV BYTE PTR DAT1,AL ;DAT1 中为 24H 为压缩的十进制数

4.4.2 分支程序设计
分支结构根据不同情况做出判断和选择,以便执行不同的程序段。分支的意思是在
两个不同的操作中选择其中的一个,如图 4.1、图 4.2、图 4.3 所示。在图 4.2 所示的两
个路径中,满足条件才执行操作。图 4.3 是多分支结构,它是在许多不同的操作中选择
其中的一个,究竟选定哪一个操作是由测试表达式来决定的。图 4.2 和图 4.3 只不过是
图 4.1 的变形而已。

满足 不满足

条件 不满足

条件

程序段1 程序段2 满足

程序段

图 4.1 选择分支图 4.2 简单分支


测试表达式

程序段1 程序段2 程序段n

图 4.3 多分支图
在很多实际问题中,都是根据不同的情况进行不同的处理。这种思想体现在程序设
计中,就是根据不同条件而跳到不同的程序段去执行,这就构成了分支程序。在汇编语
言程序设计中,跳转是通过条件转移指令来实现的。
在分支程序中,不论是两分支结构还是多分支结构,它们都有一个共同特点:运行
方向是向前的,在某种确定条件下,只能执行两个或多个分支中的一个分支。
【例 4.3】把内存中某一区域的源数据块传送到另一区域。

开始

设源、目的地址指针SI、DI计数器CX

Y N
源首地址+长度-1<目的首地址?

增量传送 减量传送

暂停

图 4.4 程序流程图
题目分析:本题要求进行数据块的传送,如果源数据块与目的数据块之间的地址
没有重叠,可以用串操作中的传送指令实现。如果它们之间的地址重叠,再用上述指令
就不可以。这要求我们先进行一个判断,看一看源地址加数据块长度是否小于目的地址。
如果是,可以按增量方式进行传递,如果不是,就要把指针修改为指向数据的底部,然
后采用减量方式传递。该例的框图如图 4.4 所示。
具体程序为:
DATA SEGMENT
STRG DB 1000DUP(?)
STG1 EQU STRG + 7
STG2 EQU STRG + 25
STRSE EQU 50
DATA ENDS

STACK SEGMENT STACK ‘STACK’


SPP DB 100DUP(?)
STACK ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
BIN PROC FAR
PUSH DS
MOV AX,0
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV CX,STRSE
MOV SI,OFFSET STG1 ;源数据块首址→SI
MOV DI,OFFSET STG2 ;目的数据块首址→DI
CLD ;增量方式
PUSH SI
ADD SI,STRSE-1
CMP SI,DI
POP SI
JL ZZ
STD ;减量方式传送
ADD SI,STRSE-1 ;指向数据底部
ADD DI,STRSE-1
ZZ: REP MOVSB ;重复传递 50 个数据
RET
BIN ENDP
CODE ENDS
END

4.4.3 循环程序设计
循环结构是重复做一系列的操作,直到某个条件出现为止。如图 4.5 和图 4.6 所示。

图 4.5 WHILE-DO 型循环图图 图 4.6 REPEAT-UNTIL 型循环图


图 4.5 是一种重复型结构,它表示如果某一条件一直成立,则重复做同一个操作或
一系列操作,直到条件不成立时为止。它是先检查条件,再去执行操作。图 4.6 这种循
环结构,先执行操作,再去检查条件成立与否,因此,这种结构至少要执行这些操作一
次。图 4.6 循环结构是由图 4.5 的循环结构演变而来,任何 REPEAT-UNTIL 型循环都
可以用 WHILE-DO 型循环表示。
循环结构和分支结构一样,是应用极为广泛的基本程序结构之一。
1. 循环程序分四部分
(1) 设置循环的初值。如设置循环次数的计数器,为使循环体正常工作而建立的
初始状态等。
(2) 循环体。循环体是循环工作的主体部分,是为完成某种特定功能而设计的程
序段。
(3) 修改部分。为保证每次循环时,相关信息(如计数器的值、操作数地址等)
能发生有规律的变化,为下次循环作好准备。
(4) 循环控制部分。循环控制是循环程序设计的关键。每个循环程序必须选择一
个恰当的循环控制条件来控制循环的运行和结束。如果循环不能工作运行,则不能完成
特定功能;如果循环不能结束,则将陷入“死循环”。因此,合理地选择循环条件就成
为循环程序设计的关键问题。有时循环次数是已知的,可使用循环次数计数器来控制;
有时循环次数是未知的,则应根据具体情况设置控制循环结束的条件。
2. 循环程序设计
控制循环是循环程序设计的关键问题。控制循环的方法很多,常用的有:
(1) 用计数器控制(循环次数已知);
(2) 按条件控制(循环次数未知) ;
(3) 用开关变量控制(分支规律已知,计数次数或循环条件已知);
(4) 用逻辑尺控制。
【例 4.4】设 a1,a2,a3,…,a100 是已知数,求这 100 个数的和,可由下列程序
实现。
DATA SEGMENT
SE DW a1,a2,…,a10
DW a11,a12,…,a20

DW a91,a92,…,a100
Y DW?
DATA ENDS

STACK SEGMENT PARA STACK ‘STACK’


DB 100DUP(?)
STACK ENDS

CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
GO PROC FAR
PUSH DS
MOV AX,0
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV AX,0
ADD AX,SE
ADD AX,SE+2
ADD AX,SE+4
加 100 次

ADD AX,SE+198
MOV Y,AX
RET
GO ENDP
CODE ENDS
END
以上程序中求和 100 次。这样设计程序当然很繁琐,由于数据是有规律存放的,
每加一项所用的指令都是一样的。只是数据的地址不一样,所以我们可以用间接寻址的
方法,将数据地址放在寄存器中,用寄存器加 1 指令修改地址。由此,上述程序可以改
写成:
1 MOV AX,0
初始化
2 MOV BX,OFFSET SE
3 MOV CX,100
4 LOP: ADD AX,[BX] ;循环体
5 INC BX
6 INC BX ; 修改部分
7 DEC CX
8 JNE LOP ;控制
9 MOV Y,AX
HLT
这个程序中,前三条指令是初始化部分。第四条指令是循环体,第五、六条指令是
修改部分,第七、八条指令是控制部分,它用 CX 作计数器。每循环一次,CX 减 1,
直至减到 0,作为循环结束条件,以达到控制循环次数的目的。第九条指令是结果处理
部分。
显然,循环程序缩短了程序的长度,而且也缩短了程序的执行时间,因此只要可用
循环结构的地方都尽量采用它。
【例 4.5】统计一个数据块中负数的个数。
题目分析:一个字节带符号数中,最高位为 1 的数就是负数。想统计出负数的个数,
先要查看每一个数的符号位,并统计其最高位为 1 的数的个数。
开始

建立数据块指针BX设置计数器CX将负数个数计 初始化
数器DX置0



取数AL

AL>0? Y

负数个数加1

修改部分
指针+1

N 控制部分
计数器-1=0?

Y
存统计结果

结束

图 4.7 程序流程图
其对应的程序为:
DATA SEGMENT
DDA DB
RR DW ?
DATA ENDS

STACK SEGMENT STACK


DB 100DUP(?)
STACK ENDS

CODE SEGMENT
ASSUME CS:CODE,ES:DATA,SS:STACK
START PROC FAR
PUSH DS
MOV AX,O
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV BX,OFFSET DDA ;建数据指针
MOV CX,RR-DDA ;设置计数器初值
MOV DX,O ;设置统计结果初值
MOV SS,AX
LOP: MOV AL,[BX]
CMP AL,O
JGE JUS
INC DX
JUS: INC BX
DEC CX
JNZ LOP
MOV RR,DX
RET
START ENDP
CODE ENDS
END
3. 多重循环程序设计
多重循环又称循环嵌套。在使用多重循环时,必须注意以下几点:
(1) 内循环必须完整地包含在外循环内,内外循环不能相互交叉。
(2) 内循环在外循环中的位置可根据需要任意设置,在分析程序流程时,要避免
出现混乱。
(3) 内循环可以嵌套在外循环中,也可以几个内循环并列存在。可以从内循环直
接跳到外循环;但不能从外循环直接跳到内循环。
(4) 防止出现“死循环”。无论是外循环,还是内循环,千万不要使循环返回到初
始部分,否则会出现“死循环”,这一点应当特别注意。
(5) 每次通过外循环再次进入内循环时,初始条件必须重新设置。
【例 4.6】设有 4 个学生参加 5 门课程的考试,试计算每个学生的平均成绩和每门
课的平均成绩。
根据题意,我们把 4 名学生的成绩依次存放在一个字数组(首址为 chg)中,把每
个学生的平均成绩和每门课的平均成绩保存在两个字数组(首址分别为 av 和 me)中,
流程图如图 4.8 所示。编写程序如下:
DATA SEGMENT Chg DW 85,92,76,88,90 DW 72,81,68,84,78
DW 90,86,94,100,80
DW 75,62,80,79,58
av DW 4 DUP(?)
me DW 5 DUP(?)
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS;DATA
MAIN PROC FAR START:PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV
DS,AX MOV CX,4 LEA BX,chg
LEA SI,av
Ll1:PUSH CX MOV AX,0 MOV CX,5
L22:ADD BX,2 ADD AX,[BX] LOOP L22 MOV DL,5 DIV DL MOV [SI],AL ADD
SI,2 POP CX LOOP Ll1 LEA BX,chg LEA SI,me MOV DI,BX MOV CX,5
L33:MOV BX,DI SUB BX,10 PUSH CX MOV AX,0 MOV CX,4
L44:ADD BX,10 ADD AX,[BX] LOOP L44 MOV DL,4 DIV DL MOV [SI],AL
ADD SI,2 ADD DI,2 POP CX LOOP L33 RET
MAIN ENDP CODE ENDS END START
开始

BX←数组首址,SI←aver的有
效地址,CX←4(初始化)

保存CX,AX←0,CX←5

BX←BX+2,AX←AX+[BX]

CX←CX-1

N
CX=0?

Y
AL←求学生的平均分数
[SI]←AL,SI←SI+2,恢复CX值

CX←CX-1

N
CX=0?

BX←数组首址,SI←mean的
有效地址,DI←BX, CX←5

BX←DI, AX←0, BX←BX-10


保存CX, CX←4

BX←BX+10,AX←AX+[BX]

CX←CX-1

N
CX=0?

Y
AL←求一门课平均分,[SI]←AL
,SI←SI+2,,DI←DI+2,恢复CX

CX←CX-1

N
CX=0?

Y
结束
图 4.8 程序流程图
4.4.4 子程序设计
1. 子程序概念
如果在一个程序中多处用到同一段程序,或者说一个程序中,在多次执行某一连串
的指令时,就把这一连串的指令抽取出来,写成一个相对独立的程序段,每当想要执行
这段程序或这一连串的指令时,就调用这段程序,执行完这段程序后,再返回原来调用
它的程序。这样每次执行这段程序时,就不必麻烦,重新去写这一连串的指令。
这样的程序段称为子程序或过程。而调用子程序的程序称为主程序或调用程序。
此外,使用子程序还有另一个主要理由。在本节一开始曾讲到“由上而下”的程序
设计方法,在这个方法中,把整个问题划分成好几个模块,把每个模块再划分成更小的
模块,直到每个模块的算法都描述得很清楚为止。能把一个大的问题划分成许多小的问
题,而这些小的问题就构成了一个个相对独立的模块,它们可以单独编程、调试和纠错。
这些独立的模块通常编写成子程序,而且可以被层次图中最高层的主程序调用。子程序
结构是模块化程序设计的重要工具和手段。
2. 子程序的定义
子程序是用过程定义伪指令 PROC 和 ENDP 来定义的。有关伪指令 PROC 和
ENDP 已在前面介绍过了,这里只对其类型属性作一些说明,因为它是一个过程能否
正确执行的保证。过程类型属性的确定原则:
(1) 调用程序和过程若在同一代码段中,则使用 NEAR 属性。
(2) 调用程序和过程若不在同一代码段中,则使用 FAR 属性。
(3) 主程序应定义为 FAR 属性。因为把程序的主过程看作 DOS 调用的一个子
程序,而 DOS 对主过程的调用和返回都是 FAR 属性。
另外,过程定义允许嵌套,即在一个过程定义中允许包含多个过程定义。
【例 4.7】调用程序和子程序在同一代码段中。
CODE SEGMENT

MAIN PROC FAR

CALL PPPl

RET
PPP1 PROC NEAR

CALL PPP2

RET
PPP2 PROC NEAR

RET PPP2 ENDP PPPl ENDP MAIN ENDP CODE ENDS
在本例中过程定义相当于三层嵌套,即主过程 MAIN 嵌套子过程 PPP1,而子过程
PPP1 又嵌套子过程 PPP2。因为主过程和两个子过程均在同一代码段,因此,除主过
程使用 FAR 属性外,其他两个子过程均使用 NEAR 属性。
【例 4.8】调用程序和子程序不在同一代码段。
CODEl SEGMENT

RRR PROC FAR

RET
RRR ENDP
CODEl ENDS
CODE2 SEGMENT

CALL RRR

CODE2 ENDS
本例中,因为子程序 RRR 和调用程序不在同一代码段,因此子程序 RRR 应定义
为 FAR 属性,这样调用指令 CALL 和返回指令 RET 都是 FAR 属性的。
应当指出,在一个过程中可以有一个以上的 RET 指令,这完全是根据需要而设置
的。
3. 子程序的调用和返回
子程序的调用和返回由 CALL 和 RET 指令完成,子程序的正确调用和正确返回是
正确执行子程序的保证。为了使子程序正确地执行,应特别注意一下两点:
(1) 正确选择过程的属性。
(2) 正确使用堆栈。在调用程序中执行 CALL 指令时,将把断点地址压入堆栈。
这个地址正是由子程序返回到调用程序的地址。当在子程序中执行 RET 指令时,便把
这个返回地址由堆栈弹出(称为恢复断点),返回调用程序自此继续往下执行。若在子
程序中不能正确地使用堆栈,而造成执行 RET 前堆栈指针 SP 并未指向进入子程序时
的返回地址,则必然会导致运行出错。因此在子程序中使用堆栈要特别注意。
4. 寄存器的保护与恢复
在程序设计中,通常独立编写调用程序(或主程序)与子程序,因此它们所使用的
一些寄存器和存储单元经常会发生冲突。如果调用程序在调用子程序以前的某些寄存器
或存储单元的内容在从子程序返回到调用程序后还要使用,而子程序又恰好使用了这些
寄存器或存储单元,则这些寄存器或存储单元的原有内容遭到了破坏,那就会使程序运
行出错,为防止出错,在进入子程序之前或之后,应该把子程序所使用的寄存器或存储
单元的内容保存在堆栈中,而退出子程序之前再恢复原有的内容。在主、子程序间传送
参数的寄存器不需要保护。
寄存器的保护有两种方法:
(1) 把需要保护和恢复的寄存器的内容,在调用程序中压入堆栈和弹出堆栈。这
种方法有一个好处,就是在每次调用子程序时,只要把你所需要的寄存器压入堆栈,返
回后弹出即可。但缺点是,在调用程序中,使用压入和弹出堆栈的功能会使调用程序不
容易理解,而且可能在调用程序其他地方使用某个寄存器时,却忽略把它压入堆栈内。
(2) 进入子程序后,首先把需要保护的寄存器的内容压入堆栈,而在返回调用程
序前,再恢复这些寄存器的内容。这种方法用得很多。这种方法的好处是:首先,在调
用程序中的任何地方都可调用子程序,而不会破坏任何寄存器的原有内容。其次,这种
方法只需要写一次压入和弹出堆栈群即可,省去很多麻烦。例如:
DUBT PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
RET
DUBT ENDP
注意:堆栈的工作方式是后进先出。
5. 调用程序与子程序之间的参数传递
调用程序在调用子程序时,往往需要向子程序传递一些参数;同样的子程序运行后,
也经常要把一些结果参数传回给调用程序。调用程序与子程序之间的这种信息传递称为
参数传递。
参数传递有 3 种主要的方式:1) 通过寄存器传递参数这种方式适合于传递参数
较少的一些简单程序。2) 通过地址表传递参数地址这种方式适合于参数较多的情况,
但要求事先建立地址表,通过地址表传递参数的地址,地址表可以在内存中或外设端口
中。3) 通过堆栈传递参数为了利用堆栈传递参数,必须在主程序中任何调用子程序之
前的地方,把这些参数压入堆栈,然后利用在子程序中的指令从堆栈弹出而取得参数。
同样,要从子程序传递回调用程序的参数也被压入堆栈内,然后由主程序中的指令把这
些参数从堆栈中取出。利用堆栈传递参数有两个非常重要的问题:
(1) 当使用堆栈来传递参数时,要注意堆栈溢出(stack-overflow) 。每当用堆
栈传送参数时,应当非常清楚,已经把什么东西压入了堆栈内及在子程序中每个地方的
堆栈指针是指向哪里,弄不好,会引起混乱和造成堆栈溢出。所谓堆栈溢出是指堆栈超
出了为它开辟的存储空间。
(2) 8086/8088 有四种形式的 RET 指令,一般的近程 RET 指令能把返回地址由
堆栈弹入到 IP,同时把堆栈指针加 2;一般的远程 RET 指令能由堆栈把返回的 IP 及
CS 值弹入到 IP 及 CS,同时把堆栈指针加 4,其他二种 RET 指令形式分别执行相同
的功能。但是它们把一个在指令中指定的数字加入堆栈指针。如近程 RET 6 指令会从
堆栈弹出一个字的内容到 IP 同时把堆栈指针加 2,然后再加 6 到堆栈指针,这是一种
快速方式,可以让堆栈指针往下(地址增大方向)跳过一些参数。
6. 子程序的嵌套
一个子程序可以作为调用程序去调用别的子程序,这种结构称为子程序的嵌套。只
要有足够的堆栈空间,嵌套的层次是不限的,其嵌套的层数称为嵌套深度。当调用程序
去调用子程序时,将产生断点,而子程序执行完后,返回到调用程序的断点处,使调用
程序继续往下执行。因此,对于嵌套结构,断点的个数等于嵌套的深度。如图 4.9 所示。

图 4.9 子程序嵌套示意图
图 4.9 所示的嵌套结构其嵌套深度为 3,所以断点个数也为 3。由此可见,嵌套结
构是层次结构。
4.5 DOS/BIOS 功能调用
在汇编语程序设计中,经常要用到 ROM-BIOS 的一些软中断和系统功能调用来扩
充汇编语言的功能。
4.5.1 概述
(1) ROM-BIOS( 基本 I/O 系统)是固化在 ROM 中的一组 I/O 设备驱动程序,
它为系统各主要部件提供设备级的控制,还为汇编语言程序设计者提供了字符 I/O 操
作。程序员在使用 ROM-BIOS 的功能模块时,可以不关心硬件 I/O 接口的特性,仅使
用指令系统的软中断指令(INT n) ,这称为中断调用。
例如,将一个 ASCII 字符显示在屏幕的当前所在位置,可使用 ROM-BIOS 的中断
类型号 10H,功能号为 0EH。程序段如下:
(2) 系统功能调用是微机的磁盘操作系统 DOS 为用户提供的一组例行子程序,
因而又称为 DOS 系统功能的调用。这些子程序可分为以下三个主要方面:
① 磁盘的读/写及控制管理。
② 内存管理。
③ 基本输入/输出管理(如键盘、打印机、显示器、磁带管理等),另外还有时间、
日期等子程序。
MOV AL,"?" ;要显示的字符送入 AL
MOV AH,0EH ;功能号送入 AH
INT 10H ;调用 10H 软中断
4.5.2 系统功能调用方法
为了使用方便,已将所有子程序顺序编号。例如,基本输入/输出管理中的功能调
用 1 号(键盘输入)、2 号(显示字符)、5 号(打印字符)、9 号(显示字符串)及 0A
号(接收键盘输入的字符串)。对于所有的功能调用,使用时一般需要经过以下三个步
骤:
(1) 子程序的入口参数送相应的寄存器。
(2) 子程序编号送 AH。
(3) 发出中断请求:INT 21H( 系统功能调用指令)。例如,显示一个字符串:
"Goodmorning!"
JK DB 'Goodmorning!$ '
…MOV DX,OFFSET JK MOV AH,9 INT 21H
有的子程序不需要入口参数,这时(1)可以略去,例如:
MOV AH,4CH INT 21H
子程序调用结束后,一般都有出口参数,这些出口参数常放在寄存器中,通过出口
参数,用户可以知道调用的成功与否。
4.5.3 DOS 系统功能调用
系统功能调用可以分组如下:
(1) 0~0CH:传统的字符 I/O 管理,包括键盘、显示器、打印机、异步通信口
的管理。
(2) 0DH~24H :传统的文件管理,包括复位磁盘,选择磁盘,打开文件,关
闭文件,查找目录项,删除文件,顺序读、写文件,建立文件,重新命名文件,查找驱
动器分配表信息,随机读、写文件,查看文件长度等。
(3) 25H~26H:传统的非设备系统调用,包括设置中断向量,建立新程序段。
(4) 27H~29H:传统的文件管理,包括随机块读写,分析文件名。
(5) 2AH~2EH:传统的非设备系统调用,读取、设置日期、时间等。
(6) 2FH~38H :扩充的系统调用组,包括读取 DOS 版本号,中止进程,读取
中断向量,读取磁盘空闲空间等。
(7) 39H~3BH:目录组,包括建立目录,修改当前目录,删除目录项。
(8) 3CH~46H:扩充的文件管理组,包括建立、打开、关闭文件,从文件或设
备读取数据。在指定的目录里删除、移动、读、写文件,读取、修改文件属性,设备
I/O 控制,即文件标记等。
(9) 47H:目录组,取当前目录。
(10)48H~4BH:扩充的内存管理组,包括分配内存,释放已分配的内存,分配
内存块,装入或执行程序等。
(11)4CH~4FH:扩充的系统管理组,包括中止进程,查询子进程的返回代码,
查找第一个相匹配的文件,查找下一个相匹配的文件。
(12) 50H~53H:扩充的系统调用,DOS 内部使用。
(13)54~62H :扩充的系统调用,包括读取校验状态,重新命名文件,设置读
取日期和时间。从 39H 以后的文件管理系统调用是为了处理树形目录结构而提供的。
下面选择其中一 部分常用的系统功能调用分别加以介绍,其余部分可参考有关的 DOS
资料。
1) 带显示键盘输入(1 号调用) 1 号系统功能调用等待从标准输入设备输入一
个字符,并送入寄存器 AL,不需入口参数。例如:MOV AH,1 INT 21H
执行上述指令,系统将扫描键盘,等待有键按下。一旦有键按下,就将键值(ASCII
码值)读入,先检查是否是 Ctrl-Break,若是,则退出命令执行;否则将键值送入 AL,
同时将这个字符显示在屏幕上。
2) 键盘输入但无显示(8 号调用) 8 号调用与 1 号调用类同,只是不在屏幕上
显示输入的字符。3) 打印输出(5 号调用) 把 DL 中的字符输出到打印机。例如:
MOV DL,A MOV AH,5 INT 21H
3) 直接控制台输入/输出 (6 号调用) 6 号调用可以从标准输入设备输入字符,
也可以向屏幕上输出字符,并且不检查 Ctrl-Break。若 DL=FFH 时,表示从键盘输入,
若标志 ZF=0,表示 AL 中为键入的字符值;若标志 ZF=1,表示 AL 中不是键入的字
符值,即尚无键按下。若 DL≠FFH 时,表示向屏幕输出,DL 中为输出字符的 ASCII 码
值。例如:MOV DL,0FFH MOV AH,6 INT 21H 为从键盘输入字符。
MOV DL,24H MOV AH,6 INT 21H
将 24H 对应的字符$输出,即从屏幕上显示“$”。
4) 直接从控制台输入但不显示(7 号调用) 等待从标准输入设备输入字符,然
后将其送入 AL,同 6 号调用一样,对字符不做检查。
5) 输出字符串 (9 号调用) 调用时,要求 DS:DX 必须指向内存中一个以“$”
作为结束标志的字符串。字符串
中每一个字符(不包括结束标志)都输出打印。例:
·118·
DATA SEGMENT
BUF DB‘HOW DO YOU DO ?$’ DATA ENDS CODE SEGMENT
… MOV AX,DATA MOV DS,AX
… MOV DX,OFFSET BUF MOV AH,9 INT 2Lh

CODE ENDS
执行本程序,屏幕上将显示:HOWDOYOUDO? 7) 输入字符串 (0AH 号调用)
从键盘接收字符串到内存输入缓冲区,缓冲区内第一个字节单元指出缓冲区能容纳字节
个数,不能为 0,第二个字节保留用作填写输入字符的实际个数。从第三个字节开始存
放从键盘接收字符串。如果实际输入的字符少于定义的字符数,缓冲区将空余的字节填
零。如果实际输入的字符多于定义的字符数,将后来输入的字符丢掉,且响铃。调用时,
要求 DS:DX 必须指向缓冲区。
DATA SEGMENT
BUFDB 50 ;缓冲区长度 DB? ;保留为填入实际输入的字符个数 DB 50 DUP
(?) ;定义 50 个字节存储空间
DATA ENDS CODE SEGMENT
… MOV AX,DATA MOV DS,AX
… MOV DX,OFFSET BUF MOV AH,10 ;即 0AH 送 AH INT 21H
CODE ENDS
习题 4
4-1. 写出完成下列要求的变量定义语句:
(1) 为某缓冲区 BUFF 预留 240 个字节的存储空间。
(2) 将字符串‘BYTE’、‘WORD’存放于某数据区。
4-2. 以图示说明下列语句实现内存分配和预置数据:
VARl DB ‘12’,12H,3 DUP(0,FFH) VAR2 DB 100 DUP(0,2 DUP((1,2)

0,3) VAR3 DB ‘HELLO. COM’ VAR4 DW VAR+6 VAR5 DD VAR3
4-3. 下列语句中,哪些是无效的汇编语言指令?并指出无效指令中的错误。
MOV SP,AL MOV WORD-OP[BX+4X3][SI],SP MOV VARl,VAR2 MOV CS,
AX MOV DS,BP MOV SP,SS:DATA-WORD[SI][DI] MOV AX,VARl+VAR2 MOV
AX,[BX-SI] INC [BX] MOV 25,[BX] MOV [8-BX],25
4-4. 若 x、y、z 已定义为字节变量,若 x 和 y 各存放一个 32 位的无符号数(存放顺
序是低位字节在先),试写出将 x 和 y 相加后结果存入 z 的程序段。
4-5. 若题 4 中 x、y 各存放一个 32 位的有符号数(低字节数在前),试编写 x-y 且结
果存入 z 的程序段,同时判断运算结果是否发生溢出,若不溢出使 DL 清零,否则(溢
出)以-1 作为标志存入 DL 中。
4-6. 若数组 ARRAY 在数据段中已作以下定义:ARRAY DW 100DUP(?)
4-7. 若 ARRAY 和 MAX 都定义为字变量,并在 ARRAY 数组中存放了 10 个 16 位无
符号数,试编写程序段,找出数组中最大数,并存入变量 MAX 中。
4-8. 若 ARRAY 数组存放的是有符号数,试编写相应的程序实现对数组求和,结果存
在变量 SUM 中。
4-9. 试编写一程序段,完成两个以压缩型 BCD 码格式表示的 16 位十进制数的加法运
算,相加的两数 x 和 y 可定义为字节变量,并假定高位在前,和数 SUM 也同样定义
为字
试指出下列语句中各操作符的作用,指令执行后有关寄存器产生了什么变化。
MOV BX,OFFSET ARRAY
MOV CX,LENGTH ARRAY
MOV SI,0
ADD SI,TYPE ARRAY
4-10. 编写一个统计 AX 中 1 的个数的程序段,统计结果存放在 CL 中。
4-11. 编写一个判断 AX 中的数是正数、负数还是零的程序段。若(AX)<0,以-1 存
入 CL;(AX)=0,以 0 存入 ClI 否则若(AX)>0,以 1 存入 CL。
4-12. 假定有一最大长度为 80 个字符的字符串已定义为字节变量 STRING,试编写一
程序段,找出第一个空格的位置(00H 至 4FH 表示),并存入 CL 中,若该串中无空
格符,则以-1 存入 CL 中。
4-13. 对题 12,若该字符串以回车符结束,试编写一段程序,统计该串的实际长度(不
包括回车符) ,统计结果存入 CL 中。
4-14. 编写统计 AX 中 0、1 个数的程序。0 的个数存入 CH,l 的个数存入 CL 中。
4-15. 编程将 AX 中的 4 位 BCD 码转换成二进制数,转换结果存放在 AX 中。
4-16. 编程将 AX 中的二进制数转换成 4 位 BCD 码,转换结果存放在 AX 中。
4-17. 编程将内存中以 AFG 为首址 ASCII 字符串,以$为结束符,转换成十进制数存
放在以 ZC 为首址的单元。
4-18. 试将一个 2 位十进制数的压缩的 BCD 码转换成十六进制数,并在屏幕上显示出
来。
4-19. 设有两个无符号数 125 和 378 ,其首地址为 x,求它们的和,将结果存放在 SUM
单元,并将其和转换为十六进制数,且在屏幕上显示出来。
4-20. 内存中从 FIRST 和 SECOND 开始的单元中分别存放着两个 4 位非压缩型的
BCD 码,数据存放的规则是:低位在低地址,高位在高地址。试编程求这两个数的和,
并存放到从 THIRD 开始的内存单元中。
第 5 章 存储器

存储器是计算机中用来存储信息的部件,是微型计算机系统不可缺少的
组成部分,是计算机中各种信息的存储和交流中心。

5.1 概述

5.1.1 存储器的分类

存储器按照其制造材料、在微型计算机系统中的作用、读写功能、信息
的保存情况等来区分,可以有以下几种分类方法:
按存储器所采用的存储介质分类,有采用半导体材料存储信息的半导体
存储器;有采用磁性材料存储信息的磁表面存储器,还有采用光学材料存储
信息的光表面存储器。
按存储器在微型计算机系统中的作用分,有内存储器、外存储器和高速
缓冲存储器(Cache)。直接和 CPU 相联系,作为微型计算机的组成部分,
用于存放当前正在运行的程序和数据的快速存储器称为内存储器或主存储
器。内存储器的存取速度很快,存取周期为几十 ns 左右。不直接和 CPU 相
联系,用来存储 CPU 当前操作暂时用不到的程序或数据的存储器称为外存
储器或辅助存储器。外存储器存储容量大,但存取速度慢。在高性能的微型
机系统中采用高速缓冲存储器作为 CPU 与内存储器之间的缓冲器,用来暂
存 CPU 正在使用的指令和数据,容量只有几 K 到几百 K 字节,但存取速度
同高速 CPU 相一致,因此可用充分发挥 CPU 的高性能。
半导体存储器按存储器读写功能,分为随机存取存储器(Random Access
Memory)和只读存储器(Read Only Memory)。
1. 只读存储器(ROM)
只读存储器一般是指机器运行期间存储内容固定不变,只能读出信息,
而不能随时写入信息的存储器。断电后,ROM 中存储的信息仍保留不变,
所以,ROM 是非易失性存储器。因此,微型系统中常用 ROM 存放固定的程
序和数据,如监控程序、操作系统中的 BIOS(基本输入/输出系统)、BASIC
解释程序或用户需要固化的程序。按照构成 ROM 的集成电路内部结构的不
同,ROM 可分为以下几类:
1) 掩膜 ROM
掩膜 ROM 是一种线路最简单半导体电路,利用掩膜工艺制造,由存储
器生产厂家根据用户要求进行编程,程序和数据在制造器件过程中已经写
入,一旦做好,不能更改。因此,只适合于存储成熟的固定程序和数据,大
量生产时成本很低。例如,键盘的控制芯片。
2) 可编程 ROM
可编程 ROM 简称 PROM(Programmable ROM)。该存储器在出厂时器件
中没有任何信息,是“空白存储器,根据用户需要,利用特殊方法写入程序
和数据,即对存储器进行编程。但只允许写入一次,写入后信息是固定的,
不能更改,所以也被称为“一次可编程只读存储器”(One Time Programming
ROM,OTP-ROM)。PROM 在出厂时,存储的内容全为 1,用户可以根据需
要将其中的某些单元写入数据 0(部分的 PROM 在出厂时数据全为 0,则用户
可以将其中的部分单元写入 1), 以实现对其“编程”的目的。PROM 的典
型产品是“双极性熔丝结构”,如果我们想改写某些单元,则可以给这些单
元通以足够大的电流,并维持一定的时间,原先的熔丝即可熔断,这样就达
到了改写某些位的效果。另外一类经典的 PROM 为使用“肖特基二极管”的
PROM,出厂时,其中的二极管处于反向截止状态,还是用大电流的方法将
反相电压加在“肖特基二极管”,造成其永久性击穿即可。
3) 可擦除 PROM
可擦除 PROM 简称 EPROM(Erasable Programmable ROM)。这种存储器
允许用户按照规定的方法和设备进行多次编程,如编程后想更改,可用紫外
线灯制作的擦除器照射 7~30 分钟左右(新的芯片擦除时间短,多次擦除过
的芯片擦除时间长),即可使存储器全部复原,用户可以再次写入新的内容。
这对于工程研制和开发特别方便,因此应用十分广泛。这一类芯片特别容易
识别,其封装中包含有“石英玻璃窗”,一个编程后的 EPROM 芯片的“石
英玻璃窗”一般使用黑色不干胶纸盖住,以防止遭到阳光直射。
4) 电可擦 PROM
电 擦 除 的 PROM 简 称 EEPROM 或 E2PROM(Electrically Erasable
PROM)。这种存储器能以字节为单位擦除和改写,而不像 EPROM 那样整体
地擦除;也不需要把芯片从用户系统中取下来用编程器编程,在用户系统中
即可进行改写。随着技术的进步,E2PROM 的擦写速度将不断加快,容量也
将不断提高,将可作为不易失的 RAM 使用。
5) 闪速存储器(Flash memory)
闪速存储器,简称 Flash 或闪存。它与 E2PROM 类似,也是一种电可擦
型 ROM。与 E2PROM 的主要区别是:E2PROM 是按字节擦写,速度慢;而
闪存是按块擦写,速度快,一般在 65~170ns 之间。Flash 芯片从结构上分为
串行传输和并行传输两大类:串行 Flash 能节约空间和成本,但存储容量小,
速度慢;而并行 Flash 存储容量大,速度快。
Flash 是近年来发展非常快的一种新型半导体存储器。由于它具有在线
电可擦写,低功耗,大容量,擦写速度快的特点,同时,还具有与 DRAM
等同的低价位,低成本的优势,因此受到广大用户的青睐。目前,Flash 在
微机系统、嵌入式系统和智能仪器仪表等领域得到了广泛的应用。
掩膜
ROM

可编程 ROM
(PROM)
只读存储器
(ROM) 可擦除 ROM
(EPROM)
半导体存储器

电可擦 PROM
(E2PROM)

闪速存储器 非易失 RAM


(Flash memory) (NVRAM)

双极型
静态 RAM
随机读写 RAM
(SRAM)
存储器
(RAM) MOS 型
RAM 动态 RAM
(DRAM)

图5.1 半导体存储器的分类
2. 随机存取存储器(RAM)
随机存取存储器一般是指机器运行期间存储内容可以改变,既可以读出
信息又能够随时写入信息的存储器。RAM 中存放的信息在关闭电源时会全
部丢失,所以,RAM 是易失性存储器,只能用来存放暂时性的输入/输出数
据、中间运算结果和用户程序,也常用它来与外存交换信息或用作堆栈。通
常人们所说的微机内存容量就是指 RAM 存储器的容量。随机存取存储器可
分为双极型和 MOS 型两种,双极型读写速度高,但是功耗大,集成度低,
所以在微型计算机中几乎都采用 MOS 型。按照 RAM 存储器存储信息电路
原理的不同,RAM 可分为以下几类:
1) 静态 RAM
静态 RAM 即 SRAM(Static RAM),其存储电路以双稳态触发器为基础,
状态稳定,只要不掉电,信息不会丢失。优点是工作速度快、稳定可靠,不
需要外加刷新电路,使用方便。缺点是集成度低。适用于不需要大存储容量
的微型计算机(例如,单板机或单片机)中,一般高速缓冲存储器(Cache
Memory)也由它组成。
2) 动态 RAM
动态 RAM 即 DRAM(Dynamic RAM),其基本存储电路由一个晶体管
及一个电容组成,因此电路简单,集成成本较低,另外耗电也少,但电容中
电荷由于漏电会逐渐丢失,为维持 DRAM 所存信息不变,需要定时地对
DRAM 进行刷新(Refresh),即对电容补充电荷。DRAM 集成度可以做得很
高,成本低、功耗少,但它需外加刷新电路。DRAM 的工作速度比 SRAM
慢,一般微型机系统中的内存储器多采用 DRAM。
3) 非易失 RAM
非易失 RAM 即 NVRAM(Non-Volatile RAM) 或称掉电自保护 RAM,其
存储单元由 SRAM 和 EEPROM 共同构成,正常运行时和 SRAM 一样,而在
掉电或电源有故障的瞬间,把 SRAM 的信息保存在 EEPROM 中,从而使信
息不会丢失。适用于存储非常重要的信息和掉电保护。
5.1.2 半导体存储器的组成

� �
半导体存储器由地址寄存器,译码电路、储存体、读/写控制电路、数据
� �
� �
寄存器、控制逻辑等几个部分组成。如下图所示:
� �
� �
� �
� � �
� � �
� � �

……
AB DB
� M �
MAR MDR

� � � �

� � � � � /�

图5.2 存储器的基本组成
1. 存储体
基本存储电路是组成存储器的基础和核心,它用于存放一位二进制信息
“0”或“1”。若干记忆单元(或称基本存储电路)组成一个存储单元,一
个存储单元一般存储一个字节,即存放 8 位二进制信息,存储体是存储单元
的集合体。
2. 译码驱动电路
该电路实际上包含译码器和驱动器两部分。译码器的功能是实现多选 1,
即对于某一个输入的地址码,N 个输出线上有唯一一个高电平(或低电平)
与之对应。例如,A4A3A2A1A0=00000 时,仅有 X0 输出为高电平,其它 X1~
X31 输出均为低电平;A4A3A2A1A0=00001 时,仅有 X1 为高电平,其它均为
低电平。
为了区分存储体中的具体存储单元,必须对它们逐一进行编号,此编号
即为对应存储单元的地址,为了对某指定存储单元寻址,计算机中采用地址
译码予以实现。常用的地址译码有两种方式,即单译码和双译码方式。
1) 单译码方式
单译码方式是一个“N 中取 1”的译码器,如下图所示:

P� � � �
AP-1 AP-2 A1 A 0 �
… �
N� 1� � � � � � � � �

Wn-1 … W1 W0 �
D0

M D1
� � � � � �
� � � M�


DM-1

N� � �
N=2P� � �

图5.3 单译码寻址示意图
译码器输出驱动 N 根字线中的一根,每根字线由 M 位组成。若某根字
线被选中,则对应此线上的 M 位信号便同时被读出或写入,经输出缓冲放
大器输出或输入一个 M 位的字。
在上图中,若字线 N 为 16,M 为 4 位,则地址译码器地址输入线 P 应
为 4 位,24=16 个状态,分别控制 16 条字线(W0~W15)。当地址信号为 0000
时,选中字线 W0,若进行读出操作,则该字线上的 4 位同时被读出;若地
址信号为 1111,则选中第 16 条字线 W15,此时如果是写操作,则该字线上
的 4 位便同时被写入。
单译码方式主要用于小容量的存储器,对于大容量的存储器,可采用双
译码方式。
2) 双译码方式
双译码方式采用的是两级译码电路。当字选择线的根数 N 很大时,N=2P
中的 P 必然也大,这时可将 P 分成两部分,
P q+r
如: N = 2 = 2 = 2q × 2r = X × Y ,
这样便将对 N 的译码分别由 X 译码和 Y 译码两部分完成。
10 5 5
现以 P=10 为例,可以分为: N = 2 = 2 × 2 = 32 × 32 = 1024 ,其
译码结构如下图所示:
X0 � � � � � �
A0
X
A1 (� )
� W0,0 … W0,31


A2 �

A3 �


X31
A4 �
W31,3
W31,0 …
1

Y0 … Y31
R/W� �
Y(� )� � � � � I/O� � � � � � /� �

A5 A6 A7 A8 A9

图5.4 双译码结构示意图
图中,1024 个字排成 32×32 的矩阵,需要 10 根地址线 A9~A0,分成
X 和 Y 两部分,A4~A0 输入至 X 方向(行)译码器,它输出 32 条字选择线,
分别选择 32 行(X0~X31);A9~A5 输入至 Y 译码器,它输出的 32 条位选
择 线 分 别 选 择 Y0 ~ Y31 列 , 它 控 制 各 列 的 位 线 控 制 门 。 设 A9 ~
A0=0000000000,则 X 地址译码输出 X0 为高电平,选中 X0 行,此时 X0 行控
制的 W0,0,W0,1,W0,3,…,W0,31 各位都有可能被选中进行读(写)操作,
具体选中哪一位,取决于 Y 地址译码,根据此例的设定,Y 地址译码输出
Y0 应为高电平,列线 Y0 有效,此列控制的位线控制门打开,故 X、Y 双向
译码结果,选中 W0,0 位基本存储电路,即可对这一位存储电路进行读(写)
操作。如果一个存储字有 8 位,就需要 8 个这样的 X、Y 阵列。当一个地址
被选中时,8 个阵列同时被激励,从而构成该地址单元的 8 位同时被读出(或
写入)。
在半导体存储器中,一个或几个 X,Y 阵列被集成在一块芯片上,如果
将存储字的 8 位都集成在一块芯片内,这种存储器芯片为字结构,如 Intel
2732ROM、Intel 6116RAM 其存储容量分别为 4K×8bit、2K×8bit;如果芯
片中集成的是各存储字的同一位或几位,这种芯片则称为位结构芯片,如
Intel 2614ARAM、Intel 2114RAM 其存储容量分别为 64K×1bit 和 1K×4bit。
与单译码方式比较,双译码寻址可减少输出选择线的数目。仍以 P=10
为例,采用单译码方式,译码输出需要 1024 根选择线,若采用双译码,排
成 32×32 的矩阵,输出状态仍为 1024 个,但译码输出选择线却只需要
32+32=64 根,大大减少了选择线的数目。存储器容量越大,此优点越突出。
3. 地址寄存器
用于存放 CPU 访问存储单元的地址,经译码驱动后指向相应的存储单
元。通常微型计算机中,访问地址由地址锁存器提供,如 8086CPU 中的地
址锁存器 8282;存储单元地址由地址锁存器输出后,经地址总线送到存储器
芯片内直接译码。
4. 读/写电路
包括读出放大器、写入电路和读/写控制电路,用以完成对被选中单元中
各位的读出或写入操作。存储器的读/写操作是在 CPU 的控制下进行的,只
有当接收到来自 CPU 的读/写命令后,才能实现正确的读/写操作。
数据寄存器用于暂时存放从存储单元读出的数据,或从 CPU 或 I/O 端口
送出的要写入存储器的数据。暂存的目的是为了协调 CPU 和存储器之间在
速度上的差异,故又称之为存储器数据缓冲器。
控制逻辑接收来自 CPU 的启动、片选、读/写及清除命令,经控制电路
综合和处理后,产生一组时序信号来控制存储器的读/写操作。

5.1.3 存储器的基本性能指标

存储器是微机系统的重要部件之一,计算机在运行过程中,大部分的总
线周期都是对存储器进行读/写操作,因此存储器性能的好坏在很大程度上直
接影响计算机的性能。衡量半导体存储器性能的指标很多,但从功能和接口
电路的角度来看,最重要的有以下几项。
1. 存储容量
存储器可以存储的二进制信息总量称为存储容量。存储容量是存储器的
一个重要指标,通常用该存储器所能存储的字数及其字长的乘积来表示:
存储容量=存储器单元数×每单元二进制位数。
应该注意:一位二进制数为最小单位(bit),8 位二进制数为一个字节
(Byte),单位用 B 表示。由于微机中都是按字节编址的,因此字节(B)是
存储器容量的基本单位。对于大容量存储器还可以用千字节(KB)、兆字节
(MB)、吉字节(GB)、太字节(TB)等表示。
其换算关系为:1KB=210B=1024B 1MB=220B=1024KB
1GB=230B=1024MB 1TB=240B=1024GB
2. 存取速度
存取速度通常用存取时间来衡量。存取时间是指从启动一次存储器操作
到完成该操作所经历的时间。存取时间又称为访问时间或读/写时间。例如,
读出时间是指从 CPU 向存储器发出有效地址和读命令开始,直到将被选单
元的内容读出送上数据总线为止所用的时间;写入时间是指从 CPU 向存储
器发出有效地址和写命令开始,直到信息写入被选中单元为止所用的时间。
显然,存取时间越短,存取速度越快。
内存的存取时间通常用 ns(纳秒)表示。在一般情况下,超高速存储器
的存取时间约为 20ns,高速存储器的存取时间约为几十纳秒,中速存储器的
存取时间约为 100~250ns,而低速存储器的存取时间约为 300ns 左右。例如,
SRAM 的存取时间约为 60ns,DRAM 的存取时间约为 120~250ns。
3. 可靠性
可靠性是指在规定的时间内,存储器无故障读/写的概率。通常用平均无
故障时间 MTBF(Mean Time Between Failures)来衡量可靠性。MTBF 可以
理解为两次故障之间的平均时间间隔,越长说明存储器的性能越好。
4. 功耗
功耗反映存储器件耗电的多少,同时也反映了其发热的程度。功耗越小,
存储器件的工作稳定性越好。大多数半导体存储器的维持功耗小于工作功
耗。
5. 价格
常用每位的价格来衡量。一般来说,主存储器的价格较高,辅助存储器
的价格则低得多。
存储器总价格正比于存储容量,反比于存取速度。一般来说,速度较快
的存储器,其价格也较高,容量也不可能太大。因此,容量、速度、价格 3
个指标之间是相互制约的。
所以,用户在设计和选用存储器时还要综合考虑这些因素,要根据实际
需要全面衡量,尽可能满足主要要求并兼顾其他,尽量提高性能价格比。
5.1.4 存储系统的层次结构

所谓存储系统的层次结构,就是把各种不同存储容量、存取速度和价格
的存储器按层次结构组成多层存储器,并通过管理软件和辅助硬件有机组合
成统一的整体,使所存放的程序和数据按层次分布在各种存储器中。目前,
在计算机系统中通常采用三级层次结构来构成存储系统,主要由高速缓冲存
储器 Cache、主存储器和辅助存储器组成,如图 5-5 所示。
CPU

高速缓存

主存储器

I/O 控制电路

辅存 磁盘 光盘 磁带

图5.5 存储系统的多级层次结构
在图 5-5 所示的存储系统多级层次结构中,由上向下分三级,其容量逐
渐增大,速度逐级降低,成本则逐次减少。整个结构又可以看成两个层次:
它们分别是主存-辅存层次和 Cache-主存层次。这个层次系统中的每一种
存储器都不再是孤立的存储器,而是一个有机的整体。它们在辅助硬件和计
算机操作系统的管理下,可把主存-辅存层次作为一个存储整体,形成的可
寻址存储空间比主存储器空间大得多。由于辅存容量大,价格低,使得存储
系统的整体平均价格降低。由于 Cache 的存取速度可以和 CPU 的工作速度
相媲美,故 Cache-主存层次可以缩小主存和 CPU 之间的速度差距,从整体
上提高存储器系统的存取速度。尽管 Cache 成本高,但由于容量较小,故不
会使存储系统的整体价格增加很多。
一个较大的存储系统是由各种不同类型的存储设备构成,是一个具有多
级层次结构的存储系统。该系统既有与 CPU 相近的速度,又有极大的容量,
而成本又是较低的。其中高速缓存解决了存储系统的速度问题,辅助存储器
则解决了存储系统的容量问题。采用多级层次结构的存储器系统可以有效的
解决存储器的速度、容量和价格之间的矛盾。

5.2 随机存储器(RAM)

常用的随机存取存储器有静态随机存取存储器 SRAM 和动态随机存取


存储器 DRAM 两种,SRAM 主要用在高速缓冲存储器或小容量的存储系统
中,而 DRAM 主要用做内存。本节介绍典型 RAM 存储器芯片的特性、引脚
信号和操作方式。

5.2.1 静态随机存储器(SRAM)

1. SRAM 的基本存储电路
SRAM 的基本存储电路通常由两个 MOS 反相器交叉耦合而成的触发器
构成,一个存储元存储一位二进制代码,如下图所示:

? ? ?
VCC

V3 V4
A B
V5 V6

V1 V2

I/O I/O
图5.6 静态 RAM 存储电路
电路中,V1~V4 所示的 MOS 管组成双稳态触发器,V1、V2 为放大管,
V3、V4 为负载管。此电路有两个稳定的状态,并且 A、B 两点的电位总是互
为相反,因此它能表示一位二进制的 1 和 0。
写“1”:在 I/O 线上输入高电位,在 I / O 线上输入低电位,V5、V6 两个
控制管导通,把高、低电位分别加在 A、B 两点,使 V1 管截止,V2 管导通,
将“1”写入存储单元。当写入信号和地址译码信号消失后,V5、V6 截止,
该状态保持。
写“0”:在 I/O 线上输入低电位,在 I / O 线上输入高电位,V5、V6 两个
控制管导通,把低、高电位分别加在 A、B 两点,使 V1 管导通,V2 管截止,
将“0”写入存储单元。当写入信号和地址译码信号消失后,V5、V6 截止,
该状态保持。
读操作:若某个存储元被选中,则该存储元的 V5、V6 管导通,A、B 两
点的信息被送到 I/O 与 I / O 线上。I/O 与 I / O 线连接差动读出放大器,从其
电流方向可以判知所存信息是“1”还是“0”。
2. SRAM 基本结构
静态 RAM 通常由地址译码、存储矩阵、读/写控制逻辑及三态数据缓冲
器 4 部分组成,1K×1 的静态 RAM 芯片的内部组成框图如下图所示:
1
A0 �
A1 (X) 2 32×32 �
� � � � �

� 32

A4 �


1
…… 32
2
� /� � � /� �
� � � (Y)� � � I/O� � � �

C A9 A8 A7 A6 A5
R/W
S
图5.7 静态 RAM 内部结构示意图
1)存储矩阵
存储矩阵是由许多基本存储元电路组成,通常排列成二维矩阵形式。本
例中采用位结构,即将所有单元(1024 个)的同一位制作在同一芯片上,并
排成 32×32 方阵,1024 个单元需要 10 条地址线,其中 5 条(A4~A0)用
于行(X)译码,5 条(A9~A5)用于列(Y)译码,行、列同时选中的单元
为所要访问的单元。这种结构的优点是芯片封装时引线较少。
2)地址译码器
CPU 在读/写一个存储单元时,总是先将访问地址送到地址总线上,然
后将高位地址经译码后产生片选信号( CS )选中某一芯片,用低位地址送
至存储器,经片内地址译码器译码选中所需的存储单元,只有行、列方向同
时选中的单元才是所要访问的单元,最后在 CPU 的读/写命令控制下完成对
该单元的读出或写入。
3)读/写控制与三态数据缓冲器
CPU 送出的访问地址中用高位部分经译码后送到读/写控制逻辑的 CS
输入端,作为片选信号,表示该芯片被选中,允许对其进行读/写。当读/写
命令送入存储器芯片的读/写控制电路的 R/W 端时,被选中存储单元中的数
据经三态 I/O 数据缓冲器的 D7~D0 端送数据总线(读操作时),或将数据总
线上的数据经三态 I/O 数据缓冲器写入被选中的存储单元(写操作时)。
3. SRAM 芯片举例
常用的典型 SRAM 芯片有 6116(2KB),6264(8KB),62256(32KB)
等,它们的引脚信号功能及操作方式基本相同。下面以 6116,6264 为例加
以介绍。
(1) Intel 6116 芯片
Intel 6116 是 24 引脚双列直插式芯片,采用 CMOS 工艺制造,芯片容量
为 2K×8bit,共 11 根地址线,7 根用于行地址译码输入,4 根用于列译码地
址输入,每条列线控制 8 位。6116 引脚如下图所示:
A10 ?
A7 1 24 VCC 128×128
?


A6 2 23 A8 ? ? ? ?
A4 ?
A5 3 22 A9 …
A4 4 21 WE
D7 ? I/O
A3 5 20 OE ? ? …

A2 6 19 A10 ? ? ? ? ?
D0
A1 7 18 CS
A0 8 17 D7 …
D0 9 16 D6 A3 A0
D1 10 15 D5
D2 11 14 D4 CS
GND 12 13 D3 WE ? ? ? ?
OE

图5.8 6116 引脚和功能框图


A10~A0(address inputs):地址线,可寻址 2KB 的存储空间。
D7~D0(data bus):数据线,双向,三态。
OE(Output Enable):读出允许信号,输入,低电平有效。
WE (Write Enable):写允许信号,输入,低电平有效。
CS (Chip Select):片选信号,输入,低电平有效。
VCC:+5V 工作电压。
GND:信号地。
6116 的操作方式由 CS 、 WE 、 OE的共同作用决定,见下表:
表5.1 Intel 6116 操作方式
操作方式 CS WE OE D7~D0

写入 0 0 × 数据输入
读出 0 1 0 数据输出
保持 1 × × 高阻
①写入:当和为低电平时,数据输入缓冲器打开,数据由数据线 D7~
D0 写入被选中的存储单元。
②读出:当和为低电平,且为高电平时,数据输出缓冲器选通,被选中
单元的数据送到数据线 D7~D0 上。
③保持:当为高电平、和为任意时,芯片未被选中,处于保持状态,数
据线呈现高阻状态。
(2) Intel 6264 芯片
Intel 6264 的容量为 8KB,是 28 引脚双列直插式芯片,采用 CMOS 工艺
制造,引脚信号如图 5.9 所示。
NC 1 28 VCC
A12 2 27 WE
A7 3 26 CS2
A6 4 25 A8
A5 5 24 A9
A4 6 626 23 A11
A3 7 22
A2 8
4 21
OE
A10
A1 9 20 CS1
A0 10 19 D7
D0 11 18 D6
D1 12 17 D5
D2 13 16 D4
GND 14 15 D3

图5.9 6264 引脚图


A12~A0(address inputs):地址线,可寻址 8KB 的存储空间。
D7~D0(data bus):数据线,双向,三态。
OE (Output Enable):读出允许信号,输入,低电平有效。
WE (Write Enable):写允许信号,输入,低电平有效。
CS1 (Chip Select):片选信号 1,输入,在读/写方式时为低电平。
CS2(Chip Select):片选信号 2,输入,在读/写方式时为高电平。
VCC:+5V 工作电压。
GND:信号地。
6264 的操作方式由 OE 、 WE 、 CS1 、CS2 的共同作用决定,见下表:
表5.2 Intel 6264 操作方式
操作方式 CS1 CS2 WE OE D7~D0

写入 0 1 0 1 数据输入
读出 0 1 1 0 数据输出
保持 1 × × × 高阻
①写入:当 CS1 和 WE 为低电平,且 OE 和 CS2 为高电平时,数据输入
缓冲器打开,数据由数据线 D7~D0 写入被选中的存储单元。
②读出:当 CS1 和 OE 为低电平,且 WE 和 CS2 为高电平时,数据输出
缓冲器选通,被选中单元的数据送到数据线 D7~D0 上。
③保持:当 CS1 为高电平,CS2 为任意时,芯片未被选中,处于保持状
态,数据线呈现高阻状态。

5.2.2 动态随机存储器(DRAM)

1. DRAM 的基本存储电路
与静态 RAM 一样,动态 RAM 也是由许多基本存储电路按照行和列来
组成的,有 4 管动态 RAM,3 管动态 RAM 和单管动态 RAM。为了减少 MOS
管数目,提高集成度和降低功耗,一般采用单管动态 RAM。单管动态 RAM
基本存储电路只有 1 个 MOS 管和 1 个电容,如下图所示:

行选择信号
V
C

刷 新
放大器
列选择信号
数据输入输出
图5.10 单管动态存储电路
由图可见,动态 RAM 存放信息靠的是电容 C,电容 C 中有电荷时,为
逻辑“1”,没有电荷时为逻辑“0”。
在读操作时,对行地址(低位地址)进行译码,使行选择线为高电平,
此行选择线使本行上所有的基本存储电路中的 MOS 管 V 导通,于是,使连
在每一列上的刷新放大器读取对应电容 C 上的电压值。刷新放大器的灵敏度
很高,放大倍数很大,并能将从电容上读得的电压值折合为逻辑“0”或逻
辑“1”,列地址(较高位地址)产生列选择信号,有了列选择信号,所选中
行上的基本存储电路才受到驱动,从而可以输出信息。在读出过程中,选中
行上所有基本存储电路中的电容上的电压都有所改变,为了在读出之后,仍
能保存所容纳的信息,刷新放大器对这些电容上的电压值读取之后又立即进
行重写。
写操作时,行选择线为高电平,本行的基本存储电路中的 V 管 处于可
导通状态,如果此时的列选择线也为高电平,对应的基本存储电路被选中,
于是,由数据输入/输出线送来的信息通过刷新放大器和 V 送到电容 C。
由于电容有漏电现象,因此,当电容 C 存有电荷时,电容会逐渐放电,
电荷流失,信息也就丢失了。所以对动态 RAM 必须间隔一段时间就刷新一
次,使原来处于逻辑电平“1”的电容的电荷得到补充,而原来处于逻辑电
平“0”的电容仍保持“0”状态。刷新间隔时间与温度有关,温度上升时,
电容的漏电会加快,所需刷新时间就短,在 70℃时,确定刷新间隔为 2ms。
虽然进行一次读/写操作实际上也进行了刷新,但这种操作本身有局限性,不
可能保证内存中所有的动态 RAM 的单元都可以通过正常的读/写操作在要求
的时间间隔内来刷新,由此,专门安排了存储器刷新周期,系统地完成对动
态 RAM 的刷新。刷新是逐行进行的,当某一行选择信号为“1”时,选中了
该行,电容上信息送到刷新放大器上,刷新放大器又对这些电容立即重写。
由于刷新时,列选择信号总是“0”,因此,电容上信息不可能被送到数据总
线上。
2. DRAM 基本结构
1)DRAM 芯片的结构特点
动态 RAM 与静态 RAM 一样,都是由许多基本存储元电路按行、列排
列组成二维存储矩阵。为了降低芯片的功耗,保证足够的集成度,减少芯片
对外封装引脚数目和便于刷新控制,DRAM 芯片都设计成位结构形式,即每
个存储单元只有一位数据位,一个芯片上含有若干字,如 4K×1 位,8K×1
位,16K×1 位,64K×1 位或 256K×1 位等。存储体的这一结构形式是 DRAM
芯片的结构特点之一。
DRAM 存储体的二维矩阵结构也使得 DRAM 的地址线总是分成行地址
线和列地址线两部分,芯片内部设置有行、列地址锁存器。在对 DRAM 进
行访问时,总是先由行地址选通信号 RAS (CPU 产生)把行地址打入内置
的行地址锁存器,随后再由列地址选通信号 CAS 把列地址打入内置的列地址
锁存器,再由读/写控制信号控制数据读出/写入。所以访问 DRAM 时,访问
地址需要分两次打入,这也是 DRAM 芯片的特点之一。行、列地址线的分
时工作,可以使 DRAM 芯片的对外地址线引脚大大减少,仅需与行地址线
相同即可。
2)DRAM 的刷新
所有的 DRAM 都是利用电容存储电荷的原理来保存信息。虽然利用
MOS 管间的高阻抗可以使电容上的电荷得以维持,但由于电容总存在泄漏
现象,时间长了其存储的电荷会消失,从而使其所存信息自动丢失。所以,
必须定时对 DRAM 的所有基本存储元电路进行补充电荷,即进行刷新操作,
以保证存储的信息不变。所谓刷新,就是不断地每隔一定时间(一般每隔 2ms)
对 DRAM 的所有单元进行读出,经读出放大器放大后再重新写入原电路中,
以维持电容上的电荷,进而使所存信息保持不变。虽然每次进行的正常读/
写存储器的操作也相当于进行了刷新操作,但由于 CPU 对存储器的读/写操
作是随机的,并不能保证在 2ms 时间内能对内存中所有单元都进行一次读/
写操作,以达到刷新效果。所以,对 DRAM 必须设置专门的外部控制电路
和安排专门的刷新周期来系统地对 DRAM 进行刷新。
3. DRAM 芯片举例
典型 DRAM 芯片有 64K×1b,64K×4b,1M×1b,1M×4b 等产品。下
面以 64K×1b 的 Intel 2164A 芯片为例,介绍其结构及工作原理。
2164A 是 16 引脚双列直插式芯片,其引脚信号如图 5.11 所示:

NC 1 16 VSS
DIN 2 15 CAS
WE 3 14 DOUT
RAS 4 13 A6
2164A
A0 5 12 A3
A2 6 11 A4
A1 7 10 A5
Vcc 8 9 A7
图5.11 Intel 2164A 引脚图
A7~A0(address inputs):地址线。
DIN(Data Input):数据输入线。
DOUT(Data Output):数据输出线。
WE (Write Enable):写允许信号,输入,低电平有效。
RAS (Row Address Strobe)
:行地址选通信号,输入,低电平有效。
CAS (Column Address Strobe):列地址选通信号,输入,低电平有效。
VCC:+5V 电源。
VSS:信号地。
Intel 2164A 芯片的存储容量为 64K×1 位,采用单管动态基本存储电路,
每个单元只有一位数据,其内部结构如图 5.12 所示。2164A 芯片的存储体
本应构成一个 256×256 的存储矩阵,为提高工作速度(需减少行列线上的
分布电容),将存储矩阵分为 4 个 128×128 矩阵,每个 128×128 矩阵配有
128 个读出放大器,各有一套 I/O 控制电路。

A0 128×128 1/128行 128×128 VDD


A1 存储矩阵 译码器 存储矩阵 VSS
A2 8位 128个读出放大器 128个读出放大器
A3 地址 1/2(1/128 1/2(1/128 1/4 输 出
A4 锁存器 列译码器) 列译码器) I/O门 缓冲器 DOUT
A5 128个读出放大器 128个读出放大器
A6 128×128 1/128行 128×128
A7 存储矩阵 译码器 存储矩阵

行时钟 列时钟 写允许 数据输入


RAS 缓冲器 缓冲器 时 钟 缓 冲 器
CAS 缓冲器
WE
DIN

图5.12 Intel 2164A 内部结构示意图


由于 2164A 每个存储单元只有 1 位,若要构成 64KB
(64K×8b)的 DRAM
存储器,需要 8 片 2164A。要实现 64KB 的 DRAM 寻址,需要 16 条地址线,
而芯片本身只有 A7~A0 共 8 条地址线,因此,该芯片采用行地址线和列地
址线分时工作的方式。其工作原理是利用内部地址锁存器和多路开关,先由
行地址选通信号 RAS 把 8 位地址信号 A7~A0 送到行地址锁存器锁存,随后
出现的列地址选通信号 CAS 把后送来的 8 位地址信号 A7~A0 送到列地址锁
存器锁存。锁存在行地址锁存器中的 7 位行地址 RA6~RA0 同时加到 4 个存
储器矩阵上,在每个存储矩阵中选中一行;锁存在列地址锁存器中的 7 位列
地址 CA6~CA0 选中 4 个存储器矩阵中的一列,选中 4 行 4 列交点的 4 个存
储单元,再经过由 RA7 和 CA7 控制的“4 选 1”I/O 门控电路,选中其中的
一个单元进行读/写。
2164A 数据的读出和写入是分开的,由 WE 信号控制。当 WE 为高电平
时,读出数据;当 WE 信号为低电平时,写入数据。芯片进行刷新的时候,
只加上行选通信号 RAS ,不加列选通信号 CAS 。可以把地址加到行译码器
上,使指定的 4 行存储单元只被刷新,而不被读/写,一般 2ms 可全部刷新
一次。实现 DRAM 定时刷新的方法和电路有多种,可以由 CPU 通过控制逻
辑实现,也可以采用 DMA 控制器实现,还可以采用专用 DRAM 控制器实现。

5.2.3 内存条

尽管 DRAM 芯片的单片容量大,但相对于 32 位 PC 的主存储器空间而


言并不算大,必须使用多个芯片组装成存储器模块才能满足 PC 内存的要求,
这种模块称为内存条。内存条经历过 8 位、32 位到 64 位的发展过程。
PC 主存储器通常不直接焊接在主板上,而是在主板上设置安装内存条
模块的插槽。内存条是一块焊接了多片存储器并带接口引脚的小型印刷电路
板,将其插入主板上的存储器插槽中即可。这样就使得 PC 主板具有配置不
同容量与不同品质存储器模块的灵活性。
1. SIMM 内存和 DIMM 内存
早期的内存条只有 8 位数据宽度,带 30 个单边引脚,称为单列直插式
存储器模块 SIMM(single in-line memory modules)。80486 主板上必须插入
4 条才能构成 32 位宽的数据总线。
从 80486 主板开始使用带有 72 个引脚的 SIMM 内存条,这种 SIMM 有
32 位数据宽度,单条存储容量有 4MB(1M×32b),8MB(2M×32b),16MB
(4M×32b),32MB(8M×32b),64MB(16M×32b)等,由访问时间大约
60~70ns 的 DRAM 芯片或扩展数据输出 EDO(extended data out)芯片组装
而成,80486 主板上使用单条即可启动。
DIMM(dual in-line memory modules)是双列直插式 168 引脚内存条,
它的数据宽度为 64 位。这种内存条的单条存储容量有 16MB(2M×64b),
32MB(4M×64b),64MB(8M×64b),128MB(16M×64b),256MB(32M
×64b),512MB(64M×64b)等。它使用 3V 电源,访问时间一般小于 10ns,
由同步动态随机存储器 SDRAM 组成。它的主要特点是把 CPU 与 DRAM 的
操作通过一个相同的时钟锁在一起,使 DRAM 在工作时与 CPU 的外部时钟
同步,即以 CPU 的外部总线时钟速率传输数据,从而解决了 CPU 与 DRAM
之间速度不匹配的问题。DIMM 的工作频率有 66MHz, 100MHz, 133MHz,
150MHz 等。
为了使系统更加稳定可靠,在实际应用中选择内存条访问速度时还应留
有余地。例如,当工作频率为 100MHz 时,访问时间为 10ns,那么应该选用
标称值少于 10ns 的存储器。l33MHz 时,理论上的访问时间为 7.5ns,实际
中则应选用 7ns 以下的芯片。
2. DDR SDRAM 内存
双速率同步动态随机存储器 DDR SDRAM(double data rate SDRAM)
是 VIA 与 ADM 两家公司联合推出的新型高速存储器芯片。其基本原理是利
用总线时钟的上升沿与下降沿在同一个时钟周期内实现两次 8 位数据传送,
从 而 达到每 个 时钟周期传送两个字节的目的。当外部总线时钟频率 为
100MHz/133MHz 时,实际操作的时钟速率可达 200MHz/266MHz,因而称为
PC200/PC266。也就是说,用这种芯片制作的 64 位内存条的理论传输速率可
达 8B×200MHz=1600MBps,或者 8B×266.7MHz=2133MBps,因而又称
为 PC1600/PC2100。

5.3 只读存储器(ROM)

只读存储器 ROM(Read-Only Memory),是一种非易失性的半导体存储器


件。在一般工作状态下,ROM 内容只能读出,不能写入。只读存储器 ROM
常用于存储数字系统及计算机中不需改写的数据,例如数据转换表及计算机
操作系统程序等。ROM 存储的数据不会因断电而消失,即具有非易失性。
对可编程的 ROM 芯片,可用特殊方法将信息写入,该过程被称为“编程”。
对可擦除的 ROM 芯片,可采用特殊方法将原来信息擦除,以便再次编程。
本节将先介绍存储器单元的工作原理,再从应用的角度出发,以几种常用的
典型芯片为例,介绍只读存储器 ROM 的工作原理、特点、外部特性以及它
们的应用。

5.3.1 掩膜 ROM

掩模 ROM 中储存的信息是在芯片制造过程中就固化好了的,用户只能
选用而无法修改原存信息,故又称为固定只读存储器 MROM。通常,用户
可将自己设计好的信息委托生产厂家在生产芯片时进行固化,但要根据用户
信息制作专用的掩模模具。
MROM 采用二次光刻掩模工艺制成,首先要制作一个掩模板,然后根
据用户程序通过掩模板曝光,在硅片上刻出图形。制作掩模板工艺较复杂,
生产周期长,因此生产第一片 MROM 的费用很大,而复制同样的 ROM 就
很便宜了,所以适合于大批量生产,不适用于科学研究。MROM 有双极型、
MOS 型等几种电路形式。
VCC

单元0
A1

址 单元1


器 单元2

A0
单元3

D3 D2 D1 D0
图5.13 掩模式 ROM 示意图
上图是一个简单的 4×4 位 MOS 管 ROM,采用单译码结构,两位地址线
A1、A0 经过译码器译码后有 4 种状态,输出 4 条选择线,分别选中 4 个存储
单元,每个单元存储有 4 位输出。在此矩阵中,行和列的交点处有管子连接
表示存储“0”信息;没有连接管子表示存储“1”信息。若地址线 A1A0=
00,则选中 0 号单元,即字线 0 为高电平,若有管子与其相连(如位线 D2、
D0),其相应的 MOS 管导通,位线输出为 0,而位线 D2、D1 没有管子与字线
相连,则输出为 1。因此,存储单元 0 输出为 0110。对于图中存储矩阵的内
容如下表所示:
表5.3 存储矩阵的内容

D3 D2 D1 D0
单元
单元 0 0 1 1 0
单元 1 1 0 1 1
单元 2 0 1 0 1
单元 3 1 0 1 0

5.3.2 可编程只读存储器(PROM)

可编程只读存储器(PROM)一般由晶体管阵列组成,用户在使用前一次
性写入信息,写入后只能读出,不能修改。根据写入原理 PROM 可分为两类:
结破坏型和熔丝型。下图所示为熔丝型 PROM 的基本存储电路:
Vcc

字线

位线Di
图5.14 熔丝式 PROM 基本存储电路
基本存储电路由 1 个三极管和 1 根熔丝组成,可存储一位信息。出厂时,
每一根熔丝都与位线相连,所有存储元的熔丝都是完好的,存储的都是“0”
信息。如果用户在使用前根据程序的需要,利用编程写入器对选中的基本存
储电路通以 20mA~50mA 的电流,将熔丝烧断,则该存储元将存储信息“1”。
由于熔丝烧断后无法再接通,因而 PROM 只能一次编程写入,编程后就不能
再修改。
写入时,按给定地址译码后,译码器的输出端选通字线,根据要写入信
息的不同,在位线上加上不同的电位,若 Di 位要写“0”,则对应位线 Di 悬
空(或接上较大电阻)而使流经被选中基本存储电路的电流很小,不足以烧
断熔丝,则该 Di 位的状态仍然保持“0”状态;若要写“1”,则位线 Di 位
加上负电位(2V),瞬间通过被选基本存储电路的电流很大,致使熔丝烧断,
即 Di 位的状态改写为“1”。在正常只读状态工作时,加到字线上的是比较
低的脉冲电位,但足以开通存储元中的晶体管。这样,被选中单元的信息就
一并读出了。是“0”,则对应位线有电流;是“1”,则对应位线无电流。在
只读状态,工作电流将会很小,不会造成熔丝烧断,即不会破坏原来存储的
信息。
不过现在这种已很少使用,几乎被 EPROM 或闪烁存储器代替。

5.3.3 可擦可编程只读存储器(Erasable PROM)

在实际工作中,一个新设计的程序往往需要经历调试、修改过程,如果
将这个程序写在 ROM 和 PROM 中,就很不方便了。因此能够重复擦写的
EPROM 被广泛应用。这种存储器利用编程器写入后,信息可长久保持,因
此可作为只读存储器。当其内容需要变更时,可利用擦除器(由紫外线灯照
射)将其擦除,各单位内容复原为 FFH,再根据需要利用 EPROM 编程器编
程,因此这种芯片可反复使用。需要注意的是,EPROM 经编程后正常使用
时,应在其照射窗口贴上不透光的胶纸作为保护层,以避免存储电路中的电
荷在阳光或正常水平荧光灯照射下的缓慢泄露。
1. EPROM 的存储单元电路
通常 EPROM 存储电路是利用浮栅 MOS 管构成的,又称 FAMOS 管
(Floating gate Avalanche Injection Metal-Oxide-Semiconductor,即浮栅雪崩注
入 MOS 管),其构造如下图所示:
VCC ?
?
?
?
SiO
S ? ? ? ?
2

P+ + + + P+ D
? ?
N? ? ? ? ?
S

(a) (b)

图5.15 浮栅 MOS EPROM 存储电路


该电路和普通 P 沟道增强型 MOS 管相似,只是浮栅管的栅极没有引出
端,而被 SiO2 绝缘层所包围,称为“浮栅”。出厂时所有 FAMOS 管的栅极
上没有电子电荷,源、漏两极间无导电沟道形成,管子不导通,此时它存放
信息 1。如果将源极和衬底接地,在衬底和漏极形成的 PN 结上加一个约 24 V
的反向电压,可导致雪崩击穿,产生许多高能量的电子,这些电子比较容易
越过绝缘薄层进入浮栅,使浮栅带上负电荷,等效于栅极上加负电压。注入
浮栅的电子数量由所加电压脉冲的幅度和宽度来控制,如果注入的电子足够
多,这些负电子在硅表面上感应出一个连接源—漏极的反型层,使源—漏极
呈低阻态,即管子呈导通状态,此时它存放信息 0。当外加电压取消后,积
累在浮栅上的电子没有放电回路,因而在室温和无光照的条件下可长期地保
存在浮栅中。
将一个浮栅管和 MOS 管串起来组成如上图所示的存储单元电路。于是
浮栅中注入了电子的 MOS 管源—漏极导通,当行选线选中该存储单元时,
相应的位线为低电平,即读取值为“0”,而未注入电子的浮栅管的源—漏极
是不导通的,故读取值为“1”。在原始状态(即厂家出厂),没有经过编程,
浮栅中没注入电子,位线上总是“l”。
消除浮栅电荷的办法是利用紫外线光照射,由于紫外线光子能量较高,
从而可使浮栅中的电子获得能量,形成光电流从浮栅流入基片,使浮栅恢复
初态。EPROM 芯片上方有一个石英玻璃窗口,只要将此芯片用紫外线照射
10~20 分钟即可擦除芯片中所存储的内容。擦除后,读出各单元的内容均为
FFH,则说明该 EPROM 已擦除。
光可擦除可编程只读存储器(EPROM)的优点是芯片可多次使用,缺点是
以整个芯片为单位的擦掉重写。尽管擦除后可以重新编程,但擦除时需要紫
外线光照射,这对于实际使用是很不方便的。在实际应用中,大多数情况下
需要以字节为单位的擦写。而且一块芯片经多次插拔之后,可能会使其外部
管脚损坏。
2. 典型 EPROM 芯片介绍
EPROM 芯片有多种型号,如 2716(2 K×8 bit)、2732(4 K×8 bit)、2764(8
K×8 bit)、27128(16 K×8 bit)、27256(32 K×8 bit)等。下面以 2764A 为例,
介绍 EPROM 的性能和工作方式。
Intel 2764A 有 13 条地址线,8 条数据线,2 个电压输入端 VCC 和 VPP,
一个片选端 CS ,此外还有输出允许 OE 和编程控制端 PGM ,其功能见下图:
D D
7 0

OE ? ? ? ?
PGM
? ? ? ? ? ? ? ?
CS
A1
A
2 Y? ? Y?

A
8
256×256
A
7 X? ?

? ? ? ?
0

图5.16 2764A 功能框图


1) 读方式
读方式是 2764A 通常使用的方式,此时两个电源引脚 VCC 和 VPP 都接
+5V, PGM 接至高电平,当从 2764A 的某个单元读数据时,先通过地址引
脚接收来自 CPU 的地址信号,然后使控制信号和 CS 、 OE 都有效,于是经
过一个时间间隔,指定单元的内容即可读到数据总线上。Intel 2764A 有七种
工作方式,如下表所示:
表5.4 2764A 的工作方式选择表
引脚
CS OE PGM A9 A0 VPP VCC 数据端功能
方式
读 低 低 高 × × VCC 5V 数据输出
输出禁止 低 高 高 × × VCC 5V 高阻
备用 高 × × × × VCC 5V 高阻
编程 低 高 低 × × 12.5V VCC 数据输入
校验 低 低 高 × × 12.5V VCC 数据输出
编程禁止 高 × × × × 12.5V VCC 高阻
低 VCC 5V 制造商编码
标识符 低 低 高 高
高 VCC 5V 器件编码
把 A9 引脚接至 11.5~12.5 V 的高电平,则 2764A 处于读 Intel 标识符模
式。要读出 2764A 的编码必须顺序读出两个字节,先让 A1~A8 全为低电平,
而使 A0 从低变高,分两次读取 2764A 的内容。当 A0=0 时,读出的内容为制
造商编码(陶瓷封装为 89H,塑封为 88H),当 A0=1 时,则可读出器件的编码
(2764A 为 08H,27C64 为 07H)。
2) 备用方式
只要 CS 为高电平,2764A 就工作在备用方式,输出端为高阻状态,这
时芯片功耗将下降,从电源所取电流由 100 mA 下降到 40 mA。
3) 编程方式
这时,VPP 接+12.5V,VCC 仍接+5V,从数据线输入这个单元要存储的数
据, CS 端保持低电平,输出允许信号 OE 为高,每写一个地址单元,都必须
在 PGM 引脚端给一个低电平有效,宽度为 45ms 的脉冲,如下图所示:
? ? ? ?
? ? ? ? ? ?

? ?

VP
P
CS

PGM

45ms
OE

图5.17 2764A 编程波形


4) 编程禁止
在编程过程中,只要使该片为高电平,编程就立即禁止。
5) 编程校验
在编程过程中,为了检查编程时写入的数据是否正确,通常在编程过程
中包含校验操作。在一个字节的编程完成后,电源的接法不变,但 PGM 为
高电平, CS 、 OE 均为低电平,则同一单元的数据就在数据线上输出,这样
就可与输入数据相比较,校验编程的结果是否正确。
在对 EPROM 编程时,每写一个字节都需 45ms 的 PGM 脉冲,速度太慢,
且容量越大,速度越慢。为此,Intel 公司开发了一种新的编程方法,比标准
方法快 6 倍以上,其流程图如下图所示:
? ?

? ? = ? ? ? ? ?

Vcc= 6.0V
Vpp= 21V

X= 0

? ? 1ms? ?

X? ?

X= 1.5? Y

N
N
? ? = ? ?

Y
? ? ? ? 3Xms? ? ?

? ? ? ? Y N
X= 1.5? ? ? ? ? ? ? ?

N
Y
? ? ? ? ?
N
Y
VCC= VPP= 21V

? ? ? ? N
? ? ? ?
? ? ? ? ? ? ? ?

Y
? ? ? ?

? ?

图5.18 Intel 对 EPROM 编程算法流程图


实际上,按这一思路开发的编程器有多种型号。编程器中有一个卡插在
I/O 扩展槽上,外部接有 EPROM 插座,所提供的编程软件可自动提供编程
电压 VPP,按菜单提示,可读、可编程、可校验,也可读出器件的编码,操
作很方便。
3. 高集成度 EPROM
高集成度 EPROM 芯片有多种型号,除了常使用的 EPROM 2764 外,还
有 27128、27256、27512 等。由于工业控制计算机的发展,迫切需用电子盘
取代硬盘,常把用户程序、操作系统固化在电子盘(ROMDISK)上,这时要用
27C010(128 K×8 bit)、27C020(256 K×8 bit)、27C040(512 K×8 bit)大容量芯
片。关于这几种芯片的使用请参阅有关手册。

5.3.4 电可擦除可编程只读存储器(E2PROM)

E2PROM 是近年来被广泛应用的种可用电擦除和编程的只读存储器,其
主要特点是能在应用系统中进行在线读写,并在断电情况下保存的数据信息
不会丢失,它既能像 RAM 那样随机地进行改写,又能像 ROM 那样在掉电
的情况下非易失地保存数据,可作为系统中可靠保存数据的存储器。因为
E2PROM 兼有 RAM 和 ROM 的双重优点,所以在计算机系统中使用 E2PROM
后,可使整机的系统应用变得方便灵活。下面以 Intel 2816 为例,说明 E2PROM
的基本特点和工作方式。
1. 2816 的基本特点
2816 是容量为 2K×8bit 的电擦除 PROM,它的逻辑符号如下图所示。
芯片的管脚排列与 2716 一致,只是在管脚定义上,数据线管脚对 2816 来说
是双向的,以适应读写工作模式。
A1 D
7
A10~ A0? ? ?
0
D7~ D0? ? ? ?
?
……
……

CS ? ?
A D
OE ? ? ? ?
0 0
CS OE VPP? ? ? ?

图5.19 2816 的逻辑符号


2816 的读取时间为 250ns,可满足多数微处理器对读取速度的要求。2816
最突出的特点是可以字节为单位进行擦除和重写。擦或写用 CS 和 OE 信号加
以控制,一个字节的擦写时间为 10ms。2816 也可整片进行擦除,整片擦除
时间也是 10ms。无论字节擦除还是整片擦除均在机内进行。
2. 2816 的工作方式
2816 有六种工作方式,每种工作方式下各个控制信号所需电平如下表所
示。从表中可见,除整片擦除外, CS 和 OE 均为 TTL 电平,而整片擦除时
电压为+9~+15V,在擦或写方式时 VPP 均为+21V 的脉冲,而其他工作方式
时电压为+4~+6V。
表5.5 2816 的工作方式选择表
引脚
CS OE VPP 数据端功能
方式
读 低 低 +4~+6V 数据输出
备用 高 × +4~+6V 高阻
字节擦除 低 高 +21V 输入为高电平
字节写 低 高 +21V 输入
片擦除 低 +9~+15V +21V 输入为高电平
擦写禁止 高 × +21V 高阻
1) 读方式
在读方式时,允许 CPU 读取 2816 的数据。当 CPU 发出地址信号以及
相关的控制信号后,与此相对应,2816 的地址信号和 CS 、 OE 信号有效,
经一定延时,2816 可提供有效数据。
2) 写方式
2816 具有以字节为单位的擦写功能,擦除和写入是同一种操作,即都是
写,只不过擦除是固定写“1”而已。因此,在擦除时,数据输入是 TTL 高
电平。在以字节为单位进行擦除和写入时,CS 为低电平, OE 为高电平,从
VPP 端输入编程脉冲,宽度最小为 9ms,最大为 70ms,电压为 21V。为保证
存储单元能长期可靠地工作,编程脉冲要求以指数形式上升到 21V。
3) 片擦除方式
当 2816 需整片擦除时,也可按字节擦除方式将整片 2KB 逐个进行,但
最简便的方法是依照上表,将 CS 和 VPP 按片擦除方式连接,将数据输入引
脚置为 TTL 高电平,而使引脚电压达到 9~15V,则约经 10ms,整片内容全
部被擦除,即 2KB 的内容全为 FFH。
4) 备用方式
当 2816 的 CS 端加上 TTL 高电平时,芯片处于备用状态,OE 控制无效,
输出呈高阻态。在备用状态下,其功耗可降到 55%。
3. 2817A E2PROM
在工业控制领域,常用 2817A E2PROM,其容量也是 2K×8bit,采用 28
脚封装,它比 2816 多一个 RDY / BUSY 引脚,用于向 CPU 提供状态。擦写
过程是当原有内容被擦除时,将 RDY / BUSY 引脚置于低电平,然后再将新
的数据写入,完成此项操作后,再将 RDY / BUSY 引脚置于高电平,CPU 通
过检测此引脚的状态来控制芯片的擦写操作,擦写时间约 5ns。2817A 的特
点是片内具有防写保护单元。它适于现场修改参数。2817A 引脚见下图:

R/B 1 28 VCC
NC 2 27 WE
A7 3 26 NC
A6 4 25 A8
A5 5 24 A9
2817A

A4 6 23 NC
A3 7 22 OE
A2 8 21 A10
A1 9 20 CS
A0 10 19 D7
D0 11 18 D6
D1 12 17 D5
D2 13 16 D4
GND 14 15 D3

图5.20 2817A 引脚图


图中, R / B 是 RDY / BUSY 的缩写,用于指示器件的准备就绪/忙状态,
2817A 使用单一的+5V 电源,在片内有升压到+21V 的电路,用于原 VPP 引
脚的功能,可避免 VPP 偏高或加电顺序错误引起的损坏,2817A 片内有地址
锁存器、数据锁存器,因此可与 8088/8086、8031、8096 等 CPU 直接连接。
2817A 片内写周期定时器通过 RDY / BUSY 引脚向 CPU 表明它所处的工作
状态。在写一个字节的过程中,此引脚呈低电平,写完以后此引脚变为高电
平。2817A 中 RDY / BUSY 引脚的这一功能可在每写完一个字节后向 CPU
请求外部中断来继续写入下一个字节,而在写入过程中,其数据线呈高阻状
态,故 CPU 可继续执行其程序。因此采用中断方式既可在线修改内存参数
而又不致影响工业控制计算机的实时性。2817A 读取时间为 200ns,数据保
存时间接近 10 年,但每个单元允许擦写 104 次,故要均衡地使用每个单元,
以提高其寿命。2817A 的工作方式如下表所示:
表5.6 2816 的工作方式选择表
引脚
CS OE WE RDY / BUSY 数据端功能
方式
读 低 低 高 高阻 数据输出
维持 高 × × 高阻 高阻
字节写入 低 高 低 低 数据输入
字节擦除 字节写入前自动擦除
此外,2864A 是 8K×8bit 的 EEPROM,其性能更优越,每一字节擦写
时间为 5ns,2864A 只需 2ms,读取时间为 250ns,其引脚与 2764 兼容。

5.3.5 Flash 存储器

闪速存储器(Flash Memory)是一种新型的半导体存储器,由于它具有
可靠的非易失性、电擦除性以及低成本,对于需要实施代码或数据更新的嵌
入式应用是一种理想的存储器,而且它在固有性能和成本方面有较明显的优
势。
Intel 公司的 ETOXTM(EPROM 沟道氧化物)闪速存储器是以单晶体管
EPROM 单元为基础的。因此闪速存储器就具有非易失性,在断电时它也能
保留存储内容,这使它优于需要持续供电来存储信息的易失性存储器。闪速
存储器的单元结构和它具有的 EPROM 基本特性使它的制造特别经济,在密
度增加时保持可测性,并具有可靠性,这几方面综合起来的优势是目前其他
半导体存储器技术所无法比拟的。
与 EPROM 只能通过紫光线照射实施擦除的特点不同,闪速存储器可实
现大规模电擦除。闪速存储器的擦除功能可迅速清除整个器件中所有内容,
这一点优于传统的可修改字串的 E2PROM。
Intel 的 ETOX 处理制造出的器件可重复使用,可以被擦除和重新编程几
十万次而不会失效。在文件需经常更新的可重复编程应用中这显然是一种独
有的性能。
总之,闪速存储器是一种低成本、高可靠性的读写非易失性存储器。从
功能上讲,由于其随机存取的特点,闪速存储器也可看作是一种非易失的
ROM,因此它成为能够用于程序代码和数据存储的理想媒体。
闪速存储器展示出了一种全新的个人计算机存储器技术。作为一种高密
度、非易失的读写半导体技术,它特别适合作固态磁盘驱动器;或以低成本
和高可靠性替代电池支持的静态 RAM。由于便携式系统既要求低功耗、小
尺寸和耐久性,又要保持高性能和功能的完整,该技术的固有优势就十分明
显。它突破传统的存储器体系,改善了现有存储器的特性。
闪速存储器的主要特点为:
1. 固有的非易失性
它不同于静态 RAM,不需要备用电池来确保数据存留,也不需要磁盘
作为动态 RAM 的后备存储器。
2. 经济的高密度
Intel 的 1M 位闪速存储器的成本按每位计要比静态 RAM 低一半以上(不
包括静态 RAM 电池的额外花费和占用空间)。闪速存储器的成本仅比容量相
同的动态 RAM 稍高,但却节省了辅助(磁盘)存储器的额外费用和空间。
3. 可直接执行
由于省去了从磁盘到 RAM 的加载步骤,查询或等待时间仅决定于闪速
存储器,用户可充分享受程序和文件的高速存取以及系统的迅速启动。
4. 固态性能
闪速存储器是一种低功耗、高密度且没有移动部分的半导体技术。便携
式计算机不再需要消耗电池以维持磁盘驱动器运行,或由于磁盘组件而额外
增加体积和重量。用户不必再担心工作条件变坏时磁盘会发生故障。
总之,Intel 闪速存储器的出现带来了固态大容量存储器的革命。Intel
公司推出了一系列的闪速存储器作为便携式个人计算机的综合存储卡,如:
iMC001FLKA1MB 闪 速 存 储 卡 、 iMC002FLKA2MB 闪 速 存 储 卡 、
iMC004FLKA4MB 闪速存储器等。
5.4 存储器的扩展

任何存储芯片的存储容量都是有限的。要构成一定容量的内存,往往单
个芯片不能满足字长或存储单元个数的要求,甚至字长和存储单元数都不能
满足要求。这时,就需要用多个存储芯片进行组合,以满足对存储容量的需
求,这种组合就称为存储器的扩展。存储器扩展时要解决的问题主要包括位
扩展、字扩展和字位扩展。

5.4.1 存储容量的位扩展

当给定的存储器芯片每个单元的位数与系统需要的内存单元位数不相
等时,利用给定的存储器芯片构成需要的内存单元位数而采用的方法,称为
存储容量的位扩展。
实际的存储芯片,每个存储单元的位数(即字长)往往与实际内存单元
字长并不相等。存储芯片可以是 1 位、4 位或 8 位的,如 DRAM 芯片 Intel 2164
存储单元为 64K×1 位,SRAM 芯片 Intel 2114 存储单元为 1K×4 位,Intel 6264
芯片存储单元则为 8K×8 位。而计算机中内存一般是按字节来进行组织的,
若要使用 Intel 2164、Intel 2114 和 Intel 6264 这样的存储芯片来构成内存,单
个存储芯片字长就不能满足要求,这时就需要进行位扩展,以满足字长的要
求。
位扩展构成的存储器系统的每个单元中的内容被存储在不同的存储器
芯片上。例如:用两片 4K×4 位的存储器芯片经过位扩展构成 4K×8 位的
存储器,其连接方法如下图所示:
� � � � AB
A11� A0 A11� A0
4KB� � � �
R/W
� /� � � A11� A0 A11� A0
4K×4 4K×4
CS SRAM SRAM
� � � �
D 3� D 0 D 3� D 0

D 7� D 4 D 3� D 0
� � � �

图5.21 4K×4 位的芯片位扩展构成容量为 4KB 的存储器


4K×8 位的存储器中每个单元内的 8 位二进制数被分别存在两个芯片
上,即一个芯片存储该单元内容的高 4 位,另一个芯片存储该单元内容的低
4 位。可以看出,位扩展保持总的地址单元数(存储单元个数)不变,但每
个单元中的位数增加了。
由于存储器的字数与存储器芯片的字数一致,4K=212,故只需 12 根地
址线(A11~A0)对各芯片内的存储单元寻址,每个芯片只有 4 位数据,所以需
要两片这样的芯片,将它们的数据线分别接到数据总线(D7~D4)和(D3~D0)
的相应位上。在此连接方法中,每一条地址线有两个负载,每一条数据线有
一个负载。在位扩展法中,所有芯片都应同时被选中,CPU 的访存请求信号
MREQ 与各芯片 CS 片选端相连作为存储器芯片的片选输入控制信号,CPU
的读写控制信号作为存储器芯片的 R /W 读/写控制信号。位扩展存储器工作
时,各芯片同时进行相同操作。在此例中,若地址线 A11~A0 上的信号为全
0,即选中了存储器 0 号单元,则该单元的 8 位信息是由这两个芯片 0 号单
元的 4 位信息共同构成的。
可以看出,位扩展的电路连接方法是:将每个存储芯片的地址线、片选
信号线和读/写信号线全部与 CPU 的相应地址线、请求信号 MREQ 线、读/
写控制信号 R /W 线进行连接,而将它们的数据线分别连接至数据总线的不
同位线上。
例 5.1 用 Intel 2164 芯片构成容量为 64KB 的存储器。
解:因为 Intel 2164 是 64K×1 位的芯片,其存储单元数也是 64K,已满
足要求。64K=216,故只需 16 根地址线(A15~A0)对各芯片内的存储单元寻
址。Intel 2164 字长不够,每一块芯片只有 1 位数据,所以需要 8 片这样的芯
片,将它们的数据线分别与 CPU 数据总线 D7~D0 的相应位相连,将每个存
储芯片的地址线、选片信号线和读/写信号线全部与 CPU 的相应地址线、请
求信号线、读/写控制信号线进行连接,线路连接如下图所示:

� � � � AB
A15� A0 A15� A0 A15� A0 A15� A0 A15� A0 A15� A0 A15� A0 A15� A0

� /� WE
� � A15� A0 A15� A0 A15� A0 A15� A0 A15� A0 A15� A0 A15� A0 A15� A0
64K×1 64K×1 64K×1 64K×1 64K×1 64K×1 64K×1 64K×1
� � CS
I/O I/O I/O I/O I/O I/O I/O I/O
� �

D7 D6 D5 D4 D3 D2 D1 D0
� � � �

图5.22 2164 芯片位扩展构成容量为 64KB 的存储器


这样就用 8 片 Intel 2164 芯片进行位扩展构成了容量为 64KB 的存储器。

5.4.2 存储容量的字扩展

当存储芯片上每个存储单元的字长已满足要求,但存储单元的个数不
够,需要增加的是存储单元的数量,就称为存储容量的字扩展。CPU 能够访
存的地址空间是很大的,一片存储器芯片的字数往往小于 CPU 的地址空间。
这时用字扩展法可以增加存储器的字数,而每个字的位数不变。字扩展法将
地址总线分成两部分:一部分地址总线直接与各存储器地址相连,作为芯片
内部寻址;一部分地址总线经过译码器译码送到存储器的片选输入端 CS 。
CPU 的访存请求信号作为译码器的片选输出控制信号。CPU 的读/写控制信
号作为存储器的读/写控制信号,CPU 的数据线与存储器的对应数据线相连。
例 5.2 用 16K×8 位的存储器芯片组成 64K×8 位的内存储器。
解:在这里,字长已满足要求,只是容量不够,所以需要进行的是字扩
展,显然,对现有的 16K×8 位芯片存储器,需要用 4 片来实现 64K×8 位
的内存储器。
用 16K×8 位的存储器芯片组成 64K×8 位的内存储器的连线图如下图
所示:
A13 2- 3
4 2
� 1

A14 �
0

A0 CS CS CS CS
64K×8 64K×8 64K×8 64K×8


A13 (0) (1) (2) (3)


R/W R/W R/W R/W
R/W D 7� D 0
D 7� D 0 D 7� D 0 D 7� D 0
D 7� D 0 � � � �

图5.23 字扩展连接示意图
因为 16K×8 位的存储器芯片字长已满足要求,4 个芯片的数据线与数
据总线 D7~D0 并连。因为 16K=214,故只需要 14 根地址线(A13~A0)对各芯
片内的存储单元寻址,让地址总线低位地址 A13~A0 与 4 个 16K×8 位的存
储器芯片的 14 位地址线并行连接,用于进行片内寻址;对于 64K×8 位的内
存储器,因为 64K=216,故总共需 16 根地址线(A13~A0)对内存储单元寻址。
为了区分 4 个 16K×8 位的存储器芯片的地址范围,还需要两根(16-14=2)
高位地址总线 A15、A14 经过 2-4 译码器译出 4 根片选信号线,分别和 4 个 16K
×8 位的存储器芯片的片选端相连。各芯片的地址范围见下表:
表5.7 各芯片地址空间分配表
地址
A15 A14 A13A12A11…A1A0 说明
片号
00 000…00 最低地址(0000H)
0
00 111…11 最高地址(3FFFH)
01 000…00 最低地址(4000H)
1
01 111…11 最高地址(7FFFH)
10 000…00 最低地址(8000H)
2
10 111…11 最高地址(BFFFH)
11 000…00 最低地址(C000H)
3
11 111…11 最高地址(FFFFH)
可以看出,字扩展的连接方式是将各芯片的地址线、数据线、读/写控制
信号线与 CPU 的相应地址总线、数据总线、读/写控制信号线相连,而由片
选信号来区分各片地址。也就是将 CPU 低位地址总线与各芯片地址线相连,
用以选择片内的某个单元;用高位地址线经译码器产生若干不同片选信号,
连接到各芯片的片选端,以确定各芯片在整个存储空间中所属的地址范围。
例 5.3 用 64K×8 位的 SRAM 芯片构成容量为 128KB 的存储器。
解:这里现有的芯片容量为 64KB,构成容量为 128KB 的存储器需要
128KB/64KB=2 片。64K×8 位的 SRAM 储器芯片字长已满足要求,2 个 64K
×8 位芯片的数据线与 CPU 数据总线 D7~D0 并行连接;因为 64K=216,故
需 16 根地址线(A15~A0)对各芯片内的存储单元寻址,CPU 地址总线低位地
址 A15~A0 与各芯片的 16 位地址线连接,用于进行片内寻址;对于 128KB
的存储器,因为 128K=217,故总共需 17 根地址线(A16~A0)对内存储单元寻
址。为了区分 2 个 64K×8 位的存储器芯片的地址范围,还需要一根(17-16
=1)高位地址线 A16,因为片选信号低电平有效,用一根地址线不经过门电
路不能产生两个有效的低电平,所以这里用两根地址线 A17 ~A16 经过
74LS138 译码器译出 4 根片选信号线,74LS138 译码器最高位输入端 C=0,
A17~A16 分别接 74LS138 译码器输入端 B 和 A。这样 74LS138 译码器输入
端 CBA 的输入码是 000B、001B、010B 或 011B;74LS138 译码器就只能对
0、1、2 或 3 进行译码。让 74LS138 译码器的输出 Y2、Y3 分别和两个 64K
×8 位的存储器芯片的片选端相连,线路连接如下图所示:
图5.24 64K×8 位芯片构成容量为 128KB 的存储器
各芯片的地址范围见下表:
表5.8 各芯片地址空间分配表
地址
A17 A16 A15A14A13…A1A0 说明
片号
00 000…00 最低地址(00000H)
0
00 111…11 最高地址(0FFFFH)
01 000…00 最低地址(10000H)
1
01 111…11 最高地址(1FFFFH)
10 000…00 最低地址(20000H)
2
10 111…11 最高地址(2FFFFH)
11 000…00 最低地址(30000H)
3
11 111…11 最高地址(3FFFFH)
思考:图中两片芯片的地址范围分别为:20000H~2FFFFH 和 30000H~
3FFFFH。如果让 74LS138 译码器的输出 Y0、Y1 分别和两个 64K×8 位的存
储器芯片的片选端 CS 相连,图中两片芯片的地址范围分别为多少呢?

5.4.3 存储容量的字/位扩展

在构成一个实际的存储器时,往往需要同时进行位扩展和字扩展才能满
足存储容量的需求。扩展时需要的芯片数量可以这样计算:要构成一个容量
为 M×N 位的存储器,若使用 l×k 位的芯片(l<M,k<N),则构成这个存
储器需要(M/l)×(N/k)个这样的存储器芯片。
M/l 和 N/k 一定要能整除。连接时可将这些芯片分成 M/l 个组,每组内
有 N/k 个芯片,N/k 个芯片组内采用位扩展法,M/l 个组间采用字扩展法。
字/位扩展法则是上述两种扩展法的组合。
微机中内存的构成就是字/位扩展的一个很好的例子。首先,存储器芯片
生产厂制造出一个个单独的存储芯片,如 32M×1 位,64M×1 位,128M×
1 位等;然后,内存条生产厂将若干个存储器芯片利用位扩展的方法组装成
内存模块(即内存条),如用 8 片 128M×1 的芯片组成 128MB 的内存条;最
后,用户根据实际需要,购买若干个内存条插到主板上构成自己的内存系统,
即是进行了字扩展。一般来讲,最终用户做的都是字扩展(即增加内存地址单
元)的工作。
进行字/位扩展时,一般先进行位扩展,构成字长满足要求的内存条,然
后再用若干个这样的内存条进行字扩展,使总存储容量满足要求。
例 5.4 用 2114(1K×4)RAM 芯片构成 4K×8 存储器
解:根据题目要求,需要同时进行位扩展和字扩展才能满足存储容量的
需求。由于 2114 是 1K×4 的芯片,所以首先要进行位扩展。用(8/4)2 片 2114
组成 1KB 的内存模块,然后再用 4 组(4/1)这样的模块进行字扩展便构成了
4KB 的存储器。所需的芯片数为(4/1)×(8/4)=8 片。因为 2114 有 1K 个存储
单元,只需要 10 位地址信号线(A9~A0)对每组芯片进行片内寻址,同组芯片
应被同时选中,故同组芯片的片选端并联在一起。要寻址 4KB 个内存单元
至少需要 12 位地址信号线(212=4K)。而 2114 有 1K 个单元,只需要 10 位地
址信号,余下的 2 位地址用 2-4 译码器对两位高位地址(A11~A10)译码,产生
4 个片选信号线,分别与各组内的两个 2114 芯片的片选端相连,用于区分 4
个 1KB 的内存条,线路连接示意如下图所示:
图5.25 字/位扩展应用举例示意图
综上所述,存储器容量的扩展可以分为以下 3 步:
第 1 步、选择合适的芯片个数(M/l)×(N/k);
第 2 步、根据要求将 N/k 个芯片“多片并连”进行位扩展,设计出满足
字长要求的“内存条”;
第 3 步、再对“内存条”M/l 组进行字扩展,构成符合要求的存储器。
例 5-5 设有若干片 256K×8 位的 SRAM 芯片:
(1)采用位扩展方法构成 256K×32 位的存储器需要多少片 SRAM 芯片?
进行片内寻址需要多少条地址线?
(2)采用字扩展方法构成 2048K×32 位的存储器需要多少组 256K×32 位
的存储器芯片?需要多少条地址线用于片间寻址?
(3)画出该 2048K×32 位的存储器与 CPU 连接的结构图,设 CPU 的接口
信号有地址信号、数据信号、控制信号 MREQ 和 R/ W 。
解:
(1)采用位扩展法构成 256K×32 位的存储器需要 32/8=4 片 SRAM 芯片;
18
2 =256K,进行片内寻址需要 18 条地址线,用 CPU 的地址总线(A19~A2)
进行片内寻址。
(2)采用字扩展法构成 2048K×32 位的存储器需要 2048/256=8 组 256K
×32 位的存储器芯片;因为 221=2048K,所以,2048K×32 位的存储器总
共需要 21 条地址线,再减去 18 条片内寻址地址线,用 3 条 CPU 的地址总
线(A22~A20)进行片间寻址。
(3)用 MREQ 作为译码器芯片的输出许可信号,译码器的输出作为存储
器芯片的选择信号,R/ W 作为读/写控制信号,CPU 访存的地址为(A22~A2)。
该 2048K×32 位的存储器与 CPU 的连接示意图如下图所示:

图5.26 256K×8 位的芯片构成容量为 2048K×32 位的存储器

5.5 新型的存储器

5.5.1 多体交叉存储器

多体交叉存储器的设计思想是在物理上将主存分成多个模块,每一个模
块都包括一个存储体、地址缓冲寄存器和数据缓冲寄存器等,即它们都是一
个完整的存储器。因此,CPU 就能同时访问各个存储模块,任何时候都允许
对多个模块并行地进行读写操作,从而提高整个存储系统的平均访问速度。
多体交叉存储器是利用主存地址的低 n 位来选择模块(可确定 2n 个模
块),高 m 位用来指定模块中的存储单元,这样连续的几个地址就位于相邻
的几个模块中,而不是在同一个模块中,故称为“多体交叉编址”。于是 CPU
要访问主存的几个连续地址时,可使这几个模块同时工作,使整个主存的平
均利用率得到提高。

5.5.2 闪速存储器

闪速存储器的英文名称为 Flash Memory,有时也译为“快闪存储器”。


它既有 EPROM 价格便宜、集成度高的优点,又有 E2PROM 的电可擦除性、
可重写性,具有可靠的非易失性,重写速度较快,对于需要实施代码或数据
更新的嵌入性应用是一种理想的存储器。

5.5.3 高速缓冲存储器 Cache

高速缓冲存储器(Cache)位于 CPU 与存储容量较大但操作速度较慢的主


存之问,可以提高 CPU 访问存储器时的存取速度,减少处理器的等待时间,
使程序员能使用一个速度与 CPU 相当而容量与主存相当的存储器。
高速缓冲存储器(Cache)是根据程序的局部性原理,即在一个较小时间间
隔内,程序所要用到的指令或数据的地址往往集中在一个局部区域内,因而
对局部范围内的存储器地址频繁访问,而对此范围外的地址则访问甚少,这
就称为程序访问的局部性原理。
如果数据在 Cache 中,则 CPU 对 Cache 进行读写操作,称为“命中”。
若是读操作,则 CPU 可以直接从 Cache 中读取数据。若是写操作,则需改
变 Cache 和主存中相应两个单元内容。这时有两种处理办法:一种是 Cache
单元和主存中相应单元同时被修改,称为“直通存储法”;另一种方法是只
修改 Cache 单元的内容,同时用一个标志位作为标志,当有标志位的信息块
从 Cache 中移去时再修改相应的主存单元,把修改信息一次写回主存,称“写
回发”。显然直通存储法比较简单,但对于需要多次修改的单元来说,可能
导致不必要的主存复写工作。
如果数据不在 Cache 中,则 CPU 直接对主存进行操作,称为“不命中”。
若是读操作,则把主存中相应的信息块送到 Cache 中(若 Cache 中已满时,则
需根据替换算法移去某一块),在送字块到 Cache 的同时就把所需的字送给
CPU,不必等待整个块都装入 Cache,这种方法称为“盲通取数”。若是写操
作,则将信息直接写入内存。一般情况下,此时主存中的相应块并不调入缓
存,因为一个写操作所涉及的往往是程序中某个数据区的一个单元,其访问
的局部性并不明显。
替换算法在有冲突时发生,即新的主存中需要调入 Cache,而它的可用
位置已被占用时发生。替换算法主要有 4 个:
1. 随机替换算法
当需要找替换的信息块时.它是用随机数发生器产生一个随机数,它就
是被替换的块号。出于这种算法没有考虑信息块的历史情况和使用情况,故
其命中率很低,已无人使用。
2. 先进先出算法(FIFO)
这种算法是把最早进入 Cache 的信息块给替换掉。这种算法在一定程度
上能反映程序的局部性特点,比随机算法好,但由于这种方法只考虑了历史
情况,并没有反映出信息的使用情况,所以其命中率也并不高。原因很简单,
最先进来的信息块,或许就是经常要用的块。
3. 近期最少使用算法(LRU)
这种算法是把最近使用最少的信息块替换掉,这就要求随时记录 Cache
中各信息块的使用情况。为了反映每个信息块的使用情况,要为每个信息块
设置一个计数器,以便确定哪个信息块是近期最少使用的。
4. 优化替换算法
这是一种理想算法,实现起来难度较大。因此,只作为衡量其他算法的
标准,这种算法需让程序运行两次,第一次分析地址流,第二次才真正运行
程序。

5.5.4 虚拟存储器

虚拟存储器(Virtual Memory)是以存储器访问的局部性为基础,建立在主
存-辅存物理体系结构上的存储管理技术。它是为了扩大存储容量,把辅存
当作主存使用,在辅助软、硬件的控制下,将主存和辅存的地址空间统一编
址,形成个庞大的存储空间。程序运行时,用户可以访问辅存中的信息,可
以使用与访问主存同样的寻址方式,所需要的程序和数据由辅助软件和硬件
自动调入主存,这个扩大了的存储空间,就称为虚拟存储器。
程序员编程所用的地址叫做“虚拟地址”或“逻辑地址”,虚地址的全
部集合构成“虚存空问”或“逻辑空间”。实际的主存储器地址称为“真实
地址”或“物理地址”,实地址对应的空间称为“主存空间”或叫“物理空
间”。
主存-辅存层次的虚拟存储和 Cache-主存层次有很多相似之处,但虚
拟存储器和 Cache 仍有很重要的区别:
1.Cache 用于内存与 CPU 的速度差距,而虚拟存储器是用来弥补主存和
辅存之间的容量差距。
2.Cache 每次传送的信息块是定长的,只有几十字节,而虚拟存储器信
息块划分方案有很多,有分页、分段等,长度可以很大,达几百或几百 K 字
节。
3.CPU 可以直接访问 Cache,而 CPU 不能直接访问辅存。
4.Cache 存取信息的过程、地址变换和替换算法等全部由辅助硬件实现,
并对程序员是透明的,而虚拟存储器是由辅助软件(操作系统的存储管理软件)
和硬件相结合来进行信息块的划分和程序的调度。
常用的虚拟存储器有:
 页式虚拟存储器:以页为信息传送单位的虚拟存储器。在页式虚拟
存储器中,将虚拟空间和主存空间机械地分成大小固定的页。页的大小
通常随机器而异,一般为 512B 或几 KB 不等。
 虚存空间中所划分的页被称为“虚页”,而主存空间中所划分的页被
称为“实页”。虚、实地址的转换主要是虚页号向实页号的转换,这个转
换关系由页表给出,页表记录程序的虚页面调入主存时被安排在主存中
的位置。
 段式虚拟存储器:段式虚拟存储器就是以程序的逻辑结构所自然形
成的段作为主存分配的单位,来进行存储器管理的一种虚拟存储器。其
中每个段的长度可不同,可以独立编址。有的段甚至可以事先不确定大
小,而在执行时动态地决定。
 程序运行时,以段为单位整段从辅存调入主存,一段占用一个连续
的存储空间,CPU 访问时仍需段表进行虚、实地址的转换。
 段页式虚拟存储器:将存储空间仍按程序的逻辑模块分段,以保证
每个模块的独立性和便于用户公用。每段又划分为若干个页,页面大小
与实存页面相同。虚存与实存之间信息调度以页为基本单位。每个程序
有一张段表,每段对应有一张页表。CPU 访问时,由段表指出每段对应
的页表的起始地址,而每一段的页表可指出该段的虚页在实存空间的存
放位置(实页号),最后与页内地址拼接即可确定 CPU 要访问的信息的实
存地址。这是一种较好的虚拟存储器管理方式。
习 题 5
5-1 简述 DRAM 芯片上 CAS,RAS 引脚的用途。
5-2 CPU 的存储器系统由一片 2K×8 SRAM 和一片 4K×8 EPROM 组成,画出用
74LS138 译码器的存储器系统电路(CPU)的地址宽度为 16)。
5-3 简述虚拟地址与逻辑地址
第 6 章 中断
中断是为处理一些紧急发生的情况,使程序中断当前任务,将 CPU 的控制转向该
紧急事件进行处理,并在处理完后返回原程序的一种过程。因此,中断是为了解决 CPU
与外设间速度方面存在差异而引入的控制方式之一。

6.1 概述

6.1.1 中断的基本概念
1. 中断
CPU 在正常执行程序过程中,由于内部或外部事件发生,引起 CPU 中断当前正在
执行的程序,转去执行请求中断的那个事件的处理程序(称为中断服务程序),中断服
务程序执行完毕,再返回到原来程序的中断处继续执行。这一过程称为中断。中断的示
意图如图 6.1 所示。其中涉及的概念如下:

主程序

中断

断点 中断服务程序

中断返回

图 6.1 中断示意图
主程序:CPU 在中断事件未发生时执行的程序。
中断源:引起中断的事件称为中断源。中断源通常有如下几种:
(1) 一般的输入/输出设备。如键盘、打印机等。
(2) 数据通道。如磁带、磁盘等。
(3) 实时时钟。在控制中如要定时检测或控制,就要用外部时钟电路实现时间控制。
当到达规定的时间,时钟电路向 CPU 发出中断请求。
(4) 故障源。如电源掉电、存储器故障、运算溢出等。
(5) 为调试程序设置的中断源。用户调制程序时,为了检查错误或中间结果,在程
序中间设置断点、单步操作等。
中断断点:被中断中止的主程序的下一条指令的地址。
中断返回:中断服务程序完成中断事件处理后,以中断返回指令(IRET)通知 CPU 返
回到主程序的断点处继续执行。
2. 中断的作用
(1) 同步操作
在中断方式下,CPU 和外设可并行工作。当 CPU 启动外设后,就去执行主程序,
同时外设也在工作。当外设准备好时,发出中断请求,请求 CPU 中断主程序,执行输
入/输出中断服务程序。服务完后 CPU 恢复执行主程序,外设也继续工作。这样 CPU
可以同时管理多个外设,大大提高了 CPU 的利用率,也提高了输入/输出速度。
(2) 实时处理
在实时控制系统中,现场各种参数、信息提出服务请求的时间是随机的,要求 CPU
及时处理。在中断方式下,向 CPU 发出中断请求,CPU 可立即响应。
(3) 故障处理
计算机运行过程中,往往会出现一些故障。如电源掉电、运算溢出、存储出错等。,
当出现上述情况时,CPU 则可以转去执行故障处理程序,自行处理故障而不必停机。

6.1.2 中断处理过程
对于不同的微机系统,CPU 中断处理的具体过程不完全相同,但是一个完整的中
断处理基本过程应包括:中断请求、中断判优、中断响应、中断处理及中断返回五个基
本过程。中断处理过程如图 6.2 所示。
1. 中断请求
当中断源需要 CPU 为其服务时,就向 CPU 提出中断请求。外部设备通过接口向
CPU 发出中断请求,CPU 是在当前指令执行到最后一个时钟周期时,才检查有无中断
请求,因此每一个中断源设置了一个中断请求触发器,锁存中断请求信号,直到 CPU
响应后才清除。为了对中断源的中断请求有选择的开放,在每一个外设的接口电路设置
一个中断屏蔽触发器,当中断屏蔽触发器置 1,即中断请求没有被屏蔽,中断请求才能
送到 CPU。
2. 中断判优
在多个中断源情况下,由设计者事先将它们安排一个中断优先级次序,当几个中断
源同时发出中断请求时,CPU 响应当前优先级最高的中断源。中断判优的另一作用是
决定是否可能实现中断嵌套。
3. 中断响应
CPU 响应当前优先级最高的中断必须满足 3 个条件:①在当前指令周期内无总线
请求(如 DMAC 发出的总线请求)②CPU 内部的中断允许触发器置 1,中断允许标志
IF=1, CPU 开中断③CPU 执行完当前指令。
CPU 响应中断,进入中断响应周期,自动完成以下操作:①关中断。将中断允许触
发器置 0,CPU 不再响应其它中断申请。②保护断点。将标志寄存器 FLAGS、程序断
点处的 CS 和 IP 的内容依次压入堆栈③获得中断服务程序入口地址,转入执行相应的
中断处理程序。
4. 中断处理
CPU 响应中断后,就转入中断服务(处理)程序。它包括如下过程:
(1) 保护现场
CPU 响应中断时自动保护了断点地址和标志寄存器,而中断服务程序中所要使用
到的寄存器内容也要加以保护,避免其被中断服务程序修改,以便返回后主程序能正确
运行。这就是所谓的保护现场,通常的做法是用入栈指令(PUSH)把寄存器内容依次
压入堆栈。
(2) 开中断
CPU 响应中断后自动关闭中断, 不允许其他的中断打断。在执行中断服务程序时,
如果希望能响应新的更高级别请求,需执行开中断指令(STI)。
(3) 中断服务
完成中断源要求完成的任务。如输入/输出操作,参数修改等。
(4) 关中断
若曾开中断,则此时要通过指令关中断,以保证在恢复现场时不被新的中断打断。
(5) 恢复现场
在中断返回前,将保护现场时压入堆栈的寄存器内容用出栈指令(POP)弹出,送
回原寄存器,这样使原来被中断的程序能够正确地继续执行。
(6)开中断
以便返回主程序后可响应新的中断。
(7) 中断返回
中断服务程序的最后一条指令为中断返回指令(IRET)。执行返回指令,使 CPU 自
动从堆栈弹出标志寄存器和断点(FLAGS、CS、IP),即返回继续执行主程序。
中断请求 中断源提出中断申请

中断判优
判优逻辑进行优先权判断

CPU执行完当前指令
CPU取下一条指令
中断请求信号有效?
N

Y
中断响应 CPU允许中断?
N

Y
CPU关中断

保护断点地址

找出中断源,形成中断服务
入口地址,转向中断服务

保护现场

开放中断

中断处理 执行中断服务程序

CPU关中断

恢复现场

开放中断
中断返回
返回主程序断点处

图 6.2 中断处理流程图

6.1.3 中断优先级
通常,系统中会有多个中断源,而 CPU 一个时刻只能响应其中一个中断源的请求。
当同时有多个中断源提出中断请求,究竟先响应哪一个中断源呢?这就必须根据中断源
的轻重缓急,预先给各中断源安排一个中断优先级次序。当多个中断源同时提出中断请
求时,CPU 处理的一般原则是:不同级别中断发生,系统先响应优先级高的中断申请。
当 CPU 处理某一级中断时,CPU 能响应更高级别的中断,暂停低的中断服务程序,转
高的服务。当处理高级别的过程中,遇到低级别或同一级别的中断,屏蔽掉,待处理完
后再服务低级别。同一级别按预先规定次序逐个处理。
中断优先级判断的具体方法分为:软件查询方式、硬件优先权排队方式。
1. 软件查询方式
各中断源优先权由查询程序的查询先后次序决定,先查询的中断源优先级高于后查
询的。软件查询,需要附加一定的硬件接口电路,如图 6.3 所示,是将各个中断请求信
号相“或”后,作为 INTR 信号。所有外设的中断请求触发器组成一个端口,赋以一个
端口号。任一外设有中断请求,都向 CPU 送出 INTR 信号。CPU 响应中断后进入查询
程序,读取端口内容,按照程序中确定的查询顺序,逐位查询端口的每位状态,查到哪
个外设有请求中断,就转入哪个外设的中断服务程序。显然查询应安排在中断服务程序
开始。其流程如图 6.4 所示。

INT

……
7 0 端口地址 20H

……
电 磁 键 打

源 盘 盘 印

故 输 输

障 入 出

图 6.3 软件查询方式的接口电路
保护现场

Y
A 申请服务 ?

N 外设 A中断服务程序
Y
B 申请服务 ?

N 外设 B 中断服务程序
Y
C 申请服务 ?

N 外设 C 中断服务程序

恢复现场

图 6.4 软件查询程序流程图
例 6-1 有 8 个中断源,优先级从高到低的顺序为 A、B、C、D、E、F、G、H。8
个中断源的中断请求触发器组成一个端口,赋予一个端口号。
查询程序段如下:
IN AL,80H ; 读入中断请求触发器的状态
TEST AL,80H ; 查询 D7=1?
JNZ SERVE_A ; 不为 0,转 SERVE_A
TEST AL,40H ;查询 D6=1?
JNZ SERVE_B ;不为 0,转 SERVE_B
… …
TEST AL,01H ;查询 D0=1?
JNZ SERVE_H ;不为 0,转 SERVE_H
… …
软件查询方式优点是硬件电路简单,并且可以随时通过修改软件来改变优先权次
序。缺点是由查询转到相应的中断服务程序入口的时间长,尤其是中断源较多时,效率
低,实时性不高。
2. 硬件优先权排队电路
硬件优先权排队方式常用的有两种:① 简单硬件方式——菊花链法② 专用硬件方
式——可编程的中断控制器。
⑴ 简单硬件方式 ——菊花链法(或称链式优先权排队电路)。菊花链法是在每个
中断源的接口电路设置一个逻辑电路构成一个链,由它来控制中断响应信号的传递通
路。图 6.5(a)是菊花链中断优先级排队电路。图(b)是菊花链具体的逻辑电路。某一中断
源申请中断,高电平的中断请求信号 INTR 送到 CPU 的 INTR 引脚。若 CPU 允许中断,
则发出中断响应信号 INTA ,如果某一级中断源未发出中断请求, INTA 仍为 0,也就是
说 INTA 可以通过的此级逻辑电路,向后传递。如果某一级的中断源发出了中断申请,
INTA = 1 ,也就是说此级的逻辑电路阻塞 INTA 信号传递通路,使 INTA 不能向后传递,
后面的外设接口将不能接收到 INTA 信号。此级接口收到 INTA 信号后撤销中断请求信
号,向总线发送中断类型码。不同的中断源的中断类型码不同,CPU 根据中断类型码
就能转向相应的中断服务程序。后面的优先级较低的申请了中断,但未收到 INTA 信号
的接口,将保持中断请求信号,直到截获到 INTA 信号,得到响应为止。当多个接口同
时申请中断时,显然最接近 CPU 的接口最先得到中断响应信号,优先级最高。越远离
CPU 的接口,优先级越低。

设备1 设备2 设备3


CPU
以及 接口 接口 接口
总线
控制 菊花链 菊花链 菊花链
逻辑 逻辑电路 逻辑电路 逻辑电路

INTA
INTR

图 6.5(a)菊花链中断优先级排队电路

中断回答 中断请求

INTA
INTR

(b)菊花链逻辑电路
菊花链方式具有中断响应速度快,电路比较简单的优点,缺点是链条的长度(中
断源)个数受到限制,各中断源的优先级因硬件连接固定而不易修改。
(2)专用硬件方式——可编程的中断控制器。采用可编程中断控制器,是当前微
型计算机系统中完成中断优先权管理的常用办法。可编程中断控制器 8259A 就是这样
的芯片,它由中断优先级管理电路、中断请求锁存器、当前中断服务寄存器、中断屏蔽
寄存器、中断类型寄存器等几部分组成。对于 8259A 来说,各中断源的优先级,中断
源屏蔽/开放,中断触发方式都可以通过编程设定,使用非常灵活方便。

6.1.4 中断嵌套
当 CPU 正在执行某一中断服务程序时,又有优先级更高的的中断源提出中断请求,
此时 CPU 暂停当前正在执行的级别较低的中断服务程序,为优先级别高的中断源服务,
待优先级高的中断服务结束后,再返回到刚才被中断的那一级,继续为它进行中断服务,
直至处理结束返回主程序,这就称为中断嵌套或多重中断。图 6.6 为两级中断嵌套示意
图。
中断服务 中断服务
主程序
程序1 程序2

中断 中断

中断返回 中断返回
图 6.6 两级中断嵌套示意图
值得注意 的是在进入中断服务程序时,CPU 自动关闭中断。若希望能响应更高级
别的中断请求,实现中断嵌套,中断服务程序中必须有中断指令(STI)。

6.2 8086/8088 CPU 中断系统

6.2.1 中断分类
8086/8088 CPU系列微机有一个灵活的中断系统,分配给每一个中断源一个确定的
中断类型码,其长度为1个字节,故系统中最多有256个中断源。每个中断源都有对应的
中断类型码(0~255)供CPU识别。中断源可以分为硬件中断和软件中断。如图6.7所
示。80386以上处理器工作于保护方式时的中断情况与8086/8088稍有不同。
8086/8088 CPU

NMI
单步 非屏蔽中断请求


除法出错

可屏蔽中断请求

INTR 8259A
INT O 溢出 辑

INT n 指令

图 6.7 8086/8088 的中断源

1. 硬件中断
硬件中断是由外部硬件产生的,所以又称外部中断。8086/8088 有两条硬件中断信
号线,即非屏蔽中断请求端 NMI 和可屏蔽中断请求端 INTR 两种。
(1)非屏蔽中断
由 NMI 引脚引入的中断称为非屏蔽中断,它不受 CPU 内部的中断允许标志位 IF 的
影响,其中断类型号为 2。当 NMI 端出现一个上升沿时,表示非屏蔽中断请求有效。
8086/8088 要求输入脉冲宽度(有效高电平)至少保持两个时钟周期,以便锁存 。CPU
在执行完当前指令后立即响应中断请求而进入相应的处理。非屏蔽中断往往用来处理系
统紧急情况或故障,如存储器故障,系统掉电等。CPU 不需要执行中断响应周期从外
部获得中断类型号,可自动获得中断类型号为 2。
(2)可屏蔽中断
从 INTR 端引入高电平信号,可产生可屏蔽中断请求。在 INTR 端输入的请求信号
(高电平)必须保持到当前指令的结束。CPU 是否响应受标志寄存器的中断允许标志
IF 的影响。若 IF=1,CPU 开中断,响应中断请求。IF=0,CPU 关中断,不响应中断请
求。IF 可用软件指令设置,STI 指令置 1,CLI 指令置 0.。可屏蔽中断通常用于各种外
部设备,中断类型号 32~255。这些外设通常通过 8259A 可编程中断控制器与 CPU 相连。
CPU 响应时进入中断响应周期,送出两个 INTA 脉冲,8259 则送出中断类型码给 CPU。
2. 软件中断
软件中断又称为内部中断——CPU 根据某条指令或者对标志寄存器中某个标志位
的设置而产生,或由 CPU 本身启动(除法出错) ,与外部硬件无关。软件中断包括:
(1)除法出错中断——0 型中断
CPU 执行除法指令 DIV、IDIV 时,若发现除数为 0 或商超过了存放它的寄存器所
能表示的范围,则产生中断类型码为 0 的中断。
(2)单步中断——1 型中断
当 TF=1,则 80X86 处于单步工作方式。 每执行一条指令产生一个中断类型码为 1
的内部中断,显示出 CPU 内部各寄存器的内容,方便程序调试。
单步中断的过程:首先将 FLAGS 入栈,清除 TF 和 IF 标志,将断点入栈,然后
进入单步服务程序。进入后,由于 TF=0,CPU 会以单步方式执行中断服务程序,而是连
续执行服务程序,显示 CPU 内部各寄存器的内容,最后返回断点,弹出 FLAGS 内容(使
TF=1),执行下一条指令,又显示各寄存器内容,如此往复。
(3)溢出中断——4 型中断
在运算中,若溢出标志 OF 置 1,后面紧跟着溢出中断指令 INTO 时,则产生一个中
断类型码为 4 的内部中断中断,进入溢出中断服务程序,给出出错信息。若 OF=0,INTO
指令不起作用。INTO 指令总是跟在加减法运算指令后。
(4)指令中断——INT n(n 为中断类型码)
CPU 执行 INT n 指令,产生中断类型码为 n 的中断 。因为 n 可以指定为 0~255
的任何类型号,故此指令可以调用所有的中断服务子程序。
特例:INT 3——断点中断 ,为单字节指令。
在程序插 INT 3 的地方引起一个中断,好象产生一个断点,故又称断点中断。在断
点处可显示寄存器、存储器单元内容,以便调试。
软件中断具有以下的特点:
(1) CPU 不需要执行中断响应周期从外部获得中断类型号,可自动获得。
(2) 除单步中断外不受中断允许标志 IF 的影响。
(3) 除单步中断外,内部中断优先级高于硬件中断。
(4) 内部中断没有随机性,由指令在程序中的位置决定。
中断源从高到低的优先级顺序如表 6.1 所示。
表 6.1 中断优先级顺序
中断源 优先级
除法出错中断 最高
指令中断 INT n ↑
溢出中断 INTO ↑
非屏蔽中断 NMI ↑
可屏蔽中断INTR ∣
单步(陷阱)中断 最低

6.2.2 中断向量表
中断类型码是识别中断源的惟一标识。 80X86 中断系统采用的是“向量中断”方
式。CPU 响应中断获得中断类型号,根据该类型号得到该中断服务程序的入口地址,
然后转到该入口地址去执行中断服务程序。这样一个过程称为“向量中断”方式,而得
到的中断服务程序入口地址叫做中断向量。
中断向量是中断服务程序的入口地址,把系统中的全部中断向量按序存放到存储器
的某一区域内,这个存放中断向量的存储区就叫中断向量表,即中断服务程序入口地址
表。
中断向量表从 CPU 内存区的 0 段 0 单元开始存放。每个中断向量占 4 个字节,256
个中断向量占 1024 个字节,因此中断向量表存放在内存 00000H~003FFH 区域,即占
用 1K 字节的最低空间存放。低两个字节(低地址)存放中断服务程序入口地址的段内
偏移量(IP,16 位),高两个字节(高地址)存放中断服务程序入口地址的段基址(CS,
16 位)。这 4 个单元的最低地址,即中断向量存储的起始地址,称为向量地址。在中断
向量表中,中断向量是按照中断类型码 n 从小到大排列的,中断向量地址=中断类型码
n×4。则 4n 和 4n 十 1 单元中的内容为段内偏移地址 IP,4n 十 2 和 4n 十 3 单元中内容
为段基址 CS。
当 CPU 响应中断时,将中断类型号 n 乘以 4,得到中断向量存储的起始地址,把
中断向量表中 4n 和 4n+1 两个单元中的内容(段内偏移地址)装入指令指针寄存器 IP ,
把中断向量表中 4n+2,4n+3 两个单元中的内容(段基址)装入代码段寄存器 CS 中,
这样就转入中断服务程序。
003 FFH 255 号向量
用户可用 003 FCH
中断向量 ∶
( 224 个)
32 号向量
00080H
31 号向量
0007CH
系统保留
中断向量 ∶
( 27 个)
5 号向量
00014H
4 号向量 ( 溢出 )
00012H
3 号向量
0000CH
专用 2 号向量(非屏蔽)
中断向量 00008H
( 5 个) 1 号向量(单步)
00004H
CS
0 号向量(除法错)
IP
00000H
16 位
图 6.8 中断向量表
图 6.8 为 8086/8088 的中断向量表,可分为三部分: (1)类型号 0~4 系统专用中断,
已由系统定义,不允许用户做任何修改。 (2)类型号 5~31 系统保留中断,用户最好不
使用。(3)类型号 32~255 供用户使用。但是,实际上,有些中断类型目前已有用途.
例如 INT 21H 提供 DOS 系统功能调用。

6.2.3 中断向量表的建立与修改
如果用户已经编写好了一个中断服务子程序,还必须将该子程序的入口地址填写到
中断向量表的相应表项中。设该子程序对应的中断向量号为n,则应该将入口地址的填
写到内存地址为4*n,4*n+1,4*n+2,4*n+3的连续四个字节中,成为中断向量表的第n
项。
具体有四种方法:
1、直接装入法
设已知中断服务程序名称是INT_SAMPLE,段基址是2010H,偏移地址为036H;
并假设中断向量号n为1AH,则对应在中断向量表的起始地址为4*n=68H:
......
CLI ;关中断
MOV AX,,0
MOV DS,AX ;把数据段段基地址设为0
MOV AX,036H
MOV WORD PTR [68H], AX ;先写偏移量
MOV AX.2010H
MOV WORD PTR [01ACH+2] AX;再写段基址
STI ;开中断
……
2、串指令装入法
CLI ;关中断
MOV AX,0
MOV ES,AX
MOV DI, n*4
MOV AX,OFFSET INT_SAMPLE ;置中断程序首地址的偏移量到AX
CLD
STOSW ;先写偏移量
MOV AX, SEG INT_SAMPLE;置中断程序的段基地址到AX
STOSW ;再写段基址
STI ;开中断
……
3、伪指令装入法
INT_MYTBL SEGMENT AT 0 ;定义中断向量表段INT_MYTBL
;AT 0 表示INT_MYTBL段的段基地址为0
ORG n*4 ;中断向量表第n项
DD INT_SAMPLE ;将中断程序入口地址存入中断向量表第n项
INT_MYTBL ENDS
…… ;其他处理
CODE SEGMENT
……
INT_SAMPLE PROC FAR ;中断服务子程序
……
IRET
INT_SAMPLE ENDP
……
4、使用DOS功能调用的25H功能装入法
首先设置入口地址:
AL=中断向量号n
DS=中断服务程序首地址的段地址
DX=中断服务程序首地址的偏移地址
然后执行以下程序:
……
MOV AX,SEG INT_SAMPLE
MOV DS,AX
MOV DX,OFFSET INT_SAMPLE
MOV AL,n ;中断向量号n送AL
MOV AH,25H
INT 21H ;调用25H功能
……
在前面第 4 章中,我们介绍了如何调用 DOS 的中断子程序及调用 ROM BIOS 的中
断服务子程序。中断向量表中,40H~7FH 中断向量是留给用户增加中断服务程序时使用
的。为此,可以将某些通用性强的子程序功能,用中断子程序来实现。一旦设置好这样的
中断子程序,在其他应用程序中就可以调用这个中断程序。
设计中断子程序的步骤如下:
(1) 选择一个中断向量。如果是采用硬件中断,则要使用硬件决定的中断向量。如果
是采用软件中断,即用执行 INT n指令的方式来执行中断服务程序,则可以在系统预留
给用户的中断向量号中选某一个中断向量。例如,选 50H号向量。
(2) 将中断子程序的入口地址置入中断向量表的相应表项中。设选择的向量号为n,
其置入方法有两种:一是用数据传送指令将中断服务子程序入口相对地址存放在物理地
址为 4×n 的字单元中,将中断服务子程序入口段地址存放在物理地址为 4×n+2 的字
单元中。二是采用 DOS 置新中断向量的中断功能(25 功能) ,即:

向量号 21H
功能号 25H
入口参数: DS=中断服务子程序入口段地址;
DX=中断服务子程序入口相对地址;
AL=新增的向量号。

(3) 使中断服务子程序驻留内存。实现这一步骤的必要性在于:一旦中断服务子程
序驻留内存后,一般程序员使用这一新增的中断调用就如同调用 DOS 或 BIOS 的中断子
程序一样,只要了解其入口要求和返回参数就可调用。程序驻留在内存后,它占用的存
储区就不会被其他软件覆盖。使程序驻留内存,要求该程序以 COM(此种结构的程序要
求入口定位于 100H、并且数据和代码均在同一个段内)形式运行,因为 COM 程序将
定位于低地址区,DOS 常在低地址区增加驻留程序,而.EXE 将定位于高地址区。使程序
驻留内存的方法是采用 DOS 的中断调用,即:

向量号 21H
功能号 31H
入口参数: DX=驻留程序字节数;

该功能使当前程序的 DX 个字节驻留内存并返回 DOS。

例:在微机中增加一中断服务子程序,其向量号为 50H 其功能是 BX 内容增 1。


C SEGMENT
ASSUME CS:C
ORG 100H
B: MOV AX,SEG SUBP
MOV DS,AX
MOV DX,OFFSET SUBP
MOV AH,25H
MOV AL,50H
INT 21H ;建立 50H 中断向量表项
MOV DX,N
MOV AH,31H
INT 21H ;中断服务程序驻留内存并返回 DOS
SUBP PROC FAR
INC BX
IRET
SUBP ENDP
N EQU $
C ENDS
END B
设这一源程序名为 INCBX.ASM,经汇编、连接后生成 INCBX.EXE。然后可用
DEBUG 将其转换成 COM 形式的执行文件。设文件名为 INC.COM,操作步骤如下:
C :\>DEBUG INCBX.EXE 回车
-N INC.COM
-W 回车
-Q 回车
C :\>
这时可运行 INC.COM 程序,即:
C:\ >INC 回车
一旦运行 INC.COM 程序后,在微机中就新增了一个中断子程序。在其后运行的程
序中,就如同调用 DOS 或 BIOS 中断子程序一样调用 INT 50H,其功能是 BX 内容增 1。

6.2.4 中断响应过程
8086//8088 对各类中断的响应过程有所不同,主要区别在于如何获得相应的中断类
型码。
1. 内部中断响应过程
(1) 当内部中断发生时,不需要执行中断响应周期去获得中断类型码。若是 INT n
指令,从指令中获得中断类型码 n;若是除法出错、单步、断点、溢出中断,
CPU 内部自动提供中断类型码 0~4。
(2) 将类型码×4,作为中断向量地址。
(3) 清除 IF 和 TF 标志,屏蔽新的 INTR 中断和单步中断
(4) 把断点地址(CS 和 IP)与标志寄存器 FR(PSW)内容压入堆栈;
(5) 取中断向量(中断服务程序的入口地址),分别装入 CS 和 IP。装入完毕,开
始执行中断服务程序。
2. 外部中断的响应过程
(1) 非屏蔽中断 NMI 的响应
当 NMI 端有中断请求信号时,CPU 在执行完当前指令后,不需要执行中断响应周
期去获得中断类型码,CPU 内部自动提供中断类型码 2。除中断类型码获得方式外,非
屏蔽中断 NMI 的响应的其余过程与内部中断相同。
(2) 可屏蔽中断 INTR 的响应
当 INTR 端有中断请求信号且 IF=1,则 CPU 执行完当前指令执行后,响应外部中
断请求,执行 2 个连续的中断响应周期,每个响应周期有 4 个时钟周期组成,如图 6.9
所示。 在每个中断响应周期各发出一个 INTA 信号。在第一个响应周期,将地址、数据
总线置于高阻态,并发出第一个 INTA 信号,表示此中断请求已被响应。在第二个总线
周期,发出第二个 INTA 信号,请求中断的外设(通常由 8259 传送)在收到第 2 个 INTA
时,将中断类型码送上数据总线。CPU 读取总线获得中断类型码。余下响应过程与内
部中断相同。
T1 T2 T3 T4 T1 T2 T3 T4
CLK

ALE

INTA

D7-D0
类型码
图 6.9 中断响应总线周期时序
图 6.10 所示,为 8086/8088 中断响应和处理流程。

执行当前指令

N
指令执行结束吗?
Y
Y
有除法出错中断? 自动形成中断类型码0
N
Y 从指令中取出中断类型码n
有软件中断INTn?
若是断点形成中断类型码3
N
取下一 Y 自动形成中断类型码4
有溢出中断?
条指令 N
Y 自动形成中断类型码2
有非屏蔽中断?
N
Y Y 响应中断
有可屏蔽中断? IF=1?
N 读取中断类型码
N
N
有单步中断吗?
Y
自动形成中断类型码1

PSW、CS、IP依次入栈并清除IF和TF标志位

由中断类型码形成中断服务程序
的入口、并执行中断服务程序

IP、CS、PSW依次出栈

图 6.10 8086/8088 中断响应和处理流程


6.3 可编程中断控制器 8259A

8259A 是与 80X86 系列 CPU 兼容的中断控制器,8086 通过它来管理外部中断中断


源。它是可编程中断控制器(PIC),集中断源优先级排队、中断源识别,中断源屏蔽
等功能为一体,对其编程,可管理 8 级中断源,级联时共可管理到最多 64 级中断。

6.3.1 8259A 的内部结构与引脚


1. 8259A 的主要功能
(1) 单片 8259 可以管理 8 级硬件中断,用多片级联最多可构成 64 级中断优先权管
理系统。
(2) 每一级中断都可以由程序屏蔽或允许。
(3) 能判别芯片的输入端是否收到一个有效的中断请求。若未被屏蔽,判其优先级。
将当前优先级最高的中断请求送到 CPU 的 INTR 端,并提供相应的中断类型
号给 CPU。
(4) 可通过编程进行选择多种工作方式。
2. 8259A 的引脚
8259A 为 28 个引脚的双列直插式封装芯片,外部引脚如图 6.11 所示。
各引脚功能如下:
D7~ D0:双向数据线,三态,它直接或通过总线驱动器与系统的数据总线相连。

RD :读信号,输入,低电平有效。与控制总线上的 IOW 信号相连。

WR :写信号,输入,低电平有效。与控制总线上的 IOR 信号相连。 。


CS :片选信号,输入,低电平有效。通过译码电路与高位地址总线相连。
Ao:地址选择信号,输入。用来对 8259A 内部的寄存器进行选择。8259A 只有两
个端口地址,A0=0 所对应的端口称为“偶端口” A0=1 所对应的端口称为“奇端口”。
与当 8259A 与 8 位 8088CPU 相连时,其 Ao 可直接与 8088 的地址线 Ao 相连。
图 6.11 8259A 引脚图
IR7 一 IR0:外设向 8259A 发出的中断请求信号,输入,高电平或上升沿有效。中
断级联时,连接 8259A 从片 INT 端。
INT:中断请求信号,输出,高电平有效。是 8259A 向 CPU 输出的中断请求,常
与 CPU 的 INTR 引脚相连。
INTA :中断响应信号,输入,低电平有效,接收来自 CPU 的中断响应信号 INTA ,
常与 CPU 的 INTA 引脚相连。
CAS2~CAS0:级联信号,双向。8259A 级联时使用,构成主—从结构。8259A 作
主片时,CAS2~CAS0 为输出线。作从片时,CAS2~CAS0 为输入线,两者互连。当 CPU
响应中断时,主片通过 CAS2~CAS0 向所用从片送出被选中从片的编码,从片将收到编
码与自身编码相比较,若相等,则判定本片的某中断请求被选中。
SP / EN :主从片设定/允许缓冲器信号,双向双功能,低电平有效。当 8259A 工
作于缓冲方式时,作为输出信号,用作缓冲器的启动信号。当 8259A 工作于主从方式
时,作为输出信号。若 SP =1,表示该 8259 作为主片工作。若 SP =0,则该片作为从片
工作。
3. 8259A 的内部结构
8259A 的内部结构见图 6.12,它是由 8 个部分组成的,分别是:数据总线缓冲器、
读/写控制逻辑、级连缓冲/比较器、中断请求寄存器 IRR、中断屏蔽寄存器 IMR、当
前中断服务寄存器 ISR、优先权判别电路、控制逻辑。
INTA INT

数据总线
D7~D0 缓冲器 控制逻辑

RD
读/写
读/写
WR 控制
A0 控制逻辑 IR0
逻辑
CS 中断 优先权 中断 IR1
服务 判别 请求 IR2
...
寄存器 电路 寄存器 IR3
ISR IRR IR4
CAS0 级连缓冲 IR5
CAS1
比较器 IR6
CAS2
IR7

SP/EN 中断屏蔽寄存器 IMR


内部总线

图 6.12 8259A 内部结构


(1) 数据总线缓冲器
数据总线缓冲器是一个 8 位的双向三态缓冲器,是 8259A 与系统数据总线接口,
通常连接低 8 位数据总线 D0~ D7。CPU 对 8259A 写入的命令字,读取的 8259 的状态
字,中断响应周期 8259 送给 CPU 的中断类型号经过数据总线缓冲器。
(2) 读/写控制逻辑

读写控制逻辑电路接收自 CPU 的读/写命令 RD 、WR ,配合片选信号 CS 、地址选

择信号 A0(0 或 1)实现对片内某个寄存器进行读写操作。CPU 执行 OUT 指令,WR 有

效,把命令字写入 8259A 相应的内部寄存器。CPU 执行 IN 指令, RD 有效,将内部寄

存器的内容读入数据总线。
(3) 级连缓冲/比较器
级联缓冲器/比较器用来存放和比较系统中全部 8259A 的标记 IDS。这个标记是微
处理器通过数据总线送入 8259A 的。所用的 8259A 通过级联线 CAS0~CAS2 三条 I/O 外
线实现互连。其中必须有一个 8259A 为主片,其余的 8259A 为从片。主片通过
CAS0~CAS2 输出标记信息,而从片通过这三条线输入标记信息,并与自己原有的标记
进行比较,如果相同则该从片被主片选中,它就在中断响应周期把自己的中断向量送到
数据总线上。
(4) 中断请求寄存器 IRR
中断请求寄存器是一个 8 位寄存器,锁存外部输入的中断请求信号 IR7—IR0。该寄
存器每一位对应一个外部中断请求端 IRi。当某个 IR 端有中断请求时,IRR 的相应位置
“1”。可以允许 8 个中断请求信号同时进入,此时 IRR 寄存器被置成全“1”。当中断
请求被响应时,IRR 的相应位复位。
(5) 中断屏蔽寄存器 IMR
中断屏蔽寄存器是一个 8 位寄存器,可设置中断请求屏蔽或开放。该寄存器每一位
对应一个外部中断请求端 IRi。当用软件编程使 IMR 寄存器中某一位置“0”时,则此
位中断请求开放,允许 IRR 寄存器中相应位的中断请求进入中断优先级判别器。若 IMR
中某位为“1”,则此位中断请求被屏蔽。各个中断屏蔽位是独立的,屏蔽了优先级高的
中断,不影响其它较低优先级的中断允许。
(6 ) 优先权判别电路
用来识别和管理各中断请求信号的优先级别。优先权判别电路对进入允许进入中断
优先权判别电路的中断请求进行优先级识别,选出当前优先级最高的中断请求,发出中
断请求信号 INT,若 CPU 中断响应,在中断响应时,执行中断处理,并送入当前服务
寄存器,将当前服务寄存器 ISR 相应位置 1。当出现新的中断请求时,中断优先权判别
电路将所出现的中断与当前服务寄存器 ISR 中当前响应中断的优先级进行比较,若高
于,发出中断请求信号 INT,将当前服务寄存器新中断请求对应位置 1。若低于,就不
发出中断请求信号。
(7) 当前中断服务寄存器 ISR
当前服务寄存器是一个 8 位寄存器,存放正在处理中的中断请求。某级中断请求被
响应,ISR 相应位置 1。在处理某级中断的整个过程中,ISR 中与它对应的位始终保持
1。只有此中断处理完毕,相应位才复位。因此在中断嵌套的情况下,ISR 可有多位同
时置 1。
(8) 控制逻辑
控制逻辑电路中,有一组初始化命令字寄存器(ICW1~ICW4),一组操作命令字
寄存器(OCW1~OCW3) 。控制逻辑按编程设定的方式管理 8259A 的全部工作。

6.3.2 8259A 的中断响应过程


8259A 应用于 8086/8088 系统,其中断响应过程如下:
(1) 当有一个或多个中断请求线 IR7—IR0 有中断请求,则中断请求寄存器 IRR 中相
应位置 1。
(2)当 IRR 的某一位置 1,而中断屏蔽寄存器 IMR 中的对应位为 0,就将此中断请
求发送到优先权判别电路。
(3) 优先权判别电路对收到的中断请求进行优先级判别,选出当前优先级最高的中
断请求信号,发出中断请求信号 INT,请求中断。
(4)若 CPU 开中断,则 CPU 在执行完当前指令后,发出两个低电平有效的中断响
应信号 INTA 。 8259A 收到第一个 INTA 信号,把当前服务寄存器 ISR 中对应当前最高
优先权的位置 1,且 IRR 中相应位清 0。8259A 收到第二个 INTA 信号,把中断类型号 n
(初始化 8259A 时已设定好)送上数据总线。
(5) CPU 读取中断类型号,类型号×4 得到中断向量中断向量表的存放地址,取出
中断服务程序的入口地址。然后转入中断服务程序。
(6) 若 8259A 自动结束中断方式,则在第二个 INTA 结束时,ISR 中相应的位复位
为 0。否则,至中断服务程序结束,发出 EOI 命令使 ISR 中相应位复位。

6.3.3 8259 的工作方式


8259 具有非常灵活的中断管理方式,用户可根据需要,编程设定不同的工作方式。
1. 优先级的设置方式有普通全嵌套方式、特殊全嵌套方式、自动循环方式、特殊
循环方式 4 种。
⑴ 普通全嵌套方式——常用方式,为 8259A 的默认方式。若 8259A 初始化后没有
设 置 其 它 优 先 级 方 式 , 就 自 动 按 此 方 式 工 作 。 适 用 于 单 片
8259 的情况。在这种 工作方式中,优先级固定,按 IR0~IR7 顺序依次递减。
当某个中断请求被响应后,中断服务寄存器 ISR 中的对应位置“1”,中断类型号被
放到数据总线上.当响应某中断请求,并服务于该中断源时,与它同级或优先级更低的
中断源的申请被屏蔽,而优先级比它高的中断源的申请可以响应。
(2)特殊全嵌套方式——适用于 8259 级联的情况。特殊全嵌套方式与普通全嵌套
方式一样优先级固定,按 IR0~IR7 顺序依次递减。但在特殊全嵌套方式,当某中断请求
被响应后,只屏蔽低级的中断请求,而允许同级和高级的中断请求。
在级联时,从片的 INT 端接到主片的 IRi 端,虽然每个从片的 8 个中断请求输入端
IR0—IR7 有不同的优先级别,但主片是把每个从片作为一级,一个从片的 8 个中断请
求看做同一优先级。若主片是普通全嵌套方式,当从片中某一较低优先级的中断请求经
主片得到响应后,主片会把该从片的所有其他中断请求作为同一级而屏蔽掉,包括优先
级较高的中断请求。而主片编程为特殊全嵌套方式 ,当处理一级中断时,如果有同级
的中断请求,也会给予响应。这样对来自同一从片的较高优先级请求不会屏蔽。因此级
联时,主片必须采用特殊的全嵌套方式,从片才能实现全嵌套。
一个系统的优先权比较复杂,所以不能总是固定不变的。 8259A 设计了两种改变
优先权的方法。
⑴ 自动循环方式——适用于设备的优先权相等情况,当一个设备受到中断服务后,
它的优先级自动降到最低,其相邻的中断请求变成最高的。初始优先级自动规定为 IR0
优先权最高,IR7 最低。若 IR4 有中断请求,处理 IR4 后,IR4 优先权降到最低,IR5
成为最高优先级,优先级次序为:IR5 IR6 IR7 IR0 IR1 IR2 IR3 IR4 。
⑵ 特殊循环方式——循环的方式同自动循环相同,但其通过 OCW2 命令字设置初
始的最低优先级,而不像自动循环方式是自动规定的。例如确定 IR5 为最低优先级,则
优先级次序为 IR6 IR7 IR0 … IR5。
2. 结束中断处理方式
在中断请求得到响应时,8259A 将中断服务寄存器 ISR 中相应位置 1,表示正在为
此外设服务,优先权判别电路以此为判别依据。中断服务结束时,必须使这个位复位为
0 以标识中断处理结束,以便接受同级的中断。注意这个中断结束是指 8259 结束中断,
而不是 CPU 结束执行中断服务程序。
⑴ 自动中断结束方式(AEOI)——只能用于只有一片 8259A,不要求中断嵌套的情

况。在这种方式中,,系统一旦进入中断过程,第二个 INTA 结束时,8259A 自动把 ISR

的对应位清 0。如果存在嵌套,此种方式下会出现某外设还在接受服务,因为 ISR 寄存


器中没有标志,低级中断申请时,可以打断高级中断.
⑵ 非自动中断结束方式
① 普通中断结束方式(EOI) ——适用于全嵌套方式
当 8259A 工作在全嵌套方式时,由于优先级固定按 IR0~IR7 顺序依次递减,就可以
用普通的中断结束命令(EOI)将 ISR 寄存器中级别最高的置 1 位(此位对应最后一次
被响应和被处理的中断)清 0,即当前正在处理的中断结束。注意 EOI 命令应放在返回
指令 IRET 前。EOI 命令放在中断服务程序中其它位置.会引起同级或低级中断在本级
未处理完前进入。
② 特殊结束中断方式——适用于非全嵌套(如自动循环方式、特殊循环方式)
当 8259A 工作在非全嵌套模式时,8259A 无法根据 ISR 的内容确定哪一级中断是
最后响应和服务的,即无法从 ISR 置 1 的位序确定当前的最高优先级。需要在中断服
务程序结束前,用特殊的中断结束 EOI 命令,指出要清除哪个 ISR 位。
级联方式下,一般都采用非自动结束方式,中断结束必须发送两次 EOI:一次给从
片,一次给主片。方法是先向从片发一条特殊的 EOI 命令去清除 ISR 位,然后读从片
的 ISR 内容。 若为 0,表示从片只有一个中断源申请中断,可向主片发一个 EOI 命令。
若不为 0,表示从片存在两个以上的中断源在申请中断,不应发 EOI 给主片。
3. 屏蔽中断源方式 —— 通过 IMR 编程可允许或禁止中断
⑴ 普通屏蔽方式
将中断屏蔽寄存器 IMR 某位或某几位置 1,则屏蔽相应中断请求。置 0 则允许中
断。
⑵ 特殊屏蔽方式——用于开放较低级中断请求
在 8259 中,当一个中断请求被响应时,ISR 对应位置 1。在该位未复位时,8259A
会禁止所有优先级比它低的中断。 当一个中断服务程序正在执行中,如果希望开放较
低级中断请求,可采用用特殊屏蔽方式,在将中断屏蔽寄存器 IMR 某一位置 1 时,同
时将当前服务寄存器 ISR 中相应位复位。这样就屏蔽了当前正在执行的中断,而较本
级低的中断源申请也可以得到响应。
4.中断请求方式
⑴ 边沿触发:中断请求输入引脚 IRi 上出现上升沿,表示有中断请求。中断请求
输入端可一直保持高电平,不会误判为又发生一次中断。
⑵ 电平触发:中断请求输入引脚 IRi 上出现高电平有效,表示有中断请求。当输
入请求被响应后,输入端必须及时撤销高电平,以免发生第二次错误中断 。
⑶ 中断查询方式:外设通过 8259A 请求中断,但 8259A 不使用 INT 信号向 CPU
请求中断,CPU 向 8259A 主动查询有无中断请求,当查询到中断请求,就转入到相应
的中断服务程序。
5、连接系统总线的方式
⑴ 缓冲方式:在多片级连的大系统中,8259A 通过总线驱动器和数据总线相连。
必须在初始化编程时规定该片 8259A 是主片还是从片;并且 SP / EN 端输出低电平作为
总线驱动器的启动信号。
⑵ 非缓冲方式:只有单片 8259A 或片数较少时,将 8259 直接与数据总线相连;
SP / EN 端作为输入,系统中只有单片 8259A 时,该端必须接高电平;系统中有多片
8259A 时,主片该端必须接高电平,从片该端必须接低电平。

6.3.4 8259A 的编程


8259A 编程可以分为初始化编程初始化编程和工作方式编程。①初始化编程:由
CPU 向 8259A 送 2~4 个字节的初始化命令字 ICW(Initialization Command Word)② 工
作方式编程:由 CPU 向 8259A 送三个字节的操作命令字 OCW( Operation Command
Word)。
8259A 必须通过 ICW 初始化,初始化命令字必须在正常操作开始前写入,并且在
整个工作过程中保持不变。在 8259A 初始化后的任何时刻,写入操作命令字设置其工
作方式,动态地控制 CPU 处理中断的过程。
1.初始化命令字
对 8259A 编程初始化命令字共有 4 个:ICW1、ICw2、ICW3、ICW4。初始化命令
字必须顺序填写,写入顺序见流程图 6.13。但并不是任何情况下都要预置 4 个命令字,
ICW1 和 ICW2 是必须送的, ICW3 和 ICW4 由工作方式决定。8259A 有两个端口地址,
一个为偶地址,一个为奇地址。ICW1 应写入偶地址端口(A0=0),ICW2、ICW3、ICw4
应写入奇地址端口(A0=1)。

写ICW1 设置8259A是否级联
信号触发类型及是否写入
,
ICW4

写ICW2设置中断类型码

N
是级联?
Y
Y
是从片?
N

设置从片ICW3,表 设置主片ICW3,,表
明从片的INT与主 明IRx引入从片的
片的IRx连接 INT

N
要写ICW4?
Y

写ICW4设置是否为特殊完全嵌套
方式,缓冲方式,自动中断结束方式
和8086/8088CPU

初始化结束

图 6.13 8259A 写入 ICW 流程图


(1)ICW1(初始化命令字)
ICW1 启动了 8259A 中的初始化顺序,自动发生以下事件: ① 对中断请求信号边
沿检测电路复位; ② 清 IMR、ISR; ③ 指定 IR0 优先级最高; ④ 设定为普通屏蔽
方式⑤ 设定为非自动结束中断方式。ICW1 命令字格式如图 6.14 所示。
A0 D7 D6 D5 D4 D3 D2 D1 D0

0 A7 A6 A5 1 LTIM ADI SNGL IC4

偶地址端口 1 要 ICW4
80/85 中断地址 0 不要 ICW4
特征位 1 单片方式
1 电平触发 0 级联方式
0 边沿触发 1 间距为 4
0 间距为 8
图 6.14 ICW1 命令字格式

特征:A0=0,ICW1 中 D4=1
D0 位 IC4:指出初始化过程是否要写入 ICW4。D0=1,写入。D0= 0,不写入。
D3 位 LTIM:指出 8 个中断信号作用的有效触发方式。D3=1,电平触发。D3= 0,
边沿触发。
D1 位 SNGL:指出单片或多片级联方式。D1=1,单片。D1= 0,级联。
其中,D2 和 D5 ~D7 只在 8080/8085 系统中使用,8086/8088 系统中不使用。
(2)ICW2(中断类型号命令字)
ICW2 用作设置 8259A 中断类型号的初值,即 IR0 对应的中断类型号。ICW2 必须写
到 8259A 的奇地址端,即 A0=1。ICW2 命令字格式如图 6.15 所示。

A0 D7 D6 D5 D4 D3 D2 D1 D0

1 T7 T6 T5 T4 T3 0 0 0

中断类型号的高 5 位 8259A 自动填入

图 6.15 ICW2 命令字格式


其中 ICW2 的高 5 位(D7~D3)有效,作为中断类型号的高 5 位。低 3 位在初始化时不
起作用,由 8259A 根据当前中断源连接的 IR 端自动填入,与 IR0~IR7(000~111)对应。
例 :在 IBMPC/XT 系统中使用一片 8259A,T7~T3=00001,所以对应 8 个中断
的类型号为 08H~0FH。A0=l,I/O 端口地址为 2lH。写 ICW2 的程序为:
MOV AL , 08H
OUT 21H , AL
(3)ICW3(级联控制命令字)
系统中只有一片 8259A 时,不用 ICW3。系统中有多片 8259A 级联时,即仅当 ICW1
中 D1=0 才需写 ICW3 。.这时主 8259A 和每一片从 8259A 都必须使用 ICW3,而主片与
从片的 ICW3 格式不同。主/从 ICW3 命令字格式如图 6.16 所示。
ICW3 必须写到 8259A 的奇地址端,即 A0=1。
A0 D7 D6 D5 D4 D3 D2 D1 D0

1 S7 S6 S5 S4 S3 S2 S1 S0

1-IRi 输入引脚接从片的 INT


0-IRi 输入引脚未接从片的 INT

图 6.16 (a)主片 ICW3 命令字格式

A0 D7 D6 D5 D4 D3 D2 D1 D0

1 0 0 0 0 0 ID2 ID1 ID0

000 接主片 IR0


001 接主片 IR1
.…
111 接主片 IR7
(b)从片 ICW3 命令字格式
对于 8259A 主片,D7~D0 位对应于 IR7~IR0 引腿上的连接情况。如果某一引脚连
有从片,则对应位为 1,如果未连从片,则对应位为 0。例如 ICW3=82H(10000010B),
表示 IR7 和 IR1 引脚接有从片,其它 IR 引脚没有接从片。
对于 8259A 从片,D7~D3 不用(通常置为 0)D2~D0 表示从片接在主片的哪个中
断请求输入端上,例如 D2~D0=010,表示从片接在主片 8259A 的 IR2 端。
(4) ICW4(方式控制初始化命令字)
只有 ICW1 的 D0=1 时才使用 ICW4。ICW4 必须写到 8259A 的奇地址端,即 A0=1。
ICW4 命令字格式如图 6.17 所示。D7~D5 位作为 ICW4 的标志位,恒为 0。

A0 D7 D6 D5 D4 D3 D2 D1 D0
1 0 0 0 SFNM BUF M/S AEOI uPM

1-8088/8086CPU
0-8080/8085CPU
1-自动 EOI 方式
0-非自动 EOI 方式

0 × 非缓冲方式
1 0 缓冲方式从片
1 1 缓冲方式主片
1-特殊完全嵌套方式
0-一般完全嵌套方式
图 6.17 ICW4 命令字格式
D0 位 μPM 指定 CPU 类型。当 D0=0 时,表示 8259A 工作于 8080/8085 系统。当
D0=1 时,表示 8259A 工作于 8086/8088 系统
D1 位 AEOI 指定是否为中断自动结束方式。D1=1 时,中断自动结束方式。此种方
式下,在第二个 INTA 脉冲后沿,当前中断服务寄存器 ISR 中相应位自动清除。D1=0
时,非中断自动结束方式,必须在中断服务子程序中安排输出指令,向 8259A 发出 EOI
结束命令,清除相应中断服务标志位,才标志中断结束。
D3 位 BUF,D2 位 M/S 表示 8259A 是否采用缓冲方式。D3=1,采用缓冲方式,8259A
通过总线驱动器与数据总线相连。 SP / EN 中 EN 有效, EN =0 允许缓冲器输出。此时,
M/S=1,表示该片是 8259A 主片,M/S=0,表示该片是 8259A 从片。BUF=0 采
用非缓冲方式, SP / EN 中 SP 有效, SP =0,该片是 8259A 从片, SP =1 该片是 8259
主片,此时,M/S 信号无效。
D4 位 SFNM 用来决定级联方式下的嵌套方式。D4=1,工作于特殊的全嵌套方式。
D4= 0,工作于普通的全嵌套方式。
例 6-2:某 8086 系统使用一片 8259A。中断请求信号采用边沿触发方式,中断类
型码高 5 位为 18H,系统采用普通全嵌套方式,普通 EOI 方式,缓冲器方式工作。8259A
的端口地址为 3C80H 和 3C81H,对该 8259A 进行初始化
MOV AL,13H ;ICW1:边沿触发,单片,不需 ICW3,需 ICW4
OUT 3C80H,AL ;向 8259A 的偶地址端写入 ICW1
MOV AL,18H ;ICW2:中断类型号的高 5 位
OUT 3C81H,AL ;向 8259A 的奇地址端写入 ICW2
MOV AL,09H ;ICW4::缓冲器方式、非自动结束方式、普通全嵌套方式
OUT 3C81H,AL ;向 8259A 的奇地址端写入 ICW4

例 6-3:某 8086 系统由两片 8259A 级联构成中断系统,从片 INT 端接主片的 IR4


端。主片的 IR2 和 IR5 有中断请求接入,中断类型号为 41H,44H。主从片的 IR4 和 IR6
上有中断请求接入,类型号分别为 53H,55H。试分别对主片和从片进行初始化编程。
要求主片和从片均采用边沿触发方式,普通中断屏蔽,普通中断结束,非缓冲方式。主
片采用特殊全嵌套方式,从片采用特殊嵌套方式。
解: (1) 主片 8259A 初始化编程 8259A 主片端口地址为 20H 和 21H
MOV AL,11H ;写入 ICW1:级联使用,边沿触发,写 ICW4
MOV DX,20H
OUT DX,AL
MOV AL,40H ;写入 ICW2:中断类型号 40H~37H
MOV DX,21H
OUT DX,AL
MOV AL,10H ;写入 ICW3:IR4 端接从片 8259A 的 INT 端
OUT DX,AL
MOV AL,11H ;写入 ICW4,特殊全嵌套方式,非缓冲方式,普通 EOI 结束方式
OUT DX,AL
(2) 从片 8259A 初始化编程 8259A 从片端口地址为 0C20H、0C21H
MOV AL,11H ;写入 ICW1: 级联使用,边沿触发,写 ICW4
MOV DX,20H
OUT DX,AL
MOV AL,50H ;写入 ICW2: 中断类型号 50H~57H
MOV DX,21H
OUT DX,AL
MOV AL,04H ;写入 ICW3: 从片接到主片的 IR4 端
OUT DX,AL
MOV AL,11H ;写入 ICW4,特殊全嵌套方式,非缓冲方式,普通 EOI 结束方式
OUT DX,AL
2、8259 的操作命令字 OCW
在写入初始化命令字 ICW 后,8259A 在其中断输入端 IR0~IR7 就可接受中断请求
信号了。若不再写入操作命令字 OCW,8259A 处于全嵌套中断工作方式。若需改变
8259A 初始化的中断控制方式,或为了屏蔽某些中断,以及读出 8259A 的一些状态信
息,如 IRR、ISR、IMR 的内容,则必须写入操作命令字 OCW。8259A 操作命令字有
三个:OCW1~OCW3。OCW 写入顺序上无特别要求,但端口地址有严格规定即 OCW1
必须写入奇地址端口(A0=1),OCW2 和 OCW3 必须写入偶地址端口(A0=0)。0CW2 和
0CW3 通过命令字本身的 D4,D3 区分,D4D4=00 表示是 OCW2,D4D3=01 表示是 OCW3。
(1)OCW1(屏蔽操作命令字)
OCW1 用来设置 8259A 的屏蔽操作。OCW1 命令字格式如图 6.18 所示,OCW1 必
须写入奇地址端口(A0=1)。当 OCW1 中某位为 1,则对应位的中断请求被屏蔽;某位为
0,则对应位的中断请求得到允许。例如,若 OCW1=30H,则 IR4 和 IR5 的中断请求被
屏蔽。
D7 D6 D5 D4 D3 D2 D1 D0
M7 M6 M5 M4 M3 M2 M1 M0

中断屏蔽
1=置屏蔽
0=复位屏蔽
图 6.18 OCW1 命令字格式
(2)OCW2(中断结束和优先权循环控制字)
OCW2 命令字格式如图 6.19 所示。OCW2 必须写入偶地址端口(A0=0)
图 6.19 OCW2 命令字格式
D7 位 R 指定中断优先权是否循环 D7=0,优先级固定,IR0 最高,IR7 最低。D7=1,
优先级左循环,当前刚被服务的中断源轮为最低优先级。
D6 位 SL 决定 D2~D0 是否有效。D6=0,当前被服务的中断源循环到最低优先级,
D2~D0 无意义。D6=1,D2~D0 有效,指出最低优先级的中断源。
D5 位 EOI:中断结束命令。当 ICW4 中的 AEOI=0 时,即非自动结束方式,必须给
出一个 EOI 命令,清除 ISR 相应位。D5=1,表示发出 EOI 命令,使当前服务寄存器 ISR
中的相应位复位。D5=1,表示不发出 EOI 命令。当 ICW4 中的 AEOI=1 时,即自动结束
方式,D5 位 EOI 应为 0。
R,SL,EOI 三位组合可形成 8259 的几种不同的工作方式,见图 6.19。
D2~D0:当 D6 位 SL=1 时,有效。有两个用途①当 OCW2 设置为特殊优先级循环方
式时,给定循环开始时最低优先级。②当 OCW2 设置为特殊的中断结束命令(EOI)时,
指明要清除当前服务寄存器 ISR 中的哪一位。R,SL,EOI 三位组合可形成 8259 的几
种不同的工作方式。
(3)OCW3(屏蔽和读状态控制字)
操作命令字的功能有三个方面:一是设置和撤消特殊屏蔽方式;二是设置中断查询
方式;三是用来设置对内部寄存器的读出命令。OCW3 命令字格式如图 6.20 所示。OCW3
命令字必须写入 8259A 偶地址端口(A0=0)。
图 6.20 OCW3 命令字格式
D7 无效位,通常取 0.
D4D3=01:用来作为的 OCW3 标识码。
D6(ESMM)D5(SMM):设置和撤消特殊屏蔽方式。D6 为特殊屏蔽方式允许位,
允许或禁止 D5 位起作用。 D5 设置或撤销特殊屏蔽。 D6D5= 11 设置为特殊屏蔽方式 D6 D5
为= 10 撤销特殊屏蔽方式,恢复为普通屏蔽方式。
D2(P):设置中断查询方式。当 D2=1,设置为中断查询工作方式。当 D2=0,设置
为非查询工作方式,即向量中断方式。
D1(RR)D0(RIS) :设置读 8259A 内部寄存器的命令。D1 为读寄存器命令位,D0
为选择位,D1 D0= 1 0 读中断申请寄存器 IRR 的内容。D1 D0= 1 1 读中断服务寄存器 ISR
的内容。当 D1=0,D0 无意义。
例 6-4:某系统正在为 IR4 中断服务,在服务过程中希望能响应比 IR4 优先级低的
中断请求。在 IR4 中断服务完之后,不再允许响应比 IR4 优先级低的中断请求。8259A
的端口地址为 0A20H,0A21H。
解:
CLI ;关中断
MOV AL,10H
OUT 0A21H,AL ;写 OCW1,屏蔽 IR4
MOV AL.68H
OUT 0A20H,AL ;写 OCW3,设置特殊屏蔽方式
STI ; 开中断
… ;若有比 IR4 优先级低的中断请求,可响应
CLI ;关中断
MOV AL,48H
OUT 0A20H,AL ;写 OCW3,撤销特殊屏蔽
MOV AL,00H
OUT 0A21H,AL ;写 OCW1,撤销对 IR4 的屏蔽

6.3.5 8259A 应用举例


1. 8259A 在 IBM PC/XT 中的应用
8 个中断请求端 IR0~IR7。
在 IBM PC/XT 微机中使用一片 8259 实现中断管理, 除 IR2
供用户使用外,其余被系统占用。8259A 在 IBM PC/XT 系统中硬件连接如图 6.21 所示。
IRQ0 日时钟定时器
INTR INT IRQ1 键盘
IRQ2 保留
8088 8259A IRQ3 串行通信口1
____ ____
CPU IRQ4 串行通信口2
INTA INTA
IRQ5 硬磁盘
IRQ6 软磁盘
IRQ7 打印机

图 6.21 8259A 在 IBM PC/XT 系统中硬件连接


系统分配给 8259 的 I/O 端口地址为 20H、21H。中断类型码:08H~0FH。
对 8259A 进行初始化时规定为边沿触发方式、缓冲器方式、非自动结束方式、普
通全嵌套方式。系统自动对 8259A 进行初始化,用户在自己编写中断服务程序程序时,
无需再对 8259A 初始化。
1)初始化程序如下
MOV AL,13H ;写入 ICW1: 边沿触发,单片,不需 ICEW3,需 ICW4
OUT 20H,AL
MOV AL,08H ; 写入 ICW2: 中断类型号 08H~0FH
OUT 21H,ALIE
MOV AL,09H ;写入 ICW4: 缓冲器方式、非自动结束方式、普通全嵌
套方式
OUT 21H,AL
2)8259A 操作方式编程
在用户程序中,可以用 OCW1 来设置 8259A 的屏蔽操作,但注意,不要破坏原设定
工作方式。如允许日时钟 IRQ0 和键盘 IRQ1 中断,其他中断状态不变,这时可送入 OCW1
命令:
IN AL,21H ;读出 IMR
AND AL,0FCH ;只允许 IR0、IR1 中断,其余不变
OUT 21H,AL ;写入 OCW1
由于在初始化中设定的是一般 EOI 中断结束方式,所以在中断服务程序结束返回
(IRET 指令)前,必须写入 OCW2。
MOV AL,20H ;写入 OCW2
OUT 20H,AL
IRET ;中断返回
在程序中,可以设置 OCW3,读出 IRR、ISR。如果要读出 IRR 内容以查看提出中
断的信号线,这时应先写入 OCW3,再读出 IRR。
MOV AL,0AH ;写入 OCW3,读 IRR 命令
OUT 20H,AL
NOP ;延时,等待 8259A 操作结束
IN AL,20H ;读出 IRR
2. 8259A 在 IBM PC/AT 中的应用
在 IBM PC/AT 和 386、486 等系统中使用两片 8259 级联实现中断管理,从片 INT
端接主片的 IRQ2 端,所以相当于主片 IRQ2 扩展了 8 个中断请求端 IRQ8~IRQ15。8259A
在 IBM PC/AT 系统中硬件连接如图 6.22 所示。

图 6.22 8259A 在 IBM PC/AT 系统中硬件连接


主片端口地址为 20H、21H,中断类型码为 08H~0FH。从片端口地址为 A0H、
A1H,中断类型码为 70H~77H。表中列出了两片 8259 在系统中的 15 级中断。其
中主片的 8 级已被系统用尽,从片保留 4 级供用户使用。
对 8259A 进行初始化时规定为主片和从片均采用边沿触发方式,普通中断结束,
非缓冲方式。主片采用特殊全嵌套方式,从片采用特殊嵌套方式系统上电时仍是自
动初始化,程序如下
1)8259A 初始化编程
对主片 8259A 的初始化:
MOV AL,11H ;写入 ICW1:边沿触发,级联
OUT 20H,AL
MOV AL,08H ;写入 ICW2:中断类型号 08H~0FH
OUT 21H,AL
MOV AL,04H ;写入 ICW3: IRQ2 IRQ2 接从片 8259A 的 INT 端
OUT 21H,AL
MOV AL,11H ;写入 ICW4,特殊全嵌套方式,非缓冲方式,普通 EOI
;结束方式
OUT 21H,AL
从片 8259A 的初始化:
MOV AL,11H ;写入 ICW1: 边沿触发,级联 OUT 0A0H,AL
OUT 0A0H,AL
MOV AL,70H ;写入 ICW2: 中断类型号 70H~77H
OUT 0A1H,AL
MOV AL,02H ;写入 ICW3: 从片级联于主片 IRQ2 端
OUT 0A1H,AL
MOV AL,01H
OUT 0A1H,AL ; ICW4 从片普通全嵌套
2)级联工作编程
对于从片提出的中断,其服务程序返回前应发送 2 个 EOI 命令,一个给从片,另
一个给主片。
读 ISR 的内容:
MOV AL,0BH ;写入 OCW3,读 IRR 命令
OUT 0A0H,AL
NOP ;延时,等待 8259A 操作结束
IN AL,0A0H ;读出 ISR
从片发 EOI 命令:
MOV AL,20H ;写入从片 EOI 命令
OUT 0A0H,AL
主片发 EOI 命令:
MOV AL,20H ;写入主片 EOI 命令
OUT 20H,AL

6.3.6 中断程序设计
8086 系列处理器可以处理 256 个中断,对于不同类型的中断,处理过程略有不同。
但都是根据中断类型码在中断向量表中查找中断服务程序的入口地址,然后转入该入口
地址执行中断服务程序。所以在进行中断服务设计是,需要首先设置中断向量表,把需
要执行的中断服务程序的入口地址事先放到入中断向量表的相应存储单元。几种中断服
务程序的编程原则大致相同,但是由于可屏蔽中断要涉及到中断控制器的操作,所以其
编程较内部中断和非屏蔽中断复杂。
下面以可屏蔽中断为例,介绍中断程序设计的一般过程。
1.设置中断向量表
由于中断响须在中断向量表中查找中断服务程序的入口地址,所以,在进入中断处
理程序前,主程序应设置号中断向量,使其指向相应的中断服务程序。
当设置中断中断向量表时,可以将中断服务程序的入口地址直接写入中断向量表。
但此种方法只在单板微机中采用。
例如中断类型号为 60H,中断服务程序的段基址是 SEC_INTR,偏移地址是
OFFSET_INTR,则写入中断向量表的程序段为:

MOV AX,00H
MOV ES,AX
MOV BX,60H*4 ;中断类型码×4→BX
MOV AX,OFFSET_INTR ;中断服务程序偏移地址→AX
MOV ES:[BX],AX ;装入偏移地址
MOV AX,SEC_INTR ;中断服务程序段基址→AX
MOV ES:[BX+2],AX ;装入段基址

在 PC 机,可利用 DOS 系统功能调用 INT21H 的 25H 和 35H 功能调用修改向量。
要注意是为了执行完应用程序后,恢复原状态,应在设置中断向量之前,首先保存原中
断向量的内容。在程序最后,即应用程序退出前,取出原中断向量恢复到中断向量表中。
读取中断向量:
把由 AL 指定中断类型码的中断向量从中断向量表中取到 ES:BX 中。
预置 AH=35H, AL=中断类型码
执行 INT 21H
返回时送:ES:BX=中断向量
设置中断向量:
把由 AL 指定中断类型码的中断向量 DS:DX 置在中断向量表中。
预置 AH=25H, AL=中断类型码
DS:DX=中断向量
执行 INT 21H
如果借用 PC/XT 微机系统中的 IRQ3(0BH)响应外部中断,中断后需执行的子程
序的过程名为 INT.PROC,其中中断向量表的设置可以用下面的程序段实现:
保存原中断向量的内容
INTSEG DW ?
INTOFF DW ?
MOV AH , 35H
MOV AL , 0BH
INT 21H
MOV INTSEG,ES
MOV INTOFF,BX
重新修改中断向量的内容
CLI ;关中断, 设置中断向量新内容
PUSH DS
MOV AX,SEG INTPROC
MOV DS,AX
MOV DX,OFFSET INTPROC
MOV AH,25H
MOV AL,0BH
INT 21H
POP DS
2. 设置中断屏蔽寄存器
在响应可屏蔽中断前,需要对中断控制器进行设置。若利用 PC 内部的 8259A 处理
中断,由于操作系统已经对 8259A 进行过初始化及操作方式按票,所以只要对中断屏
蔽寄存器 IMR 进行相应的设置。对于通过 8259A 控制的硬件中断,必须使中断屏蔽寄
存器 IMR 的相应位置零,才能允许中断请求。同样,为了应用程序返回操作系统后恢
复原状态,应在修改 IMR 之前保存原内容,在程序退出前子以恢复。在程序中,还可
以通过控制屏蔽位,随时允许或禁止有关中断的产生。编程修改 IMR 的程序如下:
INTIMR DB ?

IN AL,21H ;读出 IMR
MOV INTIMR,AL ;保存原 IMR 内容
AND AL,0F7H ;允许 IRQ3,其它不变
OUT 21H,AL ;设置新 IMR 内容

恢复原先的 IMR:
MOV AL,INTIMR ;取出保留的 IMR 原内容
OUT 21H,AL ;重写 OCW1

3. 控制 CPU 的中断允许标志 IF
硬件中断来自外设,它随时都可能提出申请。除利用 IMR 控制某一个或某几个中
断响应外,还可以通过关中断指令 CLI 和开中断指令 STI 控制所有可屏蔽中断的产生。
当我们不需要中断和不能中断时,就必须关闭中断,以防止不可预测的后果。而在其他
时间,则应打开中断,以便及时响应中断,为外设提供服务。比如,修改中断向量表和
IMR 不能产生中断,所以在这段时间里必须管中断。在进入中断服务程序,如要允许
嵌套,则需要开中断。
4.设计中断服务程序
中断服务程序通常需完成以下任务:保护现场、中断服务、恢复现场、向 8259A
发送中断结束命令、中断返回等。
INTPROCPROC ;中断服务程序
PUSH AX ;保护现场
PUSH BX
STI ;开中断


CLI ;关中断

POP BX ;恢复现场
POP AX
MOV AL , 20H ;向 8059A 发送 EOI 命令
OUT 20H , AL
IRET ;中断返回
INTPROC ENDP
中断服务程序设计过程中还要注意以下几点① 能在主程序做的尽量不放在中断服
务程序中; ② 在外中断服务程序中不要使用 DOS 系统功能调用 INT 21H,因为 DOS
版本的内核是不可重入的; ③ 中断服务程序若要控制 I/O 设备,最好调用 ROM BIOS
功能 或者对 I/O 接口直接编程。
例 6-5 8259A 的 IRQ0 中断请求来自定时器,它每隔 55ms 产生一次中断,并提供
了完成日时钟计时功能的中断服务程序。 本程序将替换系统计时程序,使得每次中断
显示一串信息。即每隔 55ms 显示一串信息,显示 10 次后中止,程序返回 DOS。
解:程序如下:
START: MOV AX,DATA
MOV DS,AX
MOV AX,3508H ;保存原中断向量内容
INT 21H
MOV INTSEG,ES
MOV INTOFF,BX
CLI ;关中断
PUSH DS ;设置中断向量表新内容
MOV AX,SEG INTPROC
MOV DS,AX
MOV DX,OFFSET INTPROC
MOV AX,2508H
INT 21H
POP DS
IN AL,21H ;读出 IMR
MOV INTIMR,AL ;保存原 IMR 内容
AND AL,0FEH ;允许 IRQ0,其它不变
OUT 21H,AL ;设置新 IMR 内容
MOV COUNTER,0 ;设置中断次数初值
STI ;开中断
L1: CMP COUNTER,10 ;循环等待中断
JB L1 ;中断 10 次退出
CLI ;关中断
MOV AL,INTIMR ;恢复 IMR
OUT 21H,AL
MOV DX,INTOFF ;恢复中断向量内容
MOV AX,INTSEG
MOV DS,AX
MOV AX,2508H
INT 21H
STI ;开中断
MOV AX,4C00H ;返回 DOS
INT 21H ;主程序结束
习题 6
6-1 什么叫中断?什么叫中断源?
6-2 简述可屏蔽中断响应和处理过程
6-3 80X86 系统有几类中断源?各有什么特点?。
6-4 什么是中断向量?什么是中断向量表?
6-5 设中断类型号为 20H 的中断服务程序的起始地址为 0485:0061H,它在中断向量表
中如何存放?
6-6 8259A 有几种屏蔽中断源的方式?各有什么特点’
6-7 8259A 有几种中断结束方式,各有什么特点?
6-8 8259A 有几种优先权循环方式?各有什么特点?
6-9 某个 8086 系统中,使用一片 8259A,端口地址为 20H,21H。中断请求信号采用边
沿触发,中断类型号为 80H~87H,特殊全嵌套方式,普通 EOI 结束,非缓冲方式。编
写程序对该 8259A 进行初始化。
6-10 设某 8086 系统中,使用两片 8259A,主片的端口地址 20H,21H,中断类型号
50~57H,从片的端口地址 80H,81H,中断类型号 60~67H。要求主片采用边沿触发方
式,特殊全嵌套,普通 EOI 结束,非缓冲方式。从片采用边沿触发方式,特殊全嵌套,
普通 EOI 结束,非缓冲方式。试编写该中断系统的程序,并画出硬件连接图。
6-11 编写程序,屏蔽 8259A 的中断请求 IR1 和 IR6,开放其它中断请求,然后再将 IR1
和 IR6 屏蔽撤销。
第 7 章 输入输出
在整个微机系统中,主机内部的微处理器与主存储器进行信息交换,可以采用查询、
中断、DMA 方式。无论何种方式,信息的交换都需要通过接口电路才能实现 CPU 与
外设的连接。常见的输入输出设备:鼠标、键盘、扫描仪等属于输入设备,显示器、打
印机、绘图仪等则属于输出设备,软磁盘驱动器,硬磁盘驱动器等是既可用作输入又可
用作输出的设备,上述设备统称为外部设备,可简称为外设或 I/O 设备。

7.1 概述

在外设与主机通信过程中,常存在存取速度、信号等不匹配不兼容以及主从机的控
制问题,因此外设不能与主机直接相连,必须在主机与外设之间设置一种缓冲电路,也
就是所谓的接口电路,示意图如 7.1 所示。

主机 接口 外设

图 7.1 输入/输出接口

7.1.1 CPU 与外设交换的信息


由之前的章节学习我们知道,CPU 与外设之间传送的信息通过数据总线(DB)、
控制总线(CB)、地址总线(AB)进行传输,信息内容可以包括数据信息、状态信息
和控制信息三大类。
(1)数据信息是要交换的数据本身,包括数字量、模拟量、开关量三种。其中数字
量指的是以二进制形式表示的数或以 ASCII 码表示的数或字符,典型的数字量如键盘、
显示器、打印机等外设与 CPU 交换的信息;模拟量指的是非电量信息(如温度、湿度、
风力、压力、位移等)经由传感器及其信号转换电路转换成的模拟电压或电流信息。这
些非电量信息必须先经过 A/D 转换后才能被计算机识别;开关量指的是只有两个状态
的量,如开关的合与断、阀门的开与关等非 0 即 1 的信息,它只要用一位二进制数即可
表示。
(2)状态信息是用于表示外设当前工作状态的信号,通常可供查询后用于控制外设
做相应的动作。CPU 通过读取外设的状态信息,可以了解其工作状态,比如打印机的
READY 端口的信号表示打印机已经准备好打印,而 BUSY 信号表示打印机没有准备好
或者正在被占用,即正在输出数据,需要再次查询以确定下一个动作。
(3)控制信息是 CPU 发给外设的相应控制信号,比如电机的启停、指示灯的亮灭、
I/O 接口的工作方式的选择等。

7.1.2 接口的功能
如上文所述,接口电路设置正是为了解决 CPU 与外设速度匹配、信号兼容等的问
题,所以接口电路通常具有以下的功能:
(1)数据缓冲或锁存
CPU 速度通常高于大多数外设输入/输出数据的速度,为了协调二者的速度差异,
一般在接口器件会设置两个或两个以上的锁存器或缓冲器端口。输出接口电路位于
CPU 之后,当 CPU 要将数据输出到外设,就需要接口电路提供锁存器,以便数据能保
持足够长的时间,供速度较慢的外围设备使用;输入接口位于 CPU 之前,当外设要将
数据传送到 CPU,由于单线程的 CPU 无法将多个外设的数据同时传送到数据总线,就需
要接口电路提供缓冲器功能,以便 CPU 依次读入缓冲器中的数据。需要说明的是,在
多个缓冲器同时提出总线请求时,由于 CPU 不一定能及时响应,因此输入接口也需要
设置锁存器功能。
(2)信号电平转换
外设输出的信号和所需的驱动信号多与微机总线信号不兼容,因此必须进行信号的
电平转换。例如在计算机与外设串行通信中,要用到 MC1488,MC1489 等芯片完成 TTL
电平与 RS232C 电平的相互转换。
(3)信号格式转换
主机只能处理并行的二进制数据,而外设处理的数据,可能是串行数据,也可能是
并行数据,可能是二进制数据,也可能是十进制数据或 ASCII 码数据,可能是数字量,
也可能是模拟量。因此 I/O 接口必须具有实现信号格式转换的功能,如: A/D 转换功
能、D/A 转换功能、串/并转换功能、并/串转换功能、数据宽度变换功能等等。
(4)时序控制
各种外设都有自己的时序和控制逻辑,与计算机的 CPU 时序不一致。I/O 接口必须
解决两者之间的时序配合问题。接口电路可以提供联络(握手)信号给微处理器和外设,
协调主机和外设的同步工作。如:CPU 通过 I/O 接口向外设发出启/停命令,外设在准
备就绪时通过 I/O 接口送回“准备好”信息等等。
(5 地址译码与设备选择
微机系统中,往往有多个外设,一个外设一般也有几种信息与 CPU 交换,因此一
个外设通常有多个端口。但 CPU 在同一时刻只能与一个端口交换信息,这时就需要接
口中的地址译码电路对端口进行寻址,选定所需的端口,只有被选择的端口才能与 CPU
交换信息。
此外,接口电路还应具有错误检测、中断管理等功能,当然,对每一个接口电路来
说,不一定要同时具备上述功能,不同用途的接口电路自然功能不完全一样。

7.1.3 接口的基本结构
不同的外设应对不同的接口,这也使得接口的内部结构不尽相同,但不管哪种接口,
一般都具有数据输入/输出寄存器、控制寄存器、状态寄存器、定时器、地址译码及控
制逻辑等基本部件。如图 7.2 所示。

I/O接口
DB 数据信号
总线
数据缓冲寄存器
驱动
状态信号
AB
地址
I/O
CPU 状态寄存器 设
译码 备
控制信号
CB 控制
控制寄存器
逻辑

图 7.2 I/O 接口的基本结构


(1)数据缓冲寄存器。数据缓冲寄存器分为输入缓冲寄存器和输出缓冲寄存器。
输入缓冲寄存器通常由锁存器和三态缓冲器组成,用来暂存外设送入的数据并实现对数
据的缓冲;输出缓冲寄存器通常由锁存器构成,用来暂存 CPU 送给外设的数据。
(2)控制寄存器。用来存放 CPU 的各种控制命令及其它信息,以实现 CPU 对外
设的具体操作。
(3)状态寄存器。用来存放外设或接口电路本身的工作状态,用状态寄存器中的
某一位反映外设或接口的状态,常用的两个状态位是准备就绪信号 READY 和忙信号
BUSY。
(4)定时与控制逻辑电路。用来提供接口电路内部工作的时序和向外发出各种控
制信号或状态信号。
此外接口电路还设有总线驱动以增加驱动能力,以及地址译码器实现对内部寄存器
的寻址。

7.2 I/O 端口

7.2.1 I/O 端口的编址方法


CPU 与外设进行数据传输时,传送的信息包括数据信息,状态信息,控制信息。
各类信息存入不同的寄存器。通常将这些寄存器称为 I/O 端口(Port)寄存器,一个接口
可能有一个或几个端口,其中用于存放输入数据或输出数据的端口称为数据端口,用来
存放外设或接口本身当前状态的端口称为状态端口,用于存放 CPU 对外设或接口发出
的控制命令的端口称为控制端口。CPU 对外设的访问实质上是对 I/O 接口电路中相应的
端口进行访问,CPU 对外设的输入/输出操作,就是对相应的端口进行读/写操作。
系统为每个端口各自分配了一个地址,称为 I/O 端口地址,又称端口号。I/O 端口
有两种编址方式:存储器映像方式、I/O 独立编址方式。如图 7.3 所示。
内存空间 内存空间
FFFFFH
FFFFFH

I/O 空间
供 I/O 接
口使用 1M
FFFFH

00000H 00000H 0000H

(a)存储器映射方式示意图 (b)I/O 映射方式示意图

图 7.3 I/O 映射方式和存储器映射方式的示意图

.
(1)存储器映像方式
存储器映像方式是将 I/O 端口作为存储器的一个存储单元,也就是给每个 I/O 端口
分配一个存储器地址。I/O 端口与存储器共享一个寻址空间,即又称为统一编址。CPU
可以像访问存储器一样,使用访问存储器的指令去访问 I/O 端口。6800 系列与 6702
系列的 CPU 采用这种方式寻址。
优点:访问存储器的所有指令均可用来访问 I/O 端口,指令类型多,功能强,对
I/O 口的访问灵活方便;由于无需专门的 I/O 指令,指令系统得到简化;地址空间可
大可小,能根据实际系统上的外设数目来调整。
缺点:I/O 端口占用了存储器的地址,相对减少了内存的可用范围。由于访问存储
器与 I/O 端口使用相同的指令使程序可读性下降。
(2)I/O 独立编址方式
I/O 独立编址方式指存储器地址空间和 I/O 端口地址空间相互独立而分别编址。
8086/8088CPU 采用这种方式寻址。使用这种编制方式,端口要用专门的 IN 指令和 OUT
指令访问。
8086CPU 通过 M/ IO 信号区分是对存储器访问还是对 I/O 端口进行访问。当 M / IO
为高电平时,表示是对存储器进行访问。当 M/ IO 为低电平时,表示是对 I/O 端口进行
访问。8088CPU 则通过 IO / M 信号区分。8086/8088CPU 有 20 根地址线 A0~A19,但
实际只使用低 16 位地址线 A0~A15 来寻址 I/O 端口,故 I/O 端口地址最多有 216=64K
个。
优点:不占用存储器地址,主存和 I/O 端口的地址可用范围都比较大。由于 I/O
指令与访问存储器的指令明显不同,程序清晰,I/O 地址线较少,所以译码电路简单 I
/O 指令短,执行快。
缺点:I/O 指令的功能一般比较弱,在 I/O 操作中必须借助 CPU 的寄存(累加)器
进行中转。

7.2.2 I/O 端口地址分配与地址译码


8086/8088CPU,使用低 16 根地址线(A0~A15)对 I/O 端口进行寻址,形成 64K
的 I/O 端口地址范围。但在 IBM PC 系列微机系统中只使用低 10 位(A0~A9)地址线进
行寻址,形成 1KB 的 I/0 端口地址空间。其端口地址空间是从 000H 到 3FFH.。
PC 系列微机中的 I/O 接口电路大体上分为两类。
(1)系统板上的 I/O 接口芯片大多是可编程的大规模集成电路,完成相应的接口操
作。如定时器/计数器、中断控制器、并行接口等。在 PC/XT 微机中,这些芯片包括 8279A
中断控制器、8237A—7DMA 控制器、8277A—7 并行接口芯片、8273—7 计数器/定时
器等。
系统板上的 I/O 接口芯片使用前 256 个端口地址,地址范围 000H~0FF H,其地址
分配如表 7.1 所示。
I/O 接口名称 PC/XT PC/AT

DMAC1 0000~00DFH 0000.001FH


DMAC2 ─ 00C0.00DFH
DMA 页面寄存器 0080~0083H 0080.009FH

中断控制器 1 OO20~0021H 0020.003FH


中断控制器 2 ─ 00A0.00BFH

定时器 0040~0043H 0040.007FH


并行接口芯片 0060~0063H ─
键盘控制器 ─ 0060.006FH
RT/CMOS RAM ─ 0070.007FH
NMI 屏蔽寄存器 00A0H ─
协处理器 ─ 00F0.00FFH
表 7.1 系统板接口芯片的端口地址
(2)扩展槽上的 I/O 接口控制卡。这些接口控制卡是由若干个集成电路按一定的
逻辑功能组成的接口部件,如硬驱卡、图形卡、同步通信卡、网络接口卡等。
扩展槽上的 I/O 接口控制卡使用后 768 个端口地址,地址范围 100H~3FFH,其地
址分配如表 7.2 所示。
I/O 接口名称 PC/XT PC/AT
游戏控制卡 0200~020FH 0200~020FH
并行口控制卡 1 0370~037FH 0370~037FH
并行口控制卡 2 0270~027FH 0270~027FH
串行口控制卡 1 03F8~03FFH 03F8~03FFH
串行口控制卡 2 02F0~02FFH 02F0~02FFH
原型插件板(用户可用) 0300~031FH 0300~031FH
同步通信卡 1 03A0~03AFH 03A0~03AFH
同步通信卡 2 0380~038FH 0380~038FH
单显 MDA 03B0~03BFH 03B0~03BFH
彩显 CGA 03D0~03DFH 03D0~03DFH
彩显 EGA/VGA 03C0~03CFH 03C0~03CFH
硬驱控制卡 01F0~01FFH 01F0~01FFH
软驱控制卡 03F0~03F7H 03F0~03F7H
扩展器/接收器 0200~020FH ─
表 7.2 扩展槽上的 I/O 接口控制卡的端口地址
我们选用 I/O 端口地址要注意以下几点:凡是被系统配置所占用了的地址一律不能
使用。从原则上讲,未被占用的地址,用户可以选用,但对计算机厂家申明保留的地址,
不要使用,否则会发生 I/O 地址重叠和冲突,造成用户开发的产品与系统不兼容。一般
来说用户可使用 300~31FH 地址。在用户可用 的 I/O 地址范围内,为了避免与其他用
户开发的接口控制卡发生地址冲突,最好采用地址开关 DIP 进行设置。

7.2.3 I/O 端口地址译码


IBM PC 系列微机系统采用 I/O 端口独立编址方式,当 CPU 执行 IN 或 OUT 指令时,
就进入 I/O 总线周期。首先端口地址有效,然后 I/O 端口读写信号 IOR 和 IOW 有效,地
址译码电路产生有效片选信号 CS 来选中指定的端口。由于 PC 系列微机在进行 DMA
操作时也使用地址线 IOR 和 IOW 信号,为了区分要使用 AEN 信号。当 AEN 为高电平时
为 DMA 操作, AEN 为低电平时才是 CPU 的 I/O 操作。 AEN 信号可以参与地址译码,
然后由 IOR 或 IOW 控制端口读写,AEN 也可以不参与地址译码而与 IOR 或 IOW 结合起
来控制端口读写。
PC总线 并行接口8255A
数 据 线
端口A 外
RD
IOR 端口B
WR
IOW A0
A0 端口C 设
A1 片内
A1
CS 译码
A2 端口D
片 218~21FH
A3
…. 选 串行接口8251
220~227H
A8 译
A9 码 228~22FH 数/模转换0832
AEN
230~237H 模/数转换0809

图 7.4 I/O 端口地址译码原理


图 7.4 为 I/O 端口地址译码原理,I/O 端口地址译码的方法灵活多样,可由地址和
控制信号的不同组合去选择端口地址。I/O 地址不太强调连续,多采用部分译码,这样
可以节省硬件开销。—般原则是把地址分为两部分:一部分是高位地址线与 CPU 的控
制信号组合,经译码电路产生 I/O 接口芯片的片选信号 CS 实现片间寻址;另一部分是
低位地址线与控制信号,直接连到 I/O 接口芯片,经过接口芯片内部的译码电路选择片
内的某个寄存器端口,实现 I/O 接口芯片的片内寻址。有时中间部分地址线不参与译码,
有时部分最低地址线不参与译码。
PC/XT 机系统板接口地址采用固定式译码,即接口电路的 I/O 端口固定不变。译码
电路如图 7.5 所示。
由于 PC/XT 机系统板上的 I/O 端口地址分配在 000~0FFH 范围内,故只使用低 8
位地址线,这意味着 A9 和 A8 位应赋 0 值。对于系统板上有的接口芯片内部有 16 个寄
存器,从系统的角度来说,低位地址线的根数应该由含有寄存器数目最多的接口芯片决
定。故使用低 4 位地址线 A3~A0 用作接口片内寻址,以保证有 16 个端口地址可供使用,

地址线 A7~A5 作为 3.8 译码器 74LS38 的输入端。由于当 G1=1,G2 A = G 2 B =0 时,74LS38

才能译码。所以当 AEN ' ( AEN ∩ M / IO )=0,且 A8 A9 均为低电平时,译码器工作,

它根据输入信号 A7A6A5 进行译码,在 Y0 ~ Y7 中产生一个低电平输出信号,作为某个接

口芯片的片选信号。例如当 A7~A5=000 时,译码输出 Y0 有效对应 8237A(DMA 控制器)

的端口地址范围是 000~01FH,当 A7~A5=001 时,译码输出 Y1 有效对应 8259A(中断


控制器)的端口地址范围是 020~03FH 等,和前面表 7.1 所列出的端口地址分配表一致。

A5
A Y0 DMACS(8237)
A6 74LS138
B Y1 INTRCS(8259)
A7
C Y2 T/CCS(8253)
Y3 PPICS(8255)
A8 G2B WRTDMAPG
Y4
A9 G2A ≥1 (写DMA页面寄存器)
AEN G1 Y5 74LS32
WRTNMIREG
Y6 ≥1
Y7
· (写出NMI屏蔽寄存器)

IOW

图7.5 PC/XT机系统板地址译码电路

7.3 CPU 和外设之间数据传送的方式

CPU 与外设之间的数据传送实际上是 CPU 与端口之间的数据传送。外设的种


类繁多,速度相差很大,需要采用不同的数据传送方式。在微型机系统中,采用的
输入输出方式主要有程序控制方式、中断方式和直接存储器存取(DMA)方式等三种。

7.3.1 程序控制方式
程序控制传送方式是指 CPU 与外设之间的数据传送是在程序控制下完成的,即
CPU 执行程序中的 I/O 指令完成输入和输出操作。程序控制方式又可以分成无条件传送
和条件传送两种。
(1)无条件传送方式
无条件传送方式也称为同步传送方式。在这种方式中,CPU 认为外设始终是准备
就绪的.因此程序不必查询外设的状态,I/O 指令放置在程序所需要的位置,当程序执
行到 I/O 指令后,数据传送便立即进行。这是一种最简单的传送方式,适用于数据变
化缓慢或定时操作的外设,比如一组开关或 LED(发光二极管)显示管。
D0 1D 1Q

· ·
· 74LS273
·
· ·
D7 8D 8Q
CLK
M/IO
CS &
WR
图 7.6 简单输出接口
若简单外设是输出设备,一般要求接口有锁存器,也就是要求 CPU 送出的数据在
接口电路中保持一段时间,保证慢速的外设动作时数据仍保持在接口中。 图 7.6 是无
条件传送方式的输出接口。74LS273 为 8 位 D 型锁存器,输入端与 CPU 数据总线相连,
输出端驱动 LED。当程序执行到输出指令时,M/ IO 、WR 和 I/O 译码器输出的片选信
号 CS 同时变低,经过与门之后上升沿触发锁存器,此时输出指令送到数据总线上被锁
存在输出端,数据中是 1 的位对应的 LED 被点亮。

+5V

D0 1Y1 1A1

· ·
· 74LS244
·
· ·
D7 2Y4 2A4
1G 2G 开关

M/IO
CS
WR

图 7.7 简单输入接口
若简单外设是输入设备,数据所要保持的时间相对于 CPU 的处理时间长得多。因
此,输入的数据就不用加锁存器而直接用三态缓冲器同数据总线连接。图 7.7 是无条件
传送方式的输入接口。74LS244 是 8 位的三态输出缓冲器,输出端与 CPU 数据总线相

连,输入端则接入开关。当程序执行到输出指令时,M/ IO 、 RD 变低,同时 I/O 译码

器使片选信号 CS 变低,三者经过与非门之后开启缓冲器三态门,此时开关断开状态输
入高电平,开关闭合状态则输入低电平。这样开关状态以二进制的形式经数据总线传递
给 CPU。
(2) 条件传送方式(查询传送方式)
一般情况下,CPU 要执行输入操作时,外设不一定是处于就绪状态,同样执行输
出操作时,外设不一定是空闲状态。为保证数据传输的准确进行,可采用查询传送方式。
所谓查询方式指在传送数据之前,先查询外设的状态,当外设准备好时,CPU 执行 I/O
指令传送数据;若未准备好时, CPU 则继续查询外设状态。
对于需要外设状态信息的接口电路,除了有传送数据的端口外,还应有传送状态的
端口。比如,外设在输入时的数据已准备好,则接口状态对应的标志位应置位;输出时,
若数据已被取走,则接口状态对应的标志清零。
图 7.8 是查询方式的输入接口电路。由 D 触发器和一个三态门(通常是三态缓冲器
中的一路)构成状态口,一个 8 位锁存器和一个 8 位缓冲器构成数据口。输入设备将数
据准备好后,发送一个选通信号 STB,该信号一方面将数据送入数据锁存器中,另一
方面让 D 触发器 Q 端置 1,从而使三态门的 Ready 位置 1。CPU 从外设读入数据时,

首先执行读状态口命令,将状态口地址送至译码器, RD 和 M/ IO 变低,之后选通三态

门读取状态(Ready 位)是否为 1。若为 1,CPU 执行读数据命令,数据口地址送至地

址译码器, RD 和 M/ IO 再次变低,从而选通数据缓冲器读取数据,同时 RD 变低使 D

触发器清零,将状态信息“Ready”复位,以便下一个数据的输入。
& RD(读数据)

数 据 数 据
锁存器 缓冲器
输入 8位
8位 D7~D0

设备 CS2
I/O
+5V M/IO
译码
A15~A0
Ready
R CS1
D Q
STB & RD(读状态)
CP

图 7.8 查询方式下的输入接口

条件传送的流程一般如下:①CPU 从状态端口中读取状态字。②CPU 检测状态字


的对应位判断外设是否就绪,如果外设未准备好,则回到前一步重新读取状态字。③如
果状态字表明该外设已处于“就绪”状态,则通过数据端口进行数据传送。查询方式的输
入程序流程图如图 7.9 所示。

输入状态信息

N
READY?
Y
输入数据

图 7.9 查询式输入程序流程图
查询部分的程序段:
LP: IN AL, S_PORT ;从状态口 S_PORT 读入状态信息
TEST AL,80H ;READY 设在 D7,检查 READY=1?
JZ LP ;未准备好 READY=0,返回继续等待
IN AL, D_PORT ;准备好 READY=1,从数据口 D_PORT 读入数据
例 7-1:设某接口的状态端口的地址为 087H,状态位从 D7 位输入,数据端口的地
址为 086H,外设从该接口电路输入 200 个字节的数据到存储器,设存储器缓冲区
首地址为 BUFFER。试编制查询式输入数据的程序段。
解: MOV SI, BUFFER ; 取 BUFFER 的地址送 SI
MOV CX,200 ;循环次数
INPUT: IN AL, 87H ;从状态口读入状态信息
TEST AL, 80H ;READY 设在 D7,检查 READY=1?
JZ INPUT ;未准备好 READY=0,返回继续等待
IN AL, 86H ;准备好 READY=1,从数据口读入数据
MOV [SI],AL ;存到内存缓冲区
INC SI ;SI 指向下一个字节数据
LOOP INPUT ;未传送完,循环

D7-D0
数 据
WR(写数据)
&
锁存器
输出 选通信号 CS2 I/O M/IO
ACK
译码 A15~A0
R CS1
CP
设备 Q D & RD(读状态)
D触发器 BUSY
D1(数据总线)

图 7.10 查询方式下的输出接口
图 7.10 是查询方式的输出接口电路。D 触发器和一个三态门构成状态口。一个 8
位锁存器构成数据口。当 CPU 准备向外设输出数据时,首先执行读状态口命令,即状态

口地址送至地址译码器, RD 和 M/ IO 变低,从而选通三态门读取状态信息(BUSY 位)

若 BUSY=1,表示外设处于忙状态。只有在 BUSY=0 时 CPU 执行输出指令,即数据口地


址送至地址译码器, WR 和 M/ IO 变低,从而将数据总线上的数据输入数据锁存器,同
时使 D 触发器置 1,即 BUSY 位置 l。当外设从接口取走数据后,会发出一个应答信号
ACK (Acknowledge),使 D 触发器置 0,即 BUSY 位置 0。
输入状态信息

Y
BUSY ?
N
准备输出数据

取数并输出数据

图 7.11 查询式输出程序流程图
查询方式的输出程序流程图如图 7.11 所示
查询部分的程序段:
LP: IN AL, S_PORT ;从状态口 S_PORT 读入状态信息
TEST AL,01H ;状态标志设在 D0,检查 BUSY=0?
JNZ LP ;忙 BUSY=1,返回继续等待
MOV AL, DOUT ;空闲 BUSY=0,取准备传送的数据
OUT D_PORT,AL ;从数据口 D_PORT 输出数据
例 7-2: 编写一个开关键的状态通过 74LS244 接口芯片进行采集和显示的程序,如
图 7.12 所示。

图 7.12 开关控制灯的亮灭
汇编程序如下:
code segment
assume cs:code
start:mov dx,04A2H ;74LS244 芯片地址
in al,dx ;采集开关状态
mov dx,04A0H ;74LS273 芯片地址
out dx,al ;输出数据使指示灯显示
jmp start
code ends
end start

7.3.2 中断方式
在查询方式中,CPU 要不断询问外设是否准备就绪,如果外设没有准备好,就要
反复查询,这样 CPU 不能进行其他操作,时间浪费掉了。因此当多个外设工作时,需
要轮流对外设进行查询,外设速度有快有慢,并且很多外设对 CPU 要求是随机的,CPU
无法实时地处理信息。
为了提高 CPU 的工作和实时处理效率,可采用中断的传送方式。即当输入设备的
数据准备好或输出设备空闲时,向 CPU 发出中断申请,CPU 响应中断申请,中断原程
序的执行,转入执行中断操作,当 CPU 完成与外设的数据交换后,就返回继续执行原
程序。

D7-D0

中断响应信号
三态缓冲器
三态缓冲器
G 中断矢量

RD

8 位锁存器 & M/IO

输入 〉 译码器
A15- A0
设备
STB
〉 R 中断请求
Q
D
+5V
INT
&
中断屏蔽
触发器

图7.13 中断方式传送的输入接口
中断方式传送的输入接口如图 7.13。当输入设备将数据准备好后,向接口发送一
个选通信号 STB,此信号一方面将输入数据锁存到锁存器中,另一方面使 D 触发器(中
断请求触发器)Q 端置“1”。若此时中断屏蔽触发器置为“1”,则由电路产生一个向
CPU 请求中断的信号 INT,中断屏蔽触发器是 1 还是 0 决定了是否允许该接口向 CPU
发出中断请求。CPU 接到中断请求后,如果 CPU 内部的中断允许触发器的状态为 1,
则在当前指令执行完后,暂停正在执行的程序,发出中断响应信号 INTA ,同时将中断
请求触发器复位,准备接收下一次中断信号。将一个中断矢量放到数据总线上,CPU
就转入中断服务程序,完成读取或输出数据。中断服务程序执行完毕,CPU 返回原程
序继续执行。

7.3.3 直接存储器访问(DMA)方式
利用中断进行传送,可大大节约 CPU 时间,但中断传送仍然由 CPU 通过程序来传
送,每次要保护断点,现场信息,都需要花多条指令的时间。对于高速的 I/O 设备,比
如磁盘与内存之间交换数据,就显得速度太慢了。因此希望用硬件在外设与内存之间直
接进行数据交换,而不通过 CPU,这就是 DMA 方式,这个硬件就是 DMAC(DMA 控
制器)。DMA( Direct Memory Access)。DMA 传送的基本原理如图 7.14 所示。

图 7.14 DMA 传送的基本原理图


习题 7
7-1 什么是接口?微型计算机的接口一般具有哪些功能?
7-2 I/O 端口的寻址方式有几种?各有什么特点?
7-3 CPU 和外设之间数据传送的方式有几种?各有什么特点?
7-4 试设计一个查询输出接口,画出电路图并写出相应的输出程序。
7-5 简述 DMA 传送的一般过程。
第 8 章 常用接口芯片
计算机要与外部设备信息交换,就需要通过接口器件来完成,我们日常生活中使用
的接口芯片有:可编程串行接口芯片 8250,可编程定时器/计数器芯片 8253,可编程并行
接口芯片(8255,8259A)
,A/D 与 D/A 转换器接口等。

8.1 8253 可编程定时器/计数器

目前可编程定时/计数器的芯片型号有多种,不同定时/计数器(也叫做 T/C)芯片
的主要差异体现在工作的频率上,如 8253-5(5MHz),8254-2(10MHz),另外还有 8253
(2MHz),8254(8MHz)等。本节就以 8253 为例来解读一下可编程定时/计数器的特
性,掌握了 8253 将便于读者对其它型号的定时/计数器理解和快速的掌握。

8.1.1 8253 的基本功能及内部结构


1.8253 的特点及功能
定时/计数器 8253-5/8254-2 的特点:
1)具有三个独立的功能完全相同的 16
位减法计数器,分别称作计数器 0,计数器 1,计数器 2。
2)24 脚 DIP 封装,由单一的+5 V 电 源供电。如图 8.1 所示:

图 8.1 8253 引脚示意图


3)可以通过编程选择计数器和设置工作方式。
定时/计数器 8253-5/8254-2 功能如下:
1) 它们可以向 I/O 设备输出周期可控的精确的定时信号。
2) 用作可编程波特率发生器。
3) 是以均匀分布的时间间隔中断分时操作系统,以便切换程序。
4) 检测外部事件发生的频率或者周期。

5) 统计外部某过程(比如生产,实验武器发射等过程)中某一事件发生的次数,并
将计数结果返回 CPU 中。

6) 在定时或计数达到编程规定的值后,向 CPU 申请中断。


7) 六种工作方式,即可对系统时钟脉冲计数实现定时,又可以对外部事件进行计
数。
2.8253 的外部引脚
8253 的外部引脚如图 8.1所示,外部引脚由面向 CPU 的信号线:
(1) D0~D7:三态双向数据线,和 CPU 数据总线相连。
(2) :是片选信号,当其有效(低电平)时选中该 8253 实现对其读写操作,通
常由端口地址的高位地址译码形成。
(3) A0.A1 为地址译码线,其中 A1,A0 为 8253 内部计数器和控制寄存器的编码选
择信号,其功能如下:
A1 A0 功能
0 0 可以选择计数器 0
0 1 可以选择计数器 1
1 0 可以选择计数器 2
1 1 可以选择控制寄存器
(4) :读信号,输入信号,为读控
制命令, 为写控制命令,由 CPU 输入,
都是低电平有效。 有效时,CPU 读取
由 A1,A0 所选定的通道内计数器的内容。
WR 有效时,CPU 将计数值写入各个通道
图 8.2 8253 的内部结构
的计数器中,或者是将方式控制字写入控
制字寄存器中。
(5)CLK:计数器时钟信号,用于输入定时基准脉冲或计数脉冲;每输入一个时钟脉
冲信号 CLK,便使计数值减 1。当 CLK 是一个周期性时钟信号时,计数器为定时器功
能;当 CLK 是一个非周期性事件计数信号时,此时呈计数器功能。
(6)GATE:计数器门控选通信号用来禁止、允许或开始计数过程的,以使计数
器和计测对象同步。它有多种控制作用,如允许/禁止计数、启动/停止计数等。控制
寄存器是用来控制计数器/定时器的工作方式,就是控制 CLK 脉冲和 CATE 门控信号
适当配合来产生 OUT 端的输出信号的形状。
控制输入端的作用归纳为以下几种
1)门脉冲控制时钟输入。此时,当门脉冲 GATE 到来时,时钟 CLK 有效,进行
计数操作;当门脉冲结束时,时钟无效,计数停止。
2)用门脉冲重新启动计数器。
3)用门脉冲停止计数器工作。
4)单次计数。此时仅要求 GATE 为高电平即可。
5)循环计数。此时,每当计数执行单元为零时,输出端 OUT 输出一个信号,同
时又重新装入计数初值寄存器内容到计数执行单元,重复原来的计数过程,从而在 OUT
端上可输出周期性的脉冲信号。
(7)OUT:计数器输出信号,每来一个时钟脉冲,计数器减 1,当计数值减为 0 时,
以相应的电平指示计数的完成,或输出脉冲波形。
3.8253 的内部结构
8253 内部有 6 个功能块如图 8.2 所示,它们是:数据总线缓冲器,读/写逻辑,控
制字寄存器和 3 个独立的功能相同的计数器(0 计数器、1 计数器 、2 计数器)。
(1)数据总线缓冲器
数据总线缓冲器 8253-5/8254-2 与 CPU 之间的数据接口,由一个三态门、双向 8 位
寄存器构成,用于将 8253 与系统数据总线 D0~D7 相连,是 CPU 与 8253 之间交换信息
的必经之路。
数据总线缓冲器有三个基本功能:
1)向 8253 写入确定 8253 工作方式控制字;
2)向 8253 计数寄存器装入计数值;
3)读出计数值的初始值或当前值。
(2)读/写控制逻辑
读/写控制逻辑电路接收输入到 8253 的读/写、片选和地址译码信号,完成对芯片
内部各功能部件的控制,并经过逻辑控制电路的组合产生相应的操作。
表 8-1 8253 读/写操作逻辑表
A1 A0 寄存器选择和操作

0 1 0 0 0 写入计数器 0
0 1 0 0 1 写入计数器 1
0 1 0 1 0 写入计数器 2
0 1 0 1 1 写入控制字寄存器
0 0 1 0 0 读计数器 0
0 0 1 0 1 读计数器 1
0 0 1 1 0 读计数器 2
0 0 1 1 1 无操作
1 × × × × 禁止使用
0 1 1 × × 无操作

(3)控制字寄存器
接收 CPU 发来的对 8253 的控制字,来决定通道的工作方式、计数方式以及使用
哪个计数器等;当地址信号 A1 和 A0 都为 1 时,访问控制字寄存器。控制字寄存器只能
写入不能读出。其使用格式如图 8.3 所示。

图 8.3 8253 控制字格式


8253 控制字各位的详细意义如下:
1) SC1、SC0 用于选择工作的计数器。
SC1SC0=00:选择计数器 0 工作。
SC1SC0=01:选择计数器 1 工作。
SC1SC0=10:选择计数器 2 工作。
SC1SC0=11:无效。
2) RW1、RW0 用于选择读写格式。
RW1RW0=00:计数器锁存命令,把写本命令时的当前计数值锁存到输出锁存器
OL 中,以供 CPU 读取。
RW1RW0=01:8 位计数,只读/写计数器低位字节,高位字节自动为 0。
RW1RW0 =10:16 位计数,只读/写计数器高位字节,低位字节自动为 0。
RW1RW0 =11:16 位计数,先读/写计数器低位字节,后读/写计数器高位字节。
3) M2、M1、M0 用于选择工作方式。
M2M1M0=000:使计数器工作于方式 0。
M2M1M0 =001:使计数器工作于方式 1。
M2M1M0 =010:使计数器工作于方式 2。
M2M1M0 =011:使计数器工作于方式 3。
M2M1M0 =100:使计数器工作于方式 4。
M2M1M0 =101:使计数器工作于方式 5。
4) BCD 计数方式选择。
BCD 位用于使计数器按二进制计数或十进制(BCD 码)计数。当 BCD 位=0 时,则
计数器按二进制计数,其计数范围是 16 位二进制数,最大计数值为 216=65536(对应计
数初值为 0000H);当 BCD 位=1 时,则计数器按十进制(BCD 码)计数,其计数范围是
四位十进制数,最大计数值为 104=10000,对应计数初值为 0000。
(4)计数器
8253-5/8254-2 内部包含 3 个功能完全相同的计数器,其内部结构图如图 8.4 所示,
分别称作计数器 0、计数器 1 和计数器 2。每个计数器包含一个 8 位的控制寄存器(控制
单元),它存放计数器的工作方式控制字。每个计数器内部都是 16 位初始值寄存器:8253
工作之前要对它设置初值;一个 16 位计数执行单元 CE,它接收计数初值寄存器 CR 送
来的内容,并对该内容执行减 1 操作;一个 16 位输出锁存器 OL,它锁存 CE 的内容,
使 CPU 能从输出锁存器内读出一个稳定的计数值。
图 8.4 计数器内部结构
4.8253的计数初值
任何一种工作方式,只有在写入计数初值后才能开始计数。门控信号GATE保持为
高电平,方式0、方式2、方式3和方式4在写入计数初值后,计数过程就开始了;而方式
1和方式5需要有外部GATE触发,才能开始计数。
计数初值与输入时钟(CLK)频率及输出波形(OUT)频率之间的关系:
Ci=CLK/OUT
Tc=CLK/OUT
例:CLK=200KHz, 要求产生10ms的时钟则
输出频率fOUT= 1/ (10X10-3)
计数初值=(200X103 ) / fOUT =2000

8.1.2 8253 的工作方式


8253 的工作方式有 6 种,不论哪种工作方式,都遵守如下 4 条基本原则:
(1) 当控制字写入计数器时,全部的控制逻辑电路立即复位,输出端 OUT 进入初
始状态。该初始状态与工作方式有关,设置成方式 0 时,OUT 的初始状态为低电平,
设置成其他工作方式,OUT 的初始状态为高电平。
(2)在初始值写入初值计数器 CR 以后,要经过一个时钟脉 冲的上升沿和下降沿,
将初值送入计数执行单元,计数执行单元从下一个时钟开始进行计数。
(3) 通常,在时钟脉冲 CLK 的上升沿对门控信号 GATE 进 行采样,各计数器的
门控信号的触发方式与工作方式有关。在方式 0、方式 4 中,门控信号为电平触发;方
式 1、方式 5 中,门控信号为上升沿触发;方式 2、方式 3 中,即可用电平触发,也可
用上升沿触发。
(4) 在时钟脉冲的下降沿计数器进行计数。0 是计数器所能容纳的最大初值,因为
用二进制计数时,16 位计数器,0 相当于 216=65536,用 BCD 码计数时,0 相当于
104=10000。
8253 中的三个计数器都可独立工作,每个计数器都有六种工作方式。工作方式由
控制字设定,六种工作方式输出的不同波形都从 OUT 端获得。门控信号 GATE 对计数
过程有影响。下面分别介绍这六种工作方式。
1.方式 0:计数结束时中断方式
(1) 计数过程由图(a)可看出,首先 CPU 将控制字 CW 写入控制寄存器后,在
下一个时钟 CLK 上升沿,并在写控制信号的上升沿,OUT 输出端变为低电平(若原来
为低电平 ,则继续维持低电平,图(a)中①虚线所示),并且计数过程中一直维持低
电平;然后,计数初值(设 N=4)写入初值寄存器 CR 后,并在上升沿之后的第一个 CLK
脉冲(图(a)中②虚线所示)的下降沿,将 CR 的值送入计数执行 单元 CE 中。
要开始计数,GATE 门控信号必须是高电平,随后每个时钟 CLK 的下降沿都使计
数执行单元的内容减 1,减到 0 时,输出端 OUT 变成高电平,并一直维持高电平,直
到写入新的计数值,开始下一轮的计数。计数初值一次有效,经过一次计数过程后,必
须重新写入计数初值。当输出端 OUT 变成高电平时,可利用 OUT 的上升沿作为中断
请求信号。方式 0 主要用于对外部事件计数。图 8.5 为方式 0 计数过程时序图

图 8.5 方式 0 计数过程时序图
(2) GATE 门控信号的影响在计数过程中,可由 GATE 信号控制暂停计数。
当 GATE
=0 时,计数暂停,保持当前值,直到 GATE 信号恢复到高电平,经过一个时钟周期,
计数执行单元从当前值开始继续执行减 1 操作。GATE 只影响计数执行单元是否暂停减
1 操作,对输出信号 OUT 无影响,OUT 信号从计数开始变为低电平,一直保持到计数
结束,才变 为高电平, 计数过程时序图如图(b)所示。如果在门控信号 GATE 处于低
电平时写入新计数初值 ,则在下一个时钟周期也将初值从初值寄存器 CR 写入计数执
行单元 CE,但不进行计数操作,当 GATE 变为高 电平时才开始计数。利用 GATE 信
号可作为启动定时的同步信号。
(3) 写入新的初值对计数过程的影响在计数过程中也可以改变计数值,在写入新
的计数初值后,计数器将立即按新的计数值重新开始计数,即改变计数值是立即有效的。
当按新的计数值减 1 计数到 0 时,输出 OUT 变成高电平。计数过程时序图如图(c)所
示。从计数开始,输出 OUT 变为低电平,一直保持到计数结束,并不因写了新的初值,
影响输出信号。
注意:8253 写计数值是由 CPU 的 WR 信号控制的,在 WR 信号的上升沿,计数
值被送入对应计数器的计数值寄存器,在 WR 信号上升沿之后的下一个 CLK 脉冲才开
始计数。
2.方式 1:可编程单稳态触发器
方式 1 的工作波形如图 8.6 所示。
方式 1 是在 GATE 门控信号的作用下才开始计数,计数过程时序如图 8.6 所示,下
面对工作原理进行分析。
(1) 计数过程
当 CPU 把方式 1 的控制字写入控制寄存器后(的上升沿),OUT 输出变成高电平(若
原来为高电平,则继续维持高电平)
;在 CPU 写入计数初值后,此时计数执行单元 CE
并不计数,直到 GATE 门控信号上升沿到来,在下一个时钟周期的下降沿才开始计数,
输出 OUT 变为低电平。计数过程中 OUT 端一直维持低电平。当计数 减到 0 时,输出
端 OUT 变为高电平,并一直维持高电平 到下一次触发之前。计数初值的设置也是一
次有效, 每输入一次计数值,只产生一次计数触发过程。
(2) GATE 门控信号的影响
方式 1 中,门控信号的影响从两个方面讨论。一方面是计数结束后,若再来一个门
控信号上升沿,则在下一个时钟周期的下降沿又从初值开始计数,而且不需要重新写入
计数初值,即门控脉冲可重新触发计数,同时 OUT 端输出从高电平降为低电平,直到
计数结束 ,再恢复到高电平。可以看出,调整门控信号的触发时刻,可调整 OUT 端
输出的高电平持续时间,即输出单次脉冲的宽度由计数初值 N 决定,另一方面是在计
数进行中,若来一个门控信号的上升沿,也要在下一个时钟下降沿终止原来的计数过程,
从初值起重新计数。在这个过程中,OUT 输出保持低电平不变,直到计数执行单元内
容减为 0 时,OUT 输出才恢复为高电平。这样,使 OUT 输出低电平持续时间加长,即
输出单次脉冲的宽度加宽。
(3) 新的初值对计数过程的影响在计数过程中如果写入新的初值,不会影响计数
过程,只有在下一个门控信号到来后的第一个时钟下降沿,才终止原来的计数过程,而
按新值开始计数。OUT 输出的变化是高电平持续到开始计数前,低电平持续到计数过
程结束。

图 8.6 方式 1 波形图

3.方式 2:频率发生器
方式 2 的工作波形如图 8.7 所示。
在这种方式下,当 CPU 输出控制字后,输出将为高电平。 用门控信号达到同步计
数的目的,方式 2 计数过程时序如图所示,下面对工作原理进行分析。
(1) 计数过程
CPU 写入控制字后,时钟 CLK 上升沿,OUT 输出变为高电平,当计数初值被写
入初值寄存器后,下一个时钟脉冲下降沿,计数初值被移入计数执行单元,开始减 1
计数,减到 1 时(不是减到 0 时),OUT 输出变为低电平,经过一个时钟 CLK 周期,OUT
输出又变成高电平,并且计数器将自动按初值重新开始计数过程。采用方式 2 时,不用
重新设置计数初值,计数器能连续工作,输出端不断输出固定负脉冲。如果计数初值为
N,则每输入 N 个 CLK 脉冲 ,输出一个负脉冲,负脉冲宽度等于 1 个 CLK 时钟周期 ,
两负脉冲间的宽度等于 N-1 个时钟周期,整个计数过 程不用重新写入计数值,重复周
期为 N 倍的 CLK 周期,因此又称此方式下的计数器为 N 分频器或频率发生器。
(2) GATE 门控信号的影响
门控信号为低电平时 终止计数,而由低电平恢复为高电平后的第一个时钟下降沿
起,从初始值重新开始计数。由此可见 GATE 一直维持高电平时,计数器为一个 N 分
频器。GATE 端每加一次从低电平到高电平的门控触发信号,都将引起一次重新从计数
初值寄存器向计数执行单元写入计数值的操作,输出端 OUT 重新又得到一个不断输出
负脉冲的脉冲信号,其宽度等于一个时钟周期,两负脉冲间的宽度等于 N-1 个时钟周
期。用门控信号实现对输出端 OUT 信号的同步作用。
(3) 新的初值对计数过程的影响
如果在计数过程中改变初值,有两种情况:一种是当 GATE 门控信号一直维持高
电平时,新的初值不影响当前的计数过程,但在计数结束后,下一个计数周期按新的初
值计数;另一种是若写入新的初值后,遇到门控信号的上升沿,则结束现行计数过程,
从下一个时钟下降沿开始按新的初始值进行计数。 第二种情况是计数值未减到 0,又
重新按新的初值进行计数,在此期间输出端 OUT 一直维持高电平,这样就可以随时通
过重新送计数值来改变输出脉冲的频率
图 8.7 方式 2 波形图
4.方式 3:方波发生器
3 方式与 2 方式基本相同,两者的主要区别是输出的脉冲宽度不同,方式 3 计数过
程时序图如图 8.8 所示,下面对工作原理进行分析。

WR WR
CLK CLK
GATE GATE

OUT OUT

4 3 2 1 4 3 2 1 4 3 5 4 3 2 1 5 4 3 2 1
① 初始值为偶数 ②当初始值为奇数

图 8.8 方式 3 波形图
(1) 计数过程
方式 3 计数过程分奇、偶两种情况。①当初始值为偶数时,CPU 写入控制字后,
在时钟 CLK 的上升沿,OUT 输出变为高电平。当计数初值写入初值寄存器 CR 后,经过
一个时钟周期,计数初值被移入计数执行单元 CE,下一个时钟下降沿开始作减 1 计数。
减到 N/2 时,OUT 输出变为低电平,计数器执行单元继续执行减 1 计数,当减到 0 时,
OUT 输出又变成高电平,计数器执行单元重新从初值开始计数。只要门控信号 GATE 为 1,
此工作过程周而复始重复进行,在 OUT 输出得一方波信号,故称这种方式又称为方波发
生器。②当初始值为奇数时, 在门控信号一直为高电平情况下,OUT 输出波形为连 续
的近似方波,高电平持续时间为(N+1)/2 个脉冲,低电平持续时间为(N-1)/2 个脉冲。
(2) GATE 门控信号的影响
当门控 GATE=1 时,允许计数;当门控 GATE=0 时,禁止计数。在计数执行过程
中,当 GATE 变为低电平时,若此时 OUT 输出为低电平,则 OUT 从低电平变为高电平,
若 OUT 原来是高电平则保持不变,且计数器停止计数。当 GATE 恢复高电平,计数器从
初值开始重新计数。
(3) 新的初值对计数过程的影响
新的初值写入也分两种情况。①当门控 GATE=1 时,在计数执行过程中,新值写
入并不影响现行计数过程,只是在下一个计数过程中,按新值进行计数;②在计数执行
过程中,加入一个 GATE 脉冲信号,停止现行计数过程,在门控信号上升沿后的第一个
时钟周期的下降沿,按新初值开始计数。
5.方式 4:软件触发选通方式
方式 4 为软件触发选通方式,其工作波形如图 8.9 所示。

WR

CLK
GATE

OUT
3 2 1 0 FF

图 8.9 方式 4 波形图

其计数过程时序图 如图所示,下面对工作原理进行分析。
(1) 计数过程
在方式 4 下,写入控制字后,在时钟上升沿,OUT 输出变成高电平,将计数初值
写入初值寄存器 CR 中。经过一个 CLK 时钟周期,计数初值被送入计数执行单元 CE,
下一个时钟下降沿开始减 1 计数,减到 0 时,OUT 输出变为低电平,脉冲宽度为一个
CLK 时钟周期,然后 OUT 自动恢复成高电平。下一次启动计数时,必须重新写入计数
值。若设置计数初值为 N,则在写入计数初值后的 N+1 个 CLK 时钟脉冲,才输出一个
负脉冲,负脉冲的宽度为 1CLK 周期。
方式 4 不能自动重复计数(即这种方式计数是一次性的),每进行一次计数过程必
须重装初值一次,所以称方式 4 为软件触发。OUT 输出低电平持续时间为一 CLK 时钟
周期,常用此负脉冲作为选通信号,所以又称为软件触发选通方式。
(2) GATE 门控信号的影响
当 GATE 门控信号为高电平时,允许计数;当 GATE 门控信号为低电平时,禁止
计数。需要注意两点:
①当 GATE 门控信号为低电平时停止计数,GATE 门控信号为高电平时并不是恢复
计数,而是重新从初值开始计数。
②GATE 的电平不会影响 OUT 输出的电平,只有计数器减为 0 时,才使 OUT 输出
产生电平的变化,
(3) 新的初值对计数过程的影响
在计数过程中,如果写入新的计数初值,则立刻终止现行的计数过程,并在下一
个时钟下降沿按新的初值 开始计数。
方式 0 和方式 4 都可用于定时和计数,定时的时间 =N×T。只是方式 0 在 OUT
端输出正脉冲信号为定 时时间到,方式 4 在 OUT 端输出负脉冲信号为定时时间到。
6.方式 5:硬件触发选通方式
方式 5 的工作波形如图 8.10 所示。由 GATE 上升沿触发计数器开始工作。方式 5
为硬件触发选通方式,完全由 GATE 端引入的触发信号控制定时和计数,下面对工作
原理进行分析。
(1) 计数过程
在方式 5 下,CPU 写入控制字后,在时钟上升沿,OUT 输出变成高电平,写入计
数初值后,计数器并不立即开始计数,当门控信号 GATE 的上升沿到来后,在下一个
时钟下降沿时,将计数初值移入计数执行单元,才开始减 1 计数,计数器减到 0,OUT
输出变为低电平,持续一个时钟周期又变为高电平,并一直保持高电平,直至下一个门
控信号 GATE 的上升沿的到 因此,采用方式 5 循环计数时,计数初值可自动重装,但
不计数,计数过程的进行是靠门控信号触发的,称方式 5 又称为硬触发。若设置计数初
值为 N,则在 GATE 的上升沿到来后,经过 N+1 个 CLK 时钟脉冲,才输出一个负脉冲,
负脉冲的宽度为 1 个 CLK 周期。
(2) GATE 门控信号作用
如果在计数的过程中,又来一个 GATE 门控信号的上升沿,则立即终止现行的计
数过程,在下一个时钟周期的下降沿,又从初值开始计数。如果在计数过程结束后,来
一个 GATE 门控信号的上升沿,计数器会在下一个时钟周期下降沿,从初值开始减 1
计数,不用重新写入初值。只要门控信号的上升沿到来,就会马上触发下一个计数过程。
(3) 写入新的初值对计数过程的影响
无论在计数的过程中,还是在计数结束之后,写入新的初值都不会影响计数过程,
必须在门控信号的上升沿到来后,才会发生下一个新的计数过程,计数的初值是按写入
新的初值进行。

CW=1AH LSB=3
WR

CLK
GATE

OUT

3 2 1 0 FF 3
图 8.10 方式 5 波形图
从上述各工作方式可看出,GATE 作为各通道的门控信号,对于各种不同的工作方
式,它所起的作用各不相同。

8.1.3 8253 初始化编程


要使用 8253 必须首先进行初始化编程,初始化编程的内容为:必须先写入每一个
计数器的控制字,然后写入计数器的计数值。在有些方式下,写入计数值后此计数器就
开始工作了,而有的方式需要外界门控信号的触发启动。
在初始化编程时,某一计数器的控制字和计数值,是通过两个不同的端口地址写入
的。任一计数器的控制字都是写入至控制字寄存器(地址总线低两位 A1A0=11),由控制
字中的 D7D6 来确定是哪一个计数器的控制字;而计数值是由各个计数器的端口地址写入
的。
1、方式命令的作用:
对 8253 初始化、也可对当前计数值进行锁存。
2、工作方式的特点:
(1)向命令寄存器写入方式命令,以便确定计数器和工作方式;
(2)向选定计数器按方式命令要求写入计数初始值;
3、初始化编程的步骤为:
(1)写入计数器控制字,规定计数器的工作方式。
(2)写入计数值。
① 若规定只写低8位,则写入的为计数值的低8位,高8位自动置0。
② 若规定只写高8位,则写入的为计数值的高8位,低8位自动置0。
③ 若是16位计数值,则分两次写入,先写入低8位,再写入高8位。

例8-1:对计数器2初始化,使其工作于方式3, 采用二进制格式计数,计数初始值
为4000H 。假设8253的片选信号由地址线A9~A2经译码器后产生,计数器1的口地址
为2F1H ,控制字寄存器的口地址为2F3H。
解:
初始化程序片段
MOV AL 10110110B ; 控制字
MOV DX 2F3H ; 控制寄存器地址
OUT DX AL ;写入控制字
MOV DX 2F2H ;计数器 2 地址
MOV AL 00H ;初值低 8 位
OUT DX AL ;写入计数器 2
MOV AL 40H ;初值高 8 位
OUT DX AL ;写入计数器 2

例8-2:要求计数器0工作于方式3,输出方波的重复频率为2KHz,计数脉冲输入为
2.5MHz,采用BCD码计数,试写出初始化程序段。
解:
计算计数初值:
TC= 2.5MHz/ 2KHz=1250
方式字为:0011 0111B=37H
(计数器0,写16位,方式3,BCD计数)
设端口地址为:80H、81H、82H、83H。
则初始化程序为:
MOV AL,37H;写入方式控制字
OUT 83H,AL
MOV AL,50H;写入计数初始值低8位
OUT 80,AL
MOV AL,12H ;写入计数初始值高8位
OUT 80H,AL
(3)读计数值
①以普通对计数器端口读的方法取得当前计数值
②锁存计数器的当前值(RL1RL0=00)

例8-3:读出例1中计数器2当前的计数值。
解:
锁存控制字
计数器2 锁存计数值 无关默认为0
10 00 0000
以上情况的初始化程序如下:
MOV DX 2F3H ; 控制字寄存器口地址
MOV AL 80H ; 计数器 2 的锁存命令送 AL
OUT DX AL ; 写入 8253 的控制字寄存器
MOV DX 2F2H ; 取计数器 2 的口地址
IN AL DX ;读计数器 2 的低字节
XCHG AL AH ; 暂存 AH
IN AL DX ; 读计数器 2 的高字节
XCHG AL AH ;使计数值的低字节到 AL 高字节到 AH

例 8-4:设 8086 系统中 8253 的三个计数器的端口地址为 0A0H,0A2H 和 0A4H,


控制口地址为 0A6H,要求计数器 0 为方式 1,按 BCD 计数;计数初值为 1800D,计
数器 1 为方式 0,按二进制计数;计数初值为 1980H,计数器 2 为方式 3,按二进制计
数;当计数初值为 065H 时,试分别写出计数器 0,1,2 的初始化程序。
解:
计数器 0 的初始化:
计数 0 的控制字:00100011B=23H
MOV AL,23H ;计数器 0 的控制字
OUT 0A6H,AL ;控制字写入 8253 的控制器
MOV AL,18H ;取计数初值的高 8 位,低 8 位 00 可不送
OUT 0A0H,AL ;计数初值送计数器 0 端口
计数器 1 和初始化:
计数器 1 的控制字:01110000B=70H
MOV AL,70H ;计数器的控制字:方式 0,送高 8 位和低 8 位,二进制计数
OUT 0A6H,AL ;控制字写入 8253 的控制器
MOV AL,080H ;取计数初值的低 8 位
OUT 0A2H,AL ;计数初值的低 8 位,写入计数器 1 端口
MOV AL, 19H ;取计数初值的高 8 位
OUT 0A2H,AL ;计数初值的高 8 位写入计数器 1 端口
计数器 2 的初始化:
计数器 2 的控制字:10010110B=96H
MOV AL,96H ;计数器 2 的控制字 96H:方式 3,只送低 8 位,二进制计数
OUT 0A6H,AL ;控制字写入 8253 的控制口
MOV AL,056H ;计数初值的低 8 位
OUT 0A4H,AL ;计数初值的低 8 位写入计数器 2 的端口

8.1.4 8253 应用举例


1.8253 定时功能的应用
例 8-4: 8086 系统接有一片 8253,当 A7~A2=001011 时该 8253 芯片工作,定义
通道 0(计数器 0)工作在方式 4,CLK0=2MHz,要求定时 5ms;通道 2(计数器 2)
工作在方式 0,其 CLK2 输入外部记数事件,每计满 1275 个数向 CPU 发出中断请求。
要求:
(1)确定 8253 各口地址;
(2)确定 8253 各通道的控制字;
(3)编写 8253 通道 0 和通道 2 的初始化程序。
解:(1)8253 的口地址分别为:2CH,2DH,2EH,2FH
(2)8253 通道 0 的控制字为:00111000(38H)
8253 通道 1 的控制字为:10110001(B1H)
(3)MOV AL,38H
OUT 2FH,AL
MOV AX,10000;
OUT 2CH,AL
MOV AL,AH
OUT 2CH,AL
MOV AL,0B1H
OUT 2FH,AL
MOV AX,1275H
OUT 2EH,AL
MOV AL,AH
OUT 2EH,AL
例 8-5:下图是用 8253 监视的一个生产流水线示意图,每通过 50 个工件扬声器响
5 秒钟,频率为 2000Hz。

+5V

工件
INT OUT0 CLK0 光敏 光源
电阻
8253
1.4MHz CLK1 驱
8255PC0 GATE1 OUT1 动 扬声器

分析:
①计数器 0 工作于方式 2 分频方式,每隔 50 个 CLK0 产生一个中断 INT;方式控
制字为:00010101B(15H),即方式 2,只装低 8 位,BCD 数制,初值为 50(H)。
②计数器 1 工作于方式 3 方波方式,产生 2000Hz 喇叭音调,方式控制字为:
01110111B(77H),即方式 3,先低后高,BCD 数制;
初值(分频比)=(1.4×106)/2000=700(H)。
(其中,计数器的时钟频率为 1.4MHz)
主程序段: MOV AL,15H;置计数器 0 方式
OUT 43H,AL;
MOV AL,50H;装初值
OUT 40H,AL;
MOV AL,00H;关 8255 的 PC0
OUT 63H,AL;
MOV AL,77H;置计数器 1 方式
OUT 43H,AL;
MOV AL,00H;装初值
OUT 41H,AL;
MOV AL,07H;
OUT 41H,AL;
STI;
LOP: HLT;
JMP LOP;
中断服务程序:
INTP: MOV AL,01H;开 8255 的 PC0
OUT 63H,AL;
CALL DLY5S;调 5S 延迟子程序
MOV AL,00H;关 8255 的 PC0
OUT 63H,AL;
IRET;
(说明:在装入 8253 计数器的初值时,不管是二进制数制还是 BCD 数制,初值
后均要加“H”。)
例 8-6: 8253A-5 的计数通道 0 连接如图所示,试回答:
(1)计数通道 0 工作于何种方式,并写出工作方式名称;
(2)写出计数通道 0 的计数初值(列出计算式)
(3)写出初始化程序

解:(1)由于出现一个 CLK 周期宽度的负脉冲的方式有方式 2\5 两种,但是 GATE0 是


一直保持高电平,因此方式 5 是无法触发的,因此可以判断计数通道 0 工作于方式 2
(2)因为 CLK 周期宽度为 400ns, CLK 正脉冲宽度为 200ns,因此计数通道 0 的
计数初值= 1ms/ 400ns=2500
(3)初始化程序段(设 8253 的口地址为:80H-83H)
MOV AL,0001 0101B
MOV 83H,AL
MOV AL,00H
OUT 80H,AL
MOV AL,25H
OUT 80H,AL
3. PC 机 8253 的应用
例 8-7:如下图所示,是 8253 在 IBM-PC 机中的应用

工作原理分析
⑴计数器 0 用来产生实时日时钟信号,工作于方式 3,计数初值为 0,采用二进制
计数方式,输出端 OUT0 作为中断请求信号 IRQ0 。
⑵计数器 1 用来产生动态存储器刷新操作的定时控制信号。它工作于方式 2,计数
初值为 18,OUT1 端输出一个负脉冲序列,其脉冲周期约为 18÷1.1931816MHz=15.08
(μs)。
⑶计数器 2 用于为系统中的扬声器发声时提供一个约为 900Hz 的方波信号。它也
工作于方式 3,计数初值为 0533H(1331),GATE2 接入一个来自系统板上 8255A 的
PB0,作为扬声器发声时间的控制信号 。
8253 的初始化程序段
⑴对计数器 0 的初始化程序:
MOV AL,00110110B
OUT 43H,AL
MOV AL,0
OUT 40H,AL
OUT 40H,AL
⑵对计数器 1 的初始化程序:
MOV AL, 01010100B
OUT 43H,AL
MOV AL,18
OUT 41H,AL

3.8253 计数通道的级联使用
例 8-8:以 2MHz 输入 8253,实现每 5 秒定时中断(设 8253 端口地址 40H~43H)。
分 析 : 8253 最 大 初 值 65536 , CLK=2MHz 可 实 现 最 大 时 间 间 隔
65536/(2×106)=32.769ms
所以需要两个计数器串联,一个计数器的输出作为另一个计数器的输入。
计数器 1:模式 2,OUT1 每 5ms 输出一个脉冲
初值(2×106)/(1/0.005)=10000

计数器 0:模式 2,OUT0 每 5s 输出一个脉冲


初值(1/0.005)/(1/5)=1000

图 8.12 8253 计数通道的级联使用


汇编程序段:
MOV AL, 74H
OUT 43H, AL
MOV AX, 10000
OUT 41H, AL
MOV AL, AH
OUT 41H, AL

MOV AL, 34H


OUT 43H, AL
MOV AX, 1000
OUT 40H, AL
MOV AL, AH
OUT 40H, AL
4. 电脑键盘模拟简易钢琴应用实例
例 8-9 音符 1、2、3、4、5、6、7 的频率分别为 350、393、441、467、525、589、
661,编写一个程序,使用户按下 1~7 键时扬声器发出相应的音符,按下其他键退出程
序。(说明:该程序可以实现电脑键盘模拟简易钢琴的功能,试着弹奏一首“虫儿飞”
吧!)
汇编源程序:
code segment
assume cs:code
start:mov al,10110110h ;设置定时器控制字为使用计数器 2,方式 3,二进制计数。
out 43H,al ;写控制字到控制端口

next:mov ah,01h ;中断调用用来输入一个字符


int 21h

cmp al,31h ;判断是否为 1


jz l1
cmp al,32h ;判断是否为 2
jz l2
cmp al,33h ;判断是否为 3
jz l3
cmp al,34h ;判断是否为 4
jz l4
cmp al,35h ;判断是否为 5
jz l5
cmp al,36h ;判断是否为 6
jz l6
cmp al,37h ;判断是否为 7
jz l7

jmp exit ;其它字符程序结束


l1:mov ax,3400 ;设置 1 的计数初值
jmp sound
l2:mov ax,3028 ;设置 2 的计数初值
jmp sound
l3:mov ax,2698 ;设置 3 的计数初值
jmp sound
l4:mov ax,2548 ;设置 4 的计数初值
jmp sound
l5:mov ax,2266 ;设置 5 的计数初值
jmp sound
l6:mov ax,2020 ;设置 6 的计数初值
jmp sound
l7:mov ax,1800 ;设置 7 的计数初值

;发声程序
sound:mov al,03h ;设置 8255 的 B 口(61H)的值,使其末两位为 1
out 61h,al
out 42h,al ;向定时器端口 2 写计数初值的低 8 位
mov al,ah
out 42h,al ;向定时器端口 2 写计数初值的高 8 位
;延迟程序,双重循环
mov bx,030fh
delay1:mov cx,0ffffH
delay2:loop delay2
dec bx
jnz delay1
;清 8255 的 B 口(61H)末两位的值,停止发声
mov al,00h
out 61h,al
;回到程序开始处,等待用户输入下一个字符
jmp next
;退出
exit:mov ah,4ch
int 21h
code ends
end start
8.2 可编程并行 I/O 接口芯片 8255A

8.2.1 可编程并行接口 8255A


8255是一个通用可编程接口电路。其具有的资源为:三个可编程的8位并行I/O口PA、
PB和PC口;PC口可以按位进行操作。
8255内部共有3个8位的输入输出端口(即A口、 B口、 C口)数据总线缓冲器、读
写控制模块、 A组和B组控制,8255A为双列直插式,共有40条引脚 ,使用单一的+5V
电源.两个4位(C口高/低4位),有2 位片内地址线,4 条控制线,2 条电源线,并行I/O
端口的接口芯片。
1.由图8.12可见,由以下几部分组成8255A内部结构:
1) 数据总线缓冲器
它是双向三态8位数据缓冲器,与8086CPU的数据接口之间相连。CPU 执行输入指
令时,8255A 可将状态信息或数据通过总线缓冲器向CPU 输入。CPU执行输出指令时,
可将控制字或数据通过数据总线缓冲器传送给8255A。
2) 并行输入和输出端口A、B、C
8255A芯片内部包含三个8位端口,它包括3个8位输入输出端口。每个端口都有一
个数据输入寄存器和一个数据输出寄存器。
3) A 组和B 组控制部件
A组控制电路控制端口A和端口C的上半部(PC7~PC4)。B组控制电路控制端口B和端
口C的下半部(PC3~PC0)。控制A、B和C三个端口的工作方式。
4) 读/写控制部件
RD和WR:读/写线,控制8255的读、写操作。 读/写控制逻辑由读信号RD、写信
号WR、选片信号CS以及端口选择信号A1A0等组成。这是8255A 内部完成读/写控制功
能的部件,它能接收CPU 的控制命令,并根据它们向片内各功能部件发出操作命令。
图 8.12 8255A 内部结构

图 8.13 8255 引脚号

2.8255A 的芯片引脚信号
(1)VCC:电源端。GND:接地端。
(2) CS : 片选信号。由 CPU 输入, CS 有效,表示该 8255A 被选中。
(3) RD , WR :读、写控制信号。控制 8255 的读、写操作, RD 有效,表示 CPU
读 8255A。 WR 有效,表示 CPU 写 8255A。
(4)RESET:复位信号,复位线,通常与单片机的复位端相连。RESET 有效时,清除
8255A 中所有控制字寄存器内容,并将各端口置成输入方式。
(5)A1、A0:端口选择信号,I/O 口的选择线,通过它可以选择 PA 口、PB 口、PC 口
和控制寄存器。
当 A1A0=00,选择端口 A;
当 A1A0=01,选择端口 B;
当 A1A0=9, 选择端口 C;
当 A1A0=11,选择控制字寄存器。
由端口地址 A1A0 和相应控制信号组合起来可定义各端口的操作方式如表 8.1 所示。
表 8.1 8255A 的读写操作

8.2.2 8255A 的控制字及其工作方式


8255 有两个控制字:
1)方式控制字:方式控制字用于设定单片机的 PA 口、PB 口和 PC 口的工作方式,
如图 8.13 所示。
2)置位/复位控制字:置位/复位控制字用于对 8255A 的 PC 口按位进行操作。
8255A 各端口共有 3 种基本工作方式:
工作方式 0:基本的输入/输出方式
工作方式 1:选通工作方式
工作方式 2:双向传送方式,只有 PA 口工作于此方式。
端口 A 可处于 3 种工作方式(方式 0,方式 1 或方式 2),端口 B 只可处于两种方式
(方式 0 或方式 1),端口 C 常常被分成高 4 位和低 4 位两部分,可分别用来传送数据
或控制信息。
1. 控制字
(1)工作方式控制字:
格式如图 8.13 所示。通过定义工作方式控制字可将 3 个端口定义为各种不同方式
的组合。
图 8.13 8255A 工作方式控制字格式
例 8-10:要把 A 口指定为 1 方式,输出,C 口上半部为输出;B 口指定为 0 方式,
输入,C 口下半部定为输入。
工作方式命令代码是:10100001B。
初始化的程序段为:
MOV DX,2F3H ;8255A 命令口地址
MOV AL,10100001B ;初始化命令
OUT DX,AL ;送到命令口
(2)置位/复位控制字:
只对端口 C 有效。端口 C 的任一位,可用这个控制字来置位或复位,而其他位不
变,使用格式如图 8.14 所示。

图 8.14 8255A 置位/复位控制字格式


例 8-11:若要把 C 口的 PC6 引脚置成高电平输出,则命令字应该为 00001101B 或
0BH。
会使得从 PC 口的 PC2 引脚输出高电平,程序段为:
MOV DX,2F3H ;8255A 命令口地址
MOV AL,0BH ;使 PC6=1 的命令字
OUT DX,AL ;送到命令口
2. 工作方式
(1)方式 0(基本输入输出方式)
A 口工作在方式 0 时,A 口和 C 口之间没有硬件联系;
B 口工作在方式 0 时,B 口和 C 口之间没有硬件联系;
工作在方式 0 的端口,为单向传送端口,由方式控制字决定是输入还是输出。
(2)工作方式 1(选通输入输出方式)
端口 A、B 口工作在方式 1 时, C 口的 6 根引脚作为 A、B 口的联络信号。
1 方式是一种选通输入/输出方式或叫应答方式,因此,需设置专用的联络信号线或
应答信号线,以便对 I/O 设备和 CPU 两侧进行联络。数据输入/输出操作要在选通信号
控制下完成。这种方式通常用于查询(条件)传送或中断传送。
因为输入是从 I/O 设备向 8255A 送数据进来,所以 I/O 设备应先把数据准备好,
并送到 8255A,然后 CPU 再从 8255A 读取数据。传递过程中指定了 C 口的 3 根线作为 8255A
与外设及 CPU 之间应答信号。
采用工作方式 1 进行输入操作时,需要使用的控制信号如下:

STB :选通信号。低电平有效。 STB 有效时,将外设输入的数据锁存到所选端口

的输入锁存器中
IBF:8255A 给外设的回答信号“输入缓冲器满”,高电平有效。IBF 有效时,表示
由输入设备输入的数据已占用该端口的输入锁存器。
INTR:8255A 给 CPU 的“中断请求”信号,高电平有效,8255A 向 CPU 发出中断
请求信号。
INTE:中断允许信号,控制中断允许或中断屏蔽的信号。8255A 中的端口 A 和端
口 B 均可工作于方式 1 输入模式,端口状态。当端口 A 和端口 B 同时被定义为工作方
式 1 完成输入操作时,端口 C 的 PC5~PC0 被用作控制信号,只有 PC7 和 PC6 位可完成数
据输入或输出操作,因此可构成两种组合状态:它们是端口 A,B 输入,PC7,PC6 同时
输入和端口 A,B 输入,PC7,PC6 同时输出。
(a)端口 A 方式 1 输入 (b)端口 B 方式 1 输入
图 8.15 方式 1 输入端口状态
例 8-12:若允许 PA 口输入时,产生中断请求,则必须设置 INTEA=1,即置 PC4=1;
若禁止它产生中断请求,则置 INTEA=0,即置 PC4=0,其程序段为:
MOV DX,2F3H ;8255A 命令口
MOV AL,00001010B ;置 PC4=1,允许中断请求
OUT DX,AL
MOV AL,00001000B ;置 PC4=0,禁止中断请求
OUT DX,AL
采用工作方式 1 也可完成输出操作,这时需要使用的控制信号如下:

OBF :输出缓冲存储器满信号。低电平有效。表示 CPU 已将数据写入该端口正等

待输出。

ACK :设应答信号。低电平有效。表示外部设备已收到由 8255A 输出的八位数据,

它实际上是对 OBF 信号的回答信号。

INTR:中断请求信号。高电平有效。8255A 向 CPU 发出新的中断请求信号。


INTE:中断允许信号。与端口 A、端口 B 工作在方式 1 输入情况时 INTE 的含义一
样,INTE 为 1 时,使端口处于中断允许状态,INTE 为 0 时,则使端口处于中断屏蔽状
态。
当端口 A 和端口 B 同时被定义为工作方式 1 完成输出操作时,端口 C 的 PC6,7 和 PC3~
PC0 被用作控制信号,只有 PC4,5 两位可完成数据输入或输出操作。因此可构成两种组合
状态:①端口 A,B 输出,PC4,5 同时输入;②端口 A,B 输出,PC4,5 同时输出。
(a)端口 A 方式 1 输出 (b)端口 B 方式 1 输出
图 8.16 方式 1 输出端口状态
(3)工作方式 2
2 方式是一种双向选通输入输出方式,它把 A 口作为双向输入/输出口,把 C 口的 5
根线(PC3~PC7)作为专用应答线,所以,8255A 只有 A 口才有 2 方式。其引脚定义如
图 8.17 所示。2 方式的状态字的含义是在 1 方式下输入和输出状态位的组合,不再赘
述。

图 8.17 A 口方式 2 端口状态

8.2.3 8255A 的编程及应用实例


例 8-13:8255A 接口电路如图 8.18 所示。已知 8255A 控制字寄存器的端口地址为
103H,编写 8255A 初始化程序和循环彩灯控制程序。初始时 D0 亮,其余不亮,D0 亮一
秒后移位一次,D1 亮,其余不亮,以此类推每隔一秒移位一次,每移位 8 次为一个循
环.共循环 8 次。要求用汇编语言写出满足上述要求的程序段(已知一个延时 1 秒的子
程序入口地址为 DELAY1S)。
图 8.18 8255 与 LED 灯
因为用到 LOOP 指令,循环计数器应该使用 CX,而不应该只用 CL。
MOV DX ,2F3H ;2F3H 为方式控制字地址
MOV AL , 80H
OUT DX , AL ;设置该 8255 B 口为方式 0 输出,其他位可置 0
MOV CX , 8 ;设置循环次数
MOV DX , 2F1H ;2F1H 为 B 口数据端口地址
AGAIN: MOV AL , 01H ;先设置 D0 位输出为高电平,点亮第一个彩灯
NEXTP: OUT DX , AL
CALL DELAY1S ;B 口相应位发出高电平点亮彩灯,并维持 1S
SHL AL , 1
JNZ NEXTP
LOOP AGAIN
例 8-14:利用 8255 驱动打印机,待打印数据存放于物理地址从 21000H 开始的
内存单元中,8255 与打印机连接采用图 8.19 方式,要求
(1)完成 8255 的初始化和打印机的初始化;
(2)若满足以下条件之一则结束打印:
①打印内容为 0AH;
②已经打印完第 100 个数;请完成打印程序。
图 8.19 8255 驱动打印机
解:分析 PA 端口地址为 0098H,控制寄存器地址为 009BH;8255 控制命令字为
81H 或 83H 或 85H 或 87H;
(1)INI55:MOV DX,009BH;
MOV AL,81H;
OUT DX,AL;
MOV AL,0DH;
OUT DX,AL;
PRINT:MOV AX,2000H
MOV DS,AX
MOV BX,1000H
MOV CX,100
GOON:MOV DX,009AH
WAIT:IN AL,DX
TEST AL,04H;
JNZ WAIT
MOV AL,[BX]
MOV AH,AL
MOV DX,0098H
OUT DX,AL
MOV DX,009AH
MOV AL,0CH
OUT DX,AL
MOV AL,0DH
OUT DX,AL
INC BX
CMP AH,0AH
JZ NEXT
LOOP GOON
NEXT:HLT
例 8-15:8255A 接口电路如图所示。已知 8255A 控制字寄存器的端口地址为 2F3H,
编写 8255A 初始化程序和循环彩灯控制程序。初始时 D0 亮,其余不亮,D0 亮一秒后移
位一次,D1 亮,其余不亮,以此类推每隔一秒移位一次,每移位 8 次为一个循环.共循
环 8 次。要求用汇编语言写出满足上述要求的程序段(已知一个延时 1 秒的子程序入口
地址为 DELAY1S)。

图 8.20 8255 与 led 灯


因为用到 LOOP 指令,循环计数器应该使用 CX,而不应该只用 CL。
MOV DX ,2F3H ;2F3H 为方式控制字地址
MOV AL , 80H
OUT DX , AL ;设置该 8255 B 口为方式 0 输出,其他位可置 0
MOV CX , 8 ;设置循环次数
MOV DX , 2F1H ;2F1H 为 B 口数据端口地址
AGAIN: MOV AL , 01H ;先设置 D0 位输出为高电平,点亮第一个彩灯
NEXTP: OUT DX , AL
CALL DELAY1S ;B 口相应位发出高电平点亮彩灯,并维持 1S
SHL AL , 1
JNZ NEXTP
LOOP AGAIN
例 8-15:8255 方式 0 应用 1。如图 8.21 所示 A 口接 8 个开关,分别控制 B 口的 8
个发光二极管的亮灭,试编程实现。 (已知条件:A 口地址:300H B 口地址:301H C 口
地址:302H 控制口地址:303H)
Vcc
8255A
.
PA0
.
. .
数据总线 .
D0~D7 .
D0~D7 .
.
.

PA7
Vcc
地址总线 A1
PB0 .
A0~A15 A0 .
. .
CS .
.
.
.
RD RD .
PB7
WR WR
时钟发生
RESET
器RESET
图 8.21 8255 方式 0 应用 1
编码如下:
code segment
assume cs:code

start: mov dx,303h ;8255 控制端口地址


mov al,90h ;100 10 0 0 0B 工作方式控制字
out dx,al ;设置 A 口输入,B 口输出
next: mov dx,300H ;A 口地址
in al,dx ;读开关量
mov dx,301H ;B 口地址
out dx,al ;写发光二极管状态
jmp next
code ends
end start
例8-16:8255 方式 0 应用 2。如图 8.22 所示 A 口接 8 个发光二极管,B 口接 8
个开关,分别控制 A 口的 8 个发光二极管的亮灭。但前提条件是 PC0 采样到高电平。试
编程实现。(已知条件:A 口地址:300H B 口地址:301H C 口地址:302H 控制口地
址:303H)
8255A Vcc
PA0 .
.
. .
数据总线 .
D0~D7 .
D0~D7 .
.
.
PA7
Vcc
地址总线 A1
A0~A15 PB0 .
A0
.
. .
CS .
.
. .
RD RD .
WR WR PB7
时钟发生 PC0
RESET
器RESET
图 8.22 8255 方式 1 应用 2
编码如下:
code segment
assume cs:code
start: mov dx,303h ;8255 控制端口地址
mov al,83h ;1 00 0 0 0 1 1 B 工作方式控制字
out dx,al ;设置 A 口输出,B 口输入,PC0 输入
next: mov dx,303h ;8255 控制端口地址
mov al,00h
out dx, al ;使 PC0 复位
mov dx, 302h ;C 端口地址
que:in al,dx ;查询 PC0 是否为 1
test al,01h
jz que ;PC0 为 0 则继续查询
mov dx,301h ;B 口地址
in al,dx ;读开关量
mov dx,300h ; A 口地址
out dx,al ;写发光二极管状态
jmp next
code ends
end start
8.3 数/模和模/数转换接口

8.3.1 数/模转换器(DAC)的主要性能参数
(1) 分辨率:它反映了数字量在最低位上变化1位时输出模拟量的最小变化。数字
量的位数越多,分辨率越高(数值越小)亦即转换器对输入量变化的敏感程度也就越高。
标准电压5V,8位:5V/28 ,10位:5V/210。
(2) 线性度:它是指D/A转换器的实际转移特性与理想直线之间的最大误差,或最
大偏移。一般情况下,偏差值应小于±1/2LSB。
(3) 转换精度:指D/A转换器实际输出与理论值之间的误差,一般采用数字量的最
低有效位作为衡量单位。精度和分辨率是两个不同的概念,精度取决于构成转换器的各
个部件的误差和稳定性,而分辨率取决于转换器的位数。如D/A分辨率为20mV,则精
度为 ±10mV。
(4) 转换时间:D/A完成一次转换所需要的时间。数字量输入到完成转换、输出达
到最终值并稳定为止所需的时间。一般电流型D/A转换器在几秒到几百微秒之内;而电
压型D/A转换器转换较慢,取决于运算放大器的响应时间。一般转换速度越快越好。

8.3.2 模/数转换器 DAC0832


DAC0832是采用CMOS工艺制成的双列直插单片8位D/A转换器,它能与多种单片机
相连,与8051相连时,以电流形式输出,当转换成电压输出时,可以外接运算放大器,
可产生256种不同的电压值。

1.DAC0832的内部结构与引脚图

图8.23给出了DAC0832的内部结构。图8.24给出了DAC0832的引脚图。

图8.23 DAC0832的内部结构
DAC0832是8位DA转换器,内部有两级三态缓冲器,输入数据可分别经过两个锁存器
保存。ILE=1,CS=WR1=0,写入第1级缓冲器;XFER=WR2=0,写入第2级缓冲器,并开始转
换。
DAC0832具有一组8位数据线D0~D7,用于输入数字量。一对模拟输出端IOUT1和IOUT2
用于输出与输入数字量成正比的电流信号,转换器的基准电压输入端VREF 一般在
-10V~+10V范围内。
各引脚的功能如下:
CS——片选信号输入端,低电平有效。
ILE——数据锁存允许信号输入端,高电平有效。
WR1——输入锁存器写选通信号,低电平有效。它作为第一级锁存信号将输入数据
锁存到输入锁存器中。WR1必须在CS和ILE均有效时才能起操控作用。
WR2——DAC寄存器写选通信号,低电平有效。它将锁存在输入锁存器中可用的8
位数据送到DAC寄存器中进行锁存。此时,传送控制信号XFER必须有效。
XFER——传送控制信号,低电平有效。当
XFER为低电平时,将允许。
D0~D7——8位数据输入端,D7为最高位。
IOUT1、IOUT2——模拟电流输出端,转换结
果以一组差动电流(IOUT1 ,IOUT2)输出。当DAC
寄存器中的数字码全为“l”时,IOUT1最大;全为“0”
时,IOUT2 为零。IOUT1+IOUT2=常数,IOUT1 、
IOUT2随DAC寄存器的内容线性变化。
RFB——反馈电阻引出端,DAC0830内部已有
反馈电阻,所以 RFB端可以直接接到外部运算放
大器的输出端,这样,相当于将一个反馈电阻接在
运算放大器的输入端和输出端之间。
VCC——电源电压输入端,范围为+5~+15 V,
以+15 V时工作为最佳。 图8.24 DAC0832的外部引脚
VREF——参考电压输入端,此端可接一个正电压,也可接负电压。范围为-10~+10
V。外部标准电压通过VREF与T型电阻网络相连。此电压越稳定,模拟输出精度就越高。
AGND——模拟地。
DGND——数字地。

2. DAC0832的工作模式

DAC0832可工作在三种不同的工作模式,如图8.25。
1. 直通方式
内部结构当ILE接高电平,CS,WR1、WR2和XFER都接数字地时,DAC处于直通
方式,8位数字量一旦到达D0~D7输入端,就立即加到D/A转换器,被转换成模拟量。
2. 单缓冲方式
单缓冲方式是将一个锁存器处于缓冲方式,另一个锁存器处于直通方式,输入数据
经过一级缓冲送入D/A转换器。把 和 都接地,使寄存锁存器2处于直通状态,
ILE接+5V, 接CPU系统总线的 信号, 接端口地址译码信号,这样CPU通过
MOV AL,N ;OUT P,AL实现转换。
3. 双缓冲方式
数据通过两个寄存器锁存后再送入D/A转换电路,执行两次写操作才能完成一次
D/A转换。转换数据可以通过 MOV AL,N ; OUT P0,AL; OUT P1,AL 来实现。

图 8.25 DAC0832 的工作方式

例 8-18:用 DAC0832 产生方波:


CONV:
MOV AL,00H ;低电平
OUT 20H,AL ;启动转换
CALL DELAY ;低电平宽度
MOV AL,0FFH ;高电平
OUT 20H,AL ;启动转换
CALL DELAY ;高电平宽度
JMP CONV
用 DAC0832 产生锯齿波:
MOV AL,00H
CONV:
OUT 20H,AL
INC AL
NOP
NOP
NOP ;决定坡度
JMP CONV
例8-19 如图利用DAC0832的直通方式实现梯形波。
MOV DX,2F3H
MOV AL,80H
OUT DX,AL
MOV DX,2F1H
MOV AL,10H
OUT DX,AL
MOV DX,300H
L1: MOV AL,0
OUT DX,AL
INC AL
JNZ L1 图 8.26 DAC0832 与 8255 连接
L2: MOV AL,0A0H
OUT DX,AL
DEC AL
JNZ L2
JMP L1

8.4 ADC 模/数转换器

8.4.1 ADC 的主要参数


1.分辨率:是指转换器对输入电压微小变化的响应能力的度量。通常以输出数字
量的位数表示。位数越多,分辨率越高,转换时对输入量的微小变化的反应越灵敏。
2.转换时间和转换频率:从输入启动信号到转换结束,得到稳定的数字量所需的
时间。通常,转换频率是转换时间的倒数,它反应了采集系统的实时性能。
3.精度、线性度同 DAC

8.4.2 ADC 的外部特性(必备信号线)


1.模拟信号输入线:单通道/多通道
2.数字量输出线:分辨率
3.转换启动线:启动方式
4.转换结束状态线:查询/引发中断/请求 DMA

8.4.3 ADC 接口的主要操作


1. 发启动转换信号
2. 取回“转换结束”状态信号
3. 读取转换结果
4. 进行通道选择:多通道 ADC
5. 发采样/保持(S/H)控制信号:高速变化信号

8.4.4 ADC0809 的内部结构与引脚图


图8.27给出了ADC0809转换器的内部结构图。

图 8.27 A0809 内部逻辑图

芯片内除含有8位逐次逼近型A/D转换器外,还有8通道多路转换器和3位地址锁存
和译码器,以实现对8路输入模拟量IN0~IN7的选择。当地址锁存允许信号ALE有效时,
将3位地址ADDC~ADDA锁入地址锁存器中,经译码器选择8路模拟量中的一路通过8
位A/D转换器转换输出。由于输出端具有三态输出锁存缓冲器,因此可以直接与CPU系
统总线相连接。
图8.27中ADC0809内部各单元的功能如下:
① 通道选择开关:实现分时采样8路模拟信号。
② 通道地址锁存和译码: ADDA、ADDB、ADDC地址选择端及译码控制通道选
择开关。
③ 逐次逼近A/D转换器:包括比较器、8位开关树型D/A转换器、逐次逼近寄存器。
转换的数据从逐次逼近寄存器传送到8位锁存器后经三态门输出。
④ 8位锁存器和三态门:当输入允许信号OE有效时,打开三态门,将锁存器中的
数字量经数据总线送到CPU。
图8.28 ADC0809引脚
图8.28中各引脚功能如下:
IN0~IN7:8路模拟输入通道。
D0~D7: 8位数字量输出端。
START:启动转换命令输入端。
OE:输出使能端,高电平有效。
ADDA、ADDB、ADDC:8路模拟开关的3位地址选通输入端,以选择对应的输入通
道。ADDc为高位地址,ADDA为低位地址。
ALE:地址锁存允许信号。当ALE为上升沿时,用于将ADDA~ADDC三条地址线送
入地址锁存器中。
EOC:转换结束信号输出。转换完成时,EOC的正跳变可用于向CPU申请中断,其
高电平也可供CPU查询。
CLK:时钟脉冲输入端,要求时钟频率不高于640KHZ。
REF(+)、REF(-):基准电压,一般与微机接口时,REF(-)接0V或-5V,REF
(+)接+5V或0V。
通常,通道选择由数据信号完成,START与ALE相连:选择通道的同时启动。

8.4.5 ADC0809 应用
下面举例说明如何编写A/D转换程序。
例8-20:编写A/D转换程序,具体要求如下:
① 采样IN2输入通道的模拟信号;
② 结果保存在ADDBUF开始的内存单元中;
分析:采集通道2通道,置通道号为2
将通道号写入A2,启动转换并锁存通道号
对A0读,读回EOC(D7)
对A1读,读取转换结果
图 8.29 ADC0809 外部引脚
相应的采集程序如下:
MOV DI, OFFSET ADDBUF;寻址数据区,结果保存在ADDBUF存储区
MOV AL, 02 ;置通道号
MOV DX,A2 ;取IN2启动地址
OUT DX,AL ;启动A/D转换
MOV DX,A0 ;取查询EOC状态的端口地址
WAIT:IN AL,DX ;读EOC状态
TEST AL,80H ;测试A/D转换是否结束
JZ WAIT ;未结束,则跳到WAIT处
MOV DX,A1 ;取读A/D转换结果寄存器的端口地址
IN AL,DX ;读A/D转换结果
MOV [DI],AL ;保存转换结果

例8-21:按图8.30编写A/D转换程序,具体要求如下:
① 顺序采样 IN0~IN7 8 个输入通道的模拟信号;
② 结果依次保存在 ADDBUF 开始的八个内存单元中;
③ 上述采样每隔 100ms 循环一次。设 DELAY 是一延时 100ms 子程序。
分析: (1)模拟输入通道 IN0~IN7 由 A0~A2 决定其端口地址,分别为 300H~307H,

与 IOW 相配合,可启动 ADC0809 进行转换;

(2)查询端口和读 A/D 转换结果寄存器的地址分别为:308H 和 300H。


308H~30FH

≥ +5V

I/O
A9 ()
REF + Vcc
1
IOR
译 500KHZ
A3 300H~307H ≥ OE CLK

2 ALE
EOC

IOW
≥ START
ADC0809 D7 D7

IN0
8 路模拟输入
IN7 D0 D0

A2 ADDC
A1 ADDB REF(-)

A0 ADDA
GND

图8.30 ADC0809 与 CPU 的连接

相应的采集程序如下:
AD:MOV CX,0008H ;通道计数单元 CX 赋初值
MOV DI, OFFSET ADDBUF;寻址数据区,结果保存在 ADDBUF 存储区
START:MOV DX,300H ;取 IN0 启动地址
LOOP1:OUT DX,AL ;启动 A/D 转换,AL 可为任意值
PUSH DX ;保存通道地址
MOV DX,308H ;取查询 EOC 状态的端口地址
WAIT:IN AL,DX ;读 EOC 状态
TEST AL,80H ;测试 A/D 转换是否结束
JZ WAIT ;未结束,则跳到 WAIT 处
MOV DX,300H ;取读 A/D 转换结果寄存器的端口地址
IN AL,DX ;读 A/D 转换结果
MOV [DI],AL ;保存转换结果
INC DI ;指向下一保存单元
POP DX ;恢复通道地址
INC DX ;指向下一个模拟通道
LOOP LOOP1 ;未完,转入下一通道采样
CALL DELAY ;延时 100ms
JMP AD ;进行下一次循环采样,跳至AD处。
习题8
8-1 填空
①、如果要在系统中扩展一片 8253,分配给 8253 的端口地址是 3F0H~3F3H,系统用地
址 线 A0~A9 来 寻 址 I/O 端 口 。 那 么 该 8255 的 片 选 信 号 /CS 应 由 地 址 线
经译码后产生; /WR、/RD 应分别与控制总线中的 和 相连。
②、8253 共有 种工作方式,其中方式 与方式 能在计数结束后自动重赋初
值。
③、8253 每个通道的最大计数值是 。如果欲使计数值超过此最大值,可
在硬件上采用 的方法,或在软件上采用
的方法。
④、在 IBM PC/XT 系统中,8255 的三个端口均工作于方式 。端口 A 在上电复位之
初用做 口,作用是 ;正常工作时用做
口,作用是 ;端口 B 用做 口,作用
是 ;端口 C 则用做 口,作用
是 。
⑤、某 PC 微机系统占用口地址 384H~387H 扩展一片 8255。若欲使该片 8255 的 PA 口工
作于方式 1、输出;PB 口工作于方式 1、输入;PC4 用做 PC 机的控制信号,则初始
化时应向口地址 H 写入控制字为 H。若需通过 PC4 向外设送出低有
效的命令,可向口地址 H 处写入 H。
8-2 8253 的计数器1 工作在方式3,按二进制计数,计数初始值为50;计数器2 工作在
方式2 下,BCD 码计数,计数初始值为1000; 8253 占用的端口地址为200H 到203H。
写出初始化程序。
8-3 8253每个通道的最大定时值是多少?欲使8253用于定时值超过其最大值时,应如
何应用?
8-4 8255A 的 24 条外设数据线有什么特点?总结 8255A 端口 C 的使用特点。
8-5 编程使 8255A 的 PC5 端输出一个负跳变。如果要求 PC5 端输出一个负脉冲,则程
序又如何编写?
8-6 设 8255 的端口地址为 200H~203H。(1)要求 PA 口方式 1,输入;PB 口方式 0 输出;
PC7~PC6 为输入;PC1~PC0 为输出。试写出 8255 的初始化程序。(2)程序要求当 PC7=0
时置位 PC1,而当 PC6=1 时复位 PC0,试编制相应的程序
8-7 设一工业控制系统,有四个控制点,分别由四个开关 K0~K3 控制,控制点的状态
用发光二极管 L0~L3 表示,开关打开则对应的发光二极管亮,表示该控制点运行正常;
开关闭合则对应发光二极管不亮,说明该控制点出现故障。画出系统的结构框图并编写
程序。
8-8知某8088微机中8255A与ADC0809的部分电路如下图所示,电路中8255A的
口地址为80H~83H。

要求:编写8255A初始化程序;说明A/D转换需要哪几个步骤? 编写一段从
ADC0809 IN4采集5个数据存入BUF开始的单元的程序段。
8-9 DAC 0832 有哪几种工作方式?每种工作方式适用于什么场合?每种方式用什么方法
产生的?
第9章 实 验

第一部分 软件实验

快速掌握 Emu8086

一、 实验要求:

1.掌握 Emu8086 软件使用方法。

2.学会单步调试

二、 实验目的:

(1) 熟悉汇编语言开发环境。

(2) 掌握 Emu8086 软件使用方法。

(3) 了解汇编语言的程序结构、调试一个简单的程序。

(4) 理解寻址方式的意义。

三、 实验内容:

1、Emu8086 的使用

(1)打开桌面上的 Emu8086 的图标,出现如图所示的对话框,选择【继续……】


图 9-1 emu8086 启动界面

首次打开软件,界面中默认已有一段小程序。该程序实现在屏幕上显示三段字符串
的功能。若用户需要自己重新编程,可点击工具栏的【新建】图标,出现如图所示的对
话框,选择编程所采用的模板。

图 9-2 emu8086 新建界面


选择不同的模板,在程序源代码中会出现如下标记:

#MAKE_COM# 选择 COM 模板
#MAKE_BIN# 选择 BIN 模板
#MAKE_EXE# 选择 EXE 模板
#MAKE_BOOT# 选择 BOOT 模板

(2)选择 COM 模板,点击【确定】,软件出现源代码编辑器的界面,如图所示:

图 9-3 emu8086 新建 exe 界面

在源代码编辑器的空白区域,编写如下一段小程序:

MOV AX, 5
MOV BX, 10

ADD AX, BX

SUB AX, 1

HLT

图 9-4 emu8086 新建指令界面

代码编写结束,点击菜单【文件】【另存为……】,将源代码换名保存。本例将源
代码保存为 TEST.asm。点击工具栏的【模拟】按钮,如果程序有错误不能编译,出现
如图所示的界面:
图 9-5 emu8086 指令错误界面

点击错误提示,即可选择源代码中相应的错误的行,在此处更改源代码。如果
源程序无错误,则编译通过,出现如图所示的界面:
图 9-6 emu8086 单步界面

点击【单步执行】,程序将每执行一条指令便产生一次中断。点击【运行】,
程序将从第一句直接运行到最后一句。

界面的左侧可以观察程序运行过程中,各个寄存器的值的变化。若是查看内存
区域的值,可以选择菜单【查看】【外部存储器】,出现如下界面:
图 9-7 emu8086 内存查看界面

单步运行该程序段,观察各寄存器的变化。

实验一 简单指令实验

一、实验要求:1.掌握简单指令的执行过程
二、实验目的:1.学习数据传送指令的用法。
2.熟悉在 PC 机上建立、汇编、链接、调试和运行汇编语言程序的过
程。
三、实验内容:
把 RAM 内 4000H~40FFH 单元内容清零

四、实验程序:
PROGNAM SEGMENT
ASSUME CS:PROGNAM,DS:DATA
ORG 3000H
START: MOV BX,4000H
MOV AX,0000H
MOV CX,007FH
L1: MOV [BX],AX
INC BX
INC BX
LOOP L1
MOV AH,4CH
INT 21H
PROGNAM ENDS
END START

五、问题思考:
1)AX,BX,CX,CS,IP,DS 的数据如何变化,为何这样变?
2) 007FH 在这里的作用是什么,能不能实现实验要求的清零?
3)两个 INC BX 在这里的作用是什么?
4) LOOP 在这里如何影响 CX,以及起到的作用?
5)观察 DS:[BX]中值的变化?为何这样?

实验二 寻址方法实验

一、实验要求:1.深入了解数据在存储器中的存储方法,及堆栈中数据的压入与弹出
2.掌握各种寻址方法及简单指令的执行过程
二、实验目的:1.学习数据传送指令的用法。
2.熟悉在 PC 机上建立、汇编、链接、调试和运行汇编语言程序的过
程。
三、实验内容:
1、设堆栈指针 SP=2000H,AX=3000H,BX=5000H;请编一程序段将 AX 和 BX 的内容进
行交换。请用堆栈作为两寄存器交换内容的中间存储单元,用字处理程序编辑程序,
2. 用单步执行的方法,分析每条指令源地址的形成过程,当数据传送完毕时,AX 中的
内容是什么。

四、实验程序:
DATA SEGMENT
ORG 0300H
A DB 12H,23H,34H,45H,56H,67H,78H,89H,9AH
DATA ENDS
PROGNAM SEGMENT
ASSUME CS:PROGNAM,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV AX,BX
MOV AX,0300H
MOV AX,[0300H]
MOV AX,[BX]
MOV BX,1
MOV AX,0001[BX]
MOV AX,[BX+1]
MOV AX,[BX][SI]
MOV AX,0001[BX][SI]
MOV AH,4CH
INT 21H
PROGNAM ENDS
END START

五、问题思考:
1)单步运行,观察每个寄存器变化;每条指令的寻址方式是什么?
2)单步运行,观察内存的变化,观察 AX 变化;SI 是多少,它的作用是什么?
3)区分 MOV BX,1
MOV AX,0001[BX]
MOV AX,[BX+1]的不同;

实验三 算术运算指令实验

一、实验要求:
计算两个双倍精度字相加 1234FEDCH+11228765H=?两个双倍精度字存放在:
1000H,2000H 的开始单元。
二、实验目的:掌握算术指令的用法。
三、实验内容:
1.利用 ADD,ADC 指令实现两个双倍精度字相加 ,两个双倍精度字存放在:
1000H,2000H 的开始单元。
2.观察各种寻址,标志;思考为何这样改变。
四、实验程序:
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATA
START: MOV SI,1000H
MOV AX,[SI]
MOV DI,2000H
ADD AX,[DI]
MOV [SI],AX
MOV AX,[SI+2]
ADC AX,[DI+2]
MOV [SI+2],AX
MOV AX,4C00H
INT 21H ;结束
CODE ENDS
END START

五、问题思考:
1)ADD,ADC 指令的区别是什么?
2)如何实现了双字节加法?CF 如何改变?
3)每条指令运行后 CF 如何改变,为什么?
4)观察 DS:[DI]与 DS:[SI]中值的变化?为何这样?

实验四 查表程序设计

一、实验要求:
1、熟练掌握编写汇编语言原程序的基本方法和基本框架。
2、掌握查表法和查表指令 XLAT。
二、实验目的:
掌握用组合的 BCD 码表示数据,并熟悉怎样实现组合 BCD 码乘法运算。
三、实验内容:
用查表的方法将一位十六进制数转换成与它相应的 ASCII 码,并将结果存放到 ASCI 单
元中。
四、实验程序:
既然指定用查表的方法,那么首先要建立一个表 TABLE。我们在表中按照十六进制数
从小到大的顺序放入他们对应的 ASCII 码值。
DATA SEGMENT
TABLE DB 30H,31H,32H,33H,34H,35H,36H,37H
DB 38H,39H,41H,42H,43H,44H,45H,46H
HEX DB X ;X 为待转换的十六进制数
ASCI DB ?;存放转换后的 ASCII 码
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATA
START: MOV BX,OFFSET TABLE
MOV AL,0AH
XLAT TABLE
MOV AX,4C00H
INT 21H ;结束
CODE ENDS
END START

五、问题思考:
1)XLAT 指令的使用方法?
2)如何建立表?
3)分析 MOV BX,OFFSET TABLE 指令?

第二部分 硬件实验部分

快速掌握 PROTEUS

让我们首先来熟悉一下仿真软件的主界面:
图 9-8 仿真软件的主界面

运行 protues 的 ISIS 模块,进入仿真软件的主界面,如图 9-8 所示,


区域①为菜单及工具栏,区域②为元器件预览区,区域③为对象选择器窗口,
区域④为编辑窗口,区域⑤为绘图工具栏,区域⑥为元器件调整工具栏,区
域⑦为运行工具条。
任务:绘制 8086 最小系统,利用 8255 实现 led 的闪烁:
目标:通过此练习,快速掌握 PROTEUS 的基本用法
步骤一: PROTEUS 电路设计
整个设计都是在 ISIS 编辑区中完成的。
(1)单击工具栏上的“新建”按钮 ,新建一个设计文档。单击“保

存”按钮 ,弹出如图 9-9 所示的“Save ISIS Designe File”对话框,在

文件名框中输入“8255-led”(简单实例的文件名),再单击“保存”按钮,
完成新建设计文件操作,其后缀名自动为.DSN。

图 9-9 保存 ISIS 设计文件


(2)选取元器件
此简单实例需要如下元器件:
CPU:8086
三八译码器:74LS138
门电路:74LS08
锁存器:74LS373
并行接口:8255A
LED 灯:LED-RED
单击图 9-10 中的“P”按钮 ,弹出如图 5-4 所示的选取元器件对话
框,在此对话框左上角“keywords(关键词)”一栏中输入元器件名称,如
“8086”,系统在对象库中进行搜索查找,并将与关键词匹配的元器件显示
在“Results”中。在“Results”栏中的列表项中,双击“8086”,则可将“8086”
添加至对象选择器窗口。按照此方法完成其它元器件的选取,如果忘记关键
词的完整写法,可以用“*”代替,被选取的元器件都加入到 ISIS 对象选择
器中。如图 9-11 所示。

图 9-10 单击“P”按钮选取元器件
图 9-11 选取元器件窗口

图 9-12 选取元器件均加入到 ISIS 对象选择器中


(3)放置元器件至图形编辑窗口
在对象选择器窗口中,选中 8086,将鼠标置于图形编辑窗口该对象的欲
放置的位置、单击鼠标左键,该对象被完成放置。同理,将其余器件放置到
图形编辑窗口中。若元器件方向需要调整,先在 ISIS 对象选择器窗口中单击

选中该元器件,再单击工具栏上相应的转向按钮 ,把元器
件旋转到合适的方向后再将其放置于图形编辑窗口。
若对象位置需要移动,将鼠标移到该对象上,单击鼠标右键,此时我们
已经注意到,该对象的颜色已变至红色,表明该对象已被选中,按下鼠标左
键,拖动鼠标,将对象移至新位置后,松开鼠标,完成移动操作。

(4)放置终端(电源、地)

放置电源操作:单击工具栏中的终端按钮 ,在对象选择器窗口中选

择“POWER”如图 9-13 所示,再在编辑区中要放电源的位置单击完成。


放置地(GROUND)的操作与此类似。
图 9-13 放置终端符号
(5)元器件之间的连线
Proteus 的智能化可以在你想要画线的时候进行自动检测。下面,我们来
操作将电阻 R1 的右端连接到 LED 显示器的左端,如图 9-14 所示。当鼠标
的指针靠近 R1 右端的连接点时,跟着鼠标的指针就会出现一个“□”号,
表明找到了 R1 的连接点,单击鼠标左键,移动鼠标(不用拖动鼠标),将鼠标
的指针靠近 LED 的左端的连接点时,跟着鼠标的指针就会出现一个“□”
号,表明找到了 LED 显示器的连接点,单击鼠标左键完成电阻 R1 和 LED
的连线。
Proteus 具有线路自动路径功能(简称 WAR),当选中两个连接点后,WAR
将选择一个合适的路径连线。WAR 可通过使用标准工具栏里的“WAR”命
令按钮 来关闭或打开,也可以在菜单栏的“Tools”下找到这个图标。
同理,我们可以完成其它连线。在此过程的任何时刻,都可以按 ESC
键或者单击鼠标的右键来放弃画线。
图 9-14 编辑完成的简单实例的电路图

1.3.2 步骤二:源程序设计
源程序设计
DATA SEGMENT
CONT EQU 00E6H
PA EQU 00E0H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
MOV DS,AX
MOV DX,CONT
MOV AL,82H
OUT DX, AL
MOV AL,0FFH
LOO: MOV DX, PA
OUT DX,AL
NOT AL
CALL DELAY
JMP LOO
DELAY PROC
PUSH BX
PUSH AX
PUSH CX
MOV CX,0FFH
D1: MOV AX,00FFH
D2: DEC AX
JNZ D2
LOOP D1
POP CX
POP AX
POP BX
RET
DELAY ENDP
CODE ENDS
END START
1.3.3 步骤三:PROTEUS 仿真

(1)加载目标代码文件
双击编辑窗口的 8086 器件,在弹出如图 9—15 所示属性编辑对话框

Program File 一栏中单击打开按钮 ,出现文件浏览对话框,找到


FLASH_LED.HEX 文件,单击“打开”按钮,完成添加文件。在 Clock frequency
栏中把频率设置为 5MHZ,仿真系统则以 5MHZ 的时钟频率运行。

图 9-15 加载目标代码文件窗口

(2)仿真
单击按钮 ,启动仿真,仿真运行片段如图 9-16 所示。发光二极
管间隔 500 毫秒闪烁。
图 9—16 仿真运行片段
红色方块代表低电平,蓝色方块代表高电平,灰色方块代表不确定电平。

实验一 开关状态显示实验

一、实验要求:编写程序,设定 8255 的 PB 口为开关量输入,PA 口为开关量输出,要


求能随时将 PB 口的开关状态通过 PA 口的发光二极管显示出来。
二、实验目的:学习使用 8255 各个口的不同工作方式
三、实验电路
图 9—17 8255 开关灯

四、实验说明:本实验要求 8255 工作方式 0,PB 口设置为输入,PB 口设置为输出,


输入量为开关量,通过 8255 可实时显示在 LED 灯上。
五、实验程序:
DATA SEGMENT
DATA ENDS
STACK SEGMENT STACK
STA DW 50 DUP(?)
TOP EQU LENGTH STA
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
START:
MOV DX, 00E6H ;设置为 B 口输入,A 口输出
MOV AL, 82H
OUT DX,AL
BG: MOV DX, 00E2H ;将 B 口状态从 A 口输出
IN AL,DX
MOV DX, 00E0H
OUT DX,AL
JMP BG
CODE ENDS
END START

实验二 定时器/计数器实验

一、实验要求:编程将 8253 定时器 0 设定为方式 3,定时器 1 设定在方式 2,定时器 0 输


出作为定时器 1 的输入,定时器 1 的输出接在一个 LED 上,运行后可观
察到该 LED 在不停闪烁。
二、实验目的:了解 8253 定时器的时序关系。掌握 8253 的各种模式编程及原理。
三、实验电路
图 9—18 8253 定时器

四、实验说明:8253 的工作频率为 0~2MHZ,所以输入的 CLK 频率必须在 2MHZ 以下。


五、实验程序:
CONTROL EQU 00E6H
COUNT0 EQU 00E0H
COUNT1 EQU 00E2H
COUNT2 EQU 00E4T
CODE SEGMENT
ASSUME CS:CODE
START PROC NEAR
MOV AL, 36H; 00110110B ; 计数器 0,16 位,方式 3,二进制
MOV DX, CONTROL
OUT DX, AL
MOV AX, 10000
MOV DX, COUNT0
OUT DX, AL ; 计数器低字节
MOV AL, AH
OUT DX, AL ; 计数器高字节
MOV AL, 76H; 01110110B ; 计数器 1,16 位,方式 3,二进制
MOV DX, CONTROL
OUT DX, AL
MOV AX, 100
MOV DX, COUNT1
OUT DX, AL ; 计数器低字节
MOV AL, AH
OUT DX, AL ; 计数器高字节
JMP $
START ENDP
CODE ENDS
END START

实验三 综合实验

一、实验要求:利用 8253 与 8255 设计混合芯片实现流水。


二、实验目的:了解多芯片混合编程及原理。
三、实验电路

图 9—18 多芯片系统图

四、实验说明:8253 的工作频率为 0~2MHZ,所以输入的 CLK 频率必须在 2MHZ 以下。


五、实验程序:
DATA SEGMENT
COTR EQU 00F6H
PB_A EQU 00F0H
PC_A EQU 00EEH;8253 控制
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START: MOV DX,00EEH
MOV AL,00110111B ;计数器 0 三方式
OUT DX, AL
MOV DX,00E8H
MOV AL,50H
OUT DX,AL
MOV DX,00E8H
MOV AL,00H
OUT DX,AL
MOV AX,DATA
MOV DS,AX
MOV DX,COTR
MOV AL,10000001B
OUT DX, AL
MOV DX,00EEH
MOV AL,00110111B ;计数器 0 三方式
OUT DX, AL
MOV DX,00E8H
MOV AL,50H
OUT DX,AL
MOV DX,00E8H
MOV AL,00H
OUT DX,AL
MOV DX,PB_A
MOV AL,0FCH
OUT DX,AL
LOO:MOV DX, PB_A
OUT DX,AL
PUSH AX
AGAIN:IN AL,0F4H
MOV AH,AL
IN AL,0F4H
CMP AL,AH
JZ AGAIN
POP AX
ROL AL,1
JMP LOO
CODE ENDS
END START
参考文献
1. 潘名莲等 . 微计算机原理(第二版) . 北京 : 电子工业出版社 , 2003
2. 刘乐善 , 欧阳星明 . 微型计算机接口技术及应用 . 武汉 : 华中科技大学出版社 ,
2007
3. 李广军 微机系统原理及接口技术 . 成都:电子科技大学出版社, 2005
4. 吕勇 徐雅娜 微机原理与接口技术教程与实训. 北京大学出版社,20
5. 王丰 微机原理与接口技术 北京航空航天大学出版社 2005 年 3 月
6. 俸远祯等 . 计算机组成原理(修订本) . 北京 : 电子工业出版社 , 1996
7. 周明德 . 微型计算机系统原理及应用 . 北京 : 清华大学出版社 , 2002
8. 邹逢兴等 . 微型计算机原理及其应用 . 长沙 : 国防科技大学出版社 , 2001
9. Peter Abel 著 , 沈美明等译 . IBM PC 汇编语言程序设计 . 北京 : 人民邮电出版
社 , 2002
10. 王正智 . 8086/8088 宏汇编语言程序设计教程(修订版) . 北京 : 电子工业出版
社 , 1998
11. 周美玉等 . IBM PC 编程技术及汇编语言程序库 . 成都 : 西南交通大学出版社 ,
1988
12. 东阳生等 . 宏汇编语言 MASM6 实用大全 . 北京 : 科学出版社 , 1995
13. 朱慧真 . 80X86 汇编语言教程 . 北京 : 清华大学出版社 , 1995
14. 唐先余 . 实用 DOS 技术 . 成都 : 四川大学出版社 , 1991
15. 顾滨等 . 80X86 微型计算机组成、原理及接口 . 北京 : 机械工业出版社 , 2000
16. 贾智平等 . 微机原理与接口技术 . 北京 : 中国水利水电出版社 , 1999
17. 曾家智等 . 80486/80386 系统设计和应用 . 成都 : 电子科技大学出版社 , 1994
18. 李广军 , 王厚军 . 实用接口技术 . 成都 : 电子科技大学出版社 , 1998
19. 马维华 . 微型计算机及接口技术 . 北京 : 科学出版社 , 2002
20. 艾德才 , 姚嘉康 . 微机接口技术实用教程 . 北京 : 清华大学出版社 , 2002
21. 戴梅萼 . 微型计算机技术及应用 . 北京 : 清华大学出版社 , 1991
22. 魏坚华等 . 微型计算机与接口技术教程 . 北京 : 北京航空航天大学出版社 ,
2002
23. 张弥左等 . 微型计算机接口技术 . 北京 : 机械工业出版社 , 2004
24. 杨全胜 . 现代微机原理与接口技术 . 北京 : 电子工业出版社 , 2002

You might also like