第 10章 中断和输入 /输出程序设计第 10章 中断和输入 /输出程序设计
10.1 概述
10.2 中断处理程序设计
10.3 DOS功能调用
10.4 BIOS中断调用
10.5 输入 /输出程序设计第 10章 中断和输入 /输出程序设计
10.1 概 述在微型计算机中,CPU与外部设备之间的信息传送是通过接口进行的,每个接口由一组寄存器组成,这些寄存器用来存放命令、状态和数据,为了对这些寄存器进行存取,它们都分配有一个称为 I/O端口的地址编码。在 80x86系统中,I/O端口编址在一个独立的地址空间中,这个空间对 80x86来讲,允许设置 64K个 8位端口或 32K个 16位端口; 80386和 80486提供了一个独立的 I/O地址空间。 I/O地址空间由 216(64 K)个可独立编址的 8位端口 (即 64 KB)组成。任意两个连续的 8位端口可作为 16
位端口处理; 4个连续的 8位端口可作为 32位端口处理。
第 10章 中断和输入 /输出程序设计因此,这个 I/O地址空间对 80486来讲,最多能提供 64 K个 8
位端口,32 K个 16位端口,16 K个 32位端口或总容量不超过 64
KB的不同位端口的组合。这 64 K的 I/O地址空间是指物理地址而不是线性地址,因为 I/O指令不经过分段或分页部件。处理器要访问的是存储地址空间还是 I/O地址空间是容易区分的。所有 I/O
端口与 CPU之间的通信都是由输入 /输出指令完成的。其中输入指令完成从 I/O到 CPU的信息传送;而输出指令完成从 CPU到 I/O
的信息传送。
第 10章 中断和输入 /输出程序设计输入和输出设备是计算机系统的重要组成部分。程序、
数据和各种现场采集到的信息要通过输入装置输入至计算机。
计算结果或各种控制信息要输出到各种输出设备,以便显示、
打印和实现各种控制操作。因此,CPU与输入 /输出设备之间的信息交换也是计算机系统中非常重要和十分频繁的操作。
输入过程是:输入设备把数据送到接口,由 CPU执行输入程序把接口中的数据读入 CPU,再根据需要放入存储器或寄存器中。处理程序完成对数据的处理并将处理结果放入指定的寄存器或存储器中。
第 10章 中断和输入 /输出程序设计输出过程,CPU执行输出程序,将存储器或寄存器中等待输出的内容送到输出接口中,然后启动输出设备,将接口中的数据通过输出设备输出。
输入 /输出的基本条件是:连接 CPU与外设的接口电路和相应的软件 —— 驱动程序。
第 10章 中断和输入 /输出程序设计
10.1.1 I/O指令 IN和 OUT
1.格式输入指令:
IN OP1,OP2
IN AL,imm8
IN AX,imm8
IN EAX,imm8
IN AL,DX
IN AX,DX
IN EAX,DX
第 10章 中断和输入 /输出程序设计输出指令:
OUT OP1,OP2
OUT imm8,AL
OUT imm8,AX
OUT imm8,EAX
OUT DX,AL
OUT DX,AX
OUT DX,EAX
第 10章 中断和输入 /输出程序设计
2.功能:
I/O指令 IN和 OUT用于在 I/O端口和 AL,AX或 EAX累加器之间交换数据。输入指令 IN完成从 I/O到 CPU的信息传送;输出指令 OUT完成从 CPU到 I/O的信息传送。
3.端口访问方法
80486有 16条 I/O地址线,I/O端口范围是 64 K。访问端口方法有两种:
① 用 1字节立即数指定的方法,可以访问 0~ 255的端口;
② 采用 DX寄存器间接寻址方法,可以访问 0~ (64 K-1)个端口中的任一端口。
第 10章 中断和输入 /输出程序设计
4.举例
IN AL,0FAH ;从端口 0FAH输入 8位数到 AL
IN EAX,28H ;将端口 28H,29H,2AH和 2BH的 32位数送 EAX
MOV DX,3AEH ; I/O地址大于 255时,应通过 DX间接寻址
IN AX,DX ;从 DX指出的端口输入 16位数到 AX
OUT 21H,AL ;将 8位数从 AL输出到端口 21H
OUT DX,EAX ;将 32位数从 EAX输出到 DX指出的端口第 10章 中断和输入 /输出程序设计
5.说明在保护方式下,当处理器遇到一条 I/O指令时,它首先检查现行任务的特权级是否高于或等于 I/O特权级,即是否
CPL≤IOP1。若是,则执行 I/O操作;否则,处理器检查 I/O允许位图,若 I/O允许位图不允许访问,则会发生异常 13。
第 10章 中断和输入 /输出程序设计
10.1.2 端口地址通过以上叙述可以看出,在进行 I/O程序设计时,需要对端口地址、控制及状态端口的各位含义有清楚的了解。 IBM PC机的部分端口地址如表 10-1所示。控制及状态端口各位的含义在讨论具体外设时描述。
第 10章 中断和输入 /输出程序设计表 10-1 端口地址对照表端口地址 端口设备或接口芯片
00H~ 0FH DMA控制器
0H~ 21H 中断控制器
40H~ 43H 时钟 /定时器
60H~ 63H 可编程外围接口芯片
200~ 20FH 游戏适配器
2F8H~ 2FEH COM1
320H~ 32FH 硬盘控制器
378H~ 37AH 2号并行口 (打印机适配器 )
3B0H~ 3BFH 单色显示及 1号并行口
3D0H~ 3DFH 彩色 /图形适配器
3F0H~ 3F7H 软盘控制器
3F8H~ 3FEH COM2
第 10章 中断和输入 /输出程序设计
10.1.3 CPU与外设之间的信息交换方式
CPU与外设通过硬件接口电路或控制器相连接,这些接口或控制器中都有数量不等的端口,用作 CPU与外设之间传送数据及提供数据传送所需要的控制逻辑与信号。使用 IN,OUT指令对这些端口进行操作,便可以实现 CPU与外设的信息交换。
概括起来,CPU与外设需要交换的信息有:数据信息、状态信息以及控制信息。例如,当需要在打印机上打印一个字符 (数据 )
时,需要先检查打印机是否准备好 (状态 ),若准备好则输出选通命令 (控制 ),以便打印。
第 10章 中断和输入 /输出程序设计
CPU与外设之间的信息交换通常有程序查询、中断传送、
DMA(直接存储器存取 )、通道,I/O处理机管理等几种方式。
CPU寻址外设有两种方式,一种是存储器对应输入 /输出方式,
另一种是端口寻址方式。其中,存储器对应输入 /输出方式把一个外设作为一个存储单元对待,一次输入 /输出操作就相当于一次存储器的读 /写操作,这种方式虽然优点不少,但实际应用却不多,因为它本身不直观,容易与正常的存储器读 /写操作混淆,
同时还需要占用存储器的部分空间并给存储器地址分配带来不便。 CPU输入 /输出端口寻址方式设有专门的输入 /输出指令,
并要求为外设接口分配端口地址。这种端口寻址方式为一个端口一个地址,使用专门的输入 /输出指令,使用方便,不易出错,
清楚直观。需要注意的是,端口寻址可以为直接方式寻址或间接方式寻址。直接方式可以寻址 0~ 255个端口地址。间接方式通过 DX寄存器给出端口地址,可寻址 64K个端口地址。
第 10章 中断和输入 /输出程序设计
1.数据信息数据通常为 8位或 16位,可分为 3种基本类型:数字量、模拟量和开关量。一般地,由键盘、光电输入机等提供的二进制形式的信息为数字量数据。电机的启停、开关的开合等可用两个状态表示的量,即用一位二进制数表示,这样的量称为开关量;由传感器等提供的信号往往是模拟量,它需先经模 /数 (A/D)
转换后再输入到计算机中。例如,温度、电压等信号。 CPU与外设进行数据传送的方式有串行传送 (一位一位传送 )和并行传送
(n位同时传送 )两种方式,但都要经过 I/O指令实现。串行方式比较经济,但速度受限,而并行方式则速度较快,成本较高。
第 10章 中断和输入 /输出程序设计
2.状态信息在输入时,有表示输入装置是否已准备好的信息 (READY);
在输出时,有表示输出装置是否忙的信息 (BUSY)等。
3.控制信息控制信息有控制输入 /输出装置的启停信号,工作方式、
工作规约及格式选择信息等。
值得指出的是,控制信息和状态信息与数据是不同性质的,
必须要分别传送。但它们都通过 IN和 OUT指令在数据总线上进行传送,所以通常采用分配不同端口的方法将它们加以区别。
第 10章 中断和输入 /输出程序设计
10.2 中断处理程序设计
10.2.1 中断处理程序的编写中断是指执行当前程序的过程中,由于某种随机出现的外设请求,使 CPU暂停 (即中断 )正在执行的程序而转去执行为外设服务的程序;当服务完毕后,CPU再退回到暂停处 (即断点 )继续执行原来的程序。现在,中断的概念除了传统的外部事件 (硬件 )
引起的中断外,又产生了内部软件中断的概念。在 80386/80486
中则把许多执行指令过程中产生错误的情况也纳入了中断处理的范围,并将它们和通常意义上的内部软件中断一起统称为异常中断,简称异常 (Exceptions),而将通常意义上的外部中断简称为中断。
第 10章 中断和输入 /输出程序设计中断和异常之间的区别在于,中断用来处理 CPU外部的异步事件,而异常是用来处理在执行指令期间由 CPU本身对检测出的某些条件作出响应的同步事件。用产生异常的程序和数据再次执行时,该异常总是可再现的,而中断通常与现行执行程序无关。但中断和异常在使处理器暂停执行其现行程序,以执行更高优先级程序方面是一样的。
第 10章 中断和输入 /输出程序设计引起中断的原因或发出中断请求的来源,称为中断源。可以根据重要性的不同为各中断源安排不同的优先级,CPU首先响应优先权高的中断。 8086具备一个简单而灵活的中断系统,
它能处理 256种类型的中断,中断类型由类型号 0~ 255指定,
中断源的情况可见图 10-1。 80286以后使用两片 8259A级连结构,
管理 15级中断。
第 10章 中断和输入 /输出程序设计图 10-1 8086的中断源
IN T n
指令
IN T O
指令除法错误单步
(T F= 1 )
中 断 逻 辑
8 0 8 6 CP U
非屏蔽中断请求
IN T R
8 2 5 9 A
可编程中 断控制器
IO RQ 0
IO RQ 1

IO RQ 7
可屏蔽中 断请 求
N M I
第 10章 中断和输入 /输出程序设计
1.外部中断
8086有两条外部中断请求线 NMI和 INTR。 NMI为非屏蔽中断,INTR为可屏蔽中断。 NMI用于重要的中断源,如电源掉电等,它的类型号是 2。 CPU不禁止 NMI线上的中断请求,但可由指令 STI(中断允许标志置,1”)和 CLI(中断允许标志置,0”)允许和禁止 INTR线上的中断请求,即 CPU可用 STI和 CLI指令开、关中断,当关中断时,CPU将不响应 INTR线上的中断请求。
第 10章 中断和输入 /输出程序设计
2.内部中断
1) 除法指令在执行除法指令时,若发现除数为 0或商超过了寄存器所能表达的范围,则立即产生一个类型 0的内部中断。
2) 溢出中断指令 INTO
若上一条指令使溢出标志 OF置 1,那么当执行溢出中断指令 INTO时,立即产生一个类型 4的中断;若标志 OF为 0,则此指令不起作用。
第 10章 中断和输入 /输出程序设计
3) INT n指令
CPU执行完 INTn指令时立即产生一个中断,所以又称它为
“软件中断”。中断的类型由指令中的 n指明。因为 INT指令中可以指定任何的类型号,故此指令可方便地用来调试为外设编写好的中断服务程序。
4) 单步中断若单步标志 IF为 1,则在每条指令执行后,CPU自动产生一个类型 1的中断 (单步中断 ),使程序单步执行,它提供给用户强有力的调试手段。
第 10章 中断和输入 /输出程序设计
8086规定这些中断的优先权从高到低的顺序是:
● 除法错误,INTO,INT n;
● NMI;
● INTR;
● 单步中断。
第 10章 中断和输入 /输出程序设计
3.中断矢量表中断矢量表占用内存中 00000H到 003FFH的 1 KB空间。表中内容分为 256项,对应于类型号 0~ 255,每一项占用 4个字节,
用来存放相应类型的中断服务程序的入口地址,高两字节存放入口地址的段地址部分,低两字节存放段内偏移地址部分,如图 10-2所示。对于任一指定类型的中断,CPU只要将其类型号乘 4就可以得到其中断矢量 (即此类中断在中断矢量表中占用的 4
个字节的最低字节的地址 ),然后取出它所占有的 4个字节的内容分别送到 IP和 CS,就实现了中断服务程序的调用,所以中断矢量表是中断类型号与其对应的中断服务程序之间的连接链。
第 10章 中断和输入 /输出程序设计图 10-2 中断矢量表
00000H

00004H
00008H


0 0 0 0 C H

0 0 3 FC H
类型 0 中断服务程序入口地址类型 1 中断服务程序入口地址类型 2 中断服务程序入口地址

类型2 5 5 中断服务程序入口地址
0 0 3 FF H

IP
CS
第 10章 中断和输入 /输出程序设计采用中断矢量表的方法,CPU可以直接通过中断矢量转向相应的处理程序,而不必逐个检查和确定中断源,因而加快了中断处理的速度。 80386到 Pentium CPU使用中断描述表 IDT
来管理各种中断。当系统工作于实模式时,IDT变为 8086中的中断矢量表。
第 10章 中断和输入 /输出程序设计
10.2.2 中断矢量的获取
1.中断类型号的获取方法
(1) 除法错误、单步中断、非屏蔽中断 NMI、断点中断和溢出中断分别自动提供类型号 0~ 5。
第 10章 中断和输入 /输出程序设计
(2) 对于外部中断 INTR,可以有两种方法提供中断类型号。
方法 1:自己设计接口电路,利用寄存器 /缓冲器或利用
8212芯片这样的组件存放中断类型号。 CPU响应中断后,接口电路将此类型号送入数据总线,CPU读数据总线从而获得中断类型号。图 10-3给出了实现这一功能的接口电路的方框图。
第 10章 中断和输入 /输出程序设计某一外设的中断类型号可事先由输出指令送入它的中断类型号寄存器 /缓冲器或预先将组件 (如 8212芯片 )的引线接好。当外部设备已准备好数据可以向 CPU输送,或外设已准备好可以接收来自 CPU的信号时,状态信号线上发一脉冲信号,经中断请求触发器向 CPU的 INTR线发出中断请求,CPU响应中断后,
进入中断响应周期,发 INTA信号,此信号将已预先装入的或由硬件芯片提供的中断矢量号送入数据总线,CPU即可读得。在中断服务程序中可以安排与此外设的数据交换。
可通过将图 10-3中的中断屏蔽触发器设置为 1或为 0来控制是否让外设发中断请求。
第 10章 中断和输入 /输出程序设计图 10-3 中断方式接口电路方框图外部设备地址总线 AB
中断请求触 发 器中断屏蔽触 发 器状态信号控制总线 CB
数据总线 DB
8 0 8 6 / 8 0 8 8
C P U
I N T R
中断类型号寄存器/ 缓冲器
DB
去 C P U 的 DB
( 中断响应信号)I N T A
&
第 10章 中断和输入 /输出程序设计例 10-1 已为某一外设指定中断类型号为 6,编写此外设中断服务程序。
程序描述如下:
CODE SEGMENT
MAIN,;主程序
HLT
INTR6 PROC NEAR ;中断类型号为 6的中断服务程序
STI
IRET
INTR6 ENDP
CODE NED

第 10章 中断和输入 /输出程序设计做了以上安排后,应在主程序的初始化部分将此中断服务程序的入口地址送入中断矢量表内对应中断类型 6的 4个单元中。
完成这个功能的程序段描述如下:
MOV AX,0
MOV ES,AX
MOV DI,06H*4
MOV AX,OFFSET INTR6
CLD
STOSW
MOV AX,CS
STOSW
第 10章 中断和输入 /输出程序设计在所有中断服务程序的结尾处,应安排开中断指令 STI和从中断返回的指令 IRET。
另一种方法:利用 Intel 8259A芯片。 Intel 8259A是可编程的中断控制器,如图 10-1所示,它可以接收来自外设的 8个各自独立的中断请求信号,分别为 IRQ0~ IRQ7。 8259A将它们按优先权的高低进行排队。 IRQ0优先权最高,依次降低,IRQ7为最低。
当某一时刻出现两个或两个以上的中断请求信号时,8259A首先响应优先权高者。将中断信号送到 CPU的 INTR线上,进而又将对应于该中断源的惟一的中断类型号送给 CPU。 CPU获得此中断类型号,就自动转入对应的中断服务程序。
第 10章 中断和输入 /输出程序设计表 10-2 8259A的中断源表 10-2 8259A的中断源
8259A输入 中断类型号 设 备
IRQ0 08H 定时器 (通道 0)
IRQ1 09H 键盘
IRQ2 0AH 彩色图像接口
IRQ3 0BH 未用
IRQ4 0CH 串行 (RS-232)接口
IRQ5 0DH 未用
IRQ6 0EH 软盘
IRQ7 0FH 打印机第 10章 中断和输入 /输出程序设计
8259A中有一个中断屏蔽寄存器 (IMR),它的 I/O端口地址是
21H。它的位 0~ 7对应于 IRQ0~ IRQ7,可以通过设置这个寄存器的任一位为 0或 1去控制任一中断源的中断允许或禁止。某位为 0表示允许该中断源发出的中断请求信号经 8259A产生一个要发给 CPU的中断,为 1则禁止该中断源。例如,只允许键盘中断,
则可设置如下中断屏蔽字:
MOV AL,0FDH
OUT 21H,AL
第 10章 中断和输入 /输出程序设计使用 8259A时,应在主程序开始处按上述原则初始化中断屏蔽寄存器。在中断服务程序的结束处应发出“中断结束” (EOI)命令 (20H)给 8259A的中断命令寄存器 (I/O端口地址
20H),具体程序如下:
MOV AL,20H
OUT 20H,AL
第 10章 中断和输入 /输出程序设计
2.中断过程在调用相应的中断服务程序前,CPU先将机器状态用标志位入栈的方法保存起来。接着 CPU清除标志位 IF和 TF,屏蔽新的中断请求和单步中断。然后,CPU把当前的代码段寄存器的内容入栈保护,从矢量表 (高两个字节 )中取出新的代码段寄存器值送至 CS;接着 CPU把当前的指令指针值入栈,再从矢量表中取出新的 IP值,送至 IP中。于是程序就转到了中断服务程序。
中断服务程序可按各个设备的要求来加以编制,但通常有保护现场 (入栈 )指令,在返回前要恢复现场 (退栈 )指令,最后要用中断返回指令 IRET,恢复断点处的 CS值和 IP值,并保存 CPU的状态。
第 10章 中断和输入 /输出程序设计在中断发生时,CPU自动清除了 IF和 TF,其目的是使 CPU
转入中断处理程序后,不允许再产生新的中断。如果在执行中断处理程序中,还允许外部中断,可以通过 STI指令再把 IP置 1。
编写中断处理程序和编写子程序一样,所使用的汇编语言指令没有特殊限制,只是中断处理程序返回时使用 IRET指令。这条指令的工作步骤和中断发生的工作步骤正好相反。它首先把 IP、
CS和 EFLAGS的内容弹栈,然后返回中断发生时紧接着的下一条指令,CPU接着执行原来的程序。在中断发生时,下述操作是由硬件自动完成的:
第 10章 中断和输入 /输出程序设计
(1) 取中断类型号 n;
(2) 标志寄存器 (EFLAGS)内容入栈;
(3) 当前代码段寄存器 (CS)内容入栈;
(4) 当前指令指针 (IP)内容入栈;
(5) 禁止外部中断和单步中断 (置 IF=0,TF=0);
(6) 从中断矢量表中取 4× n地址的内容送 IP,取 4× n+2地址中内容送 CS;
(7) 转中断处理程序。
第 10章 中断和输入 /输出程序设计
10.2.3 中断程序设计举例
1.中断和中断返回指令 INT/INTO/IRET
指令格式,INT imm8
INTO
IRET
INT imm8为软中断指令,用于产生一个由 8位立即数指定中断号的软中断。该指令首先将标志寄存器和断点地址 (CS和 IP
的值 )入栈,并将标志位 TF和 IF清 0(关单步和可屏蔽中断 ),然后转向指定中断号对应的中断服务程序。中断服务程序的入口地址是以中断号作为索引,查中断矢量表或中断描述符表得到的。
第 10章 中断和输入 /输出程序设计
INTO为溢出中断指令。它实际上是软中断指令 INT的特例,
其中断号隐含为 1,所以 INTO= INT 4。它只有当 OF置 1时才产生中断。
IRET为中断返回指令,用于从中断服务程序返回原程序。
它执行的操作是从堆栈中弹出原入栈保护的 IP,CS和标志寄存器值,并重新开始被中断程序的执行。
第 10章 中断和输入 /输出程序设计
2.中断处理程序的编写前面已提及,当一个可屏蔽中断被响应后,CPU进入中断响应周期。此时被响应的外设应将本身的中断类型号送往数据总线。 CPU读取这个类型号,将其乘 4,就得到中断矢量表中相应的中断矢量入口,并转入中断处理程序。具体的工作由中断处理程序完成,外中断和软中断程序设计不尽相同。
第 10章 中断和输入 /输出程序设计
1) 外中断处理程序外设中断是随机发生的,在中断处理程序设计时必须考虑这一点。外中断处理程序的主要步骤如下:
(1) 保护现场,主要指各通用寄存器的内容和除 CS外代码段寄存器的内容,保护方法一般是入栈;
(2) 尽快完成中断处理,以免影响其他外设的中断请求;
(3) 恢复现场;
(4) 中断返回,用 IRET指令返回。
第 10章 中断和输入 /输出程序设计
2) 软中断处理程序由中断指令引起的软中断尽管是不可屏蔽的,但只有在
CPU执行中断指令后才会发生。中断指令类似于子程序调用指令,相应的软中断处理程序在很大程度上类似于子程序。
(1) 栈切换。由于软中断处理程序往往在开中断状态下执行,
占用栈空间量大,栈的切换不可避免,同时,为实现中断的嵌套,也需要栈的切换。
(2) 开中断。只有在开中断后,CPU才响应可屏蔽的外设请求,外设的中断请求才能及时得到处理。如果此软件中断处理程序要被外设中断处理程序“调用”,则是否要开中断或何时开中断,应根据实际情况,再作考虑。
第 10章 中断和输入 /输出程序设计
(3) 保护现场。应保护中断处理程序中要使用的寄存器,而这些寄存器在进入中断处理程序前,可能已被其他程序所使用。
这样在使用软中断指令时,可不必考虑有关寄存器内容的保护问题。
(4) 中断处理。
(5) 恢复现场。依次恢复被保护寄存器的原有内容。
(6) 再次实施栈切换。如果在开始时切换了栈,那么也要再重新切换回原栈。
(7) 利用 IRET指令实现中断返回。
第 10章 中断和输入 /输出程序设计例 10-2 当需要改变某个中断矢量的内容时,必须要先将原中断矢量的入口地址保护起来,以便用完之后恢复。使用 DOS
的 35号系统功能调用,读取指定中断矢量 (由 AL寄存器给出 )的入口地址到寄存器对 ES和 BX中,ES寄存器用于存放段基址,
BX寄存器存放偏移量。这就是取中断矢量所要实现的功能。
第 10章 中断和输入 /输出程序设计实现取中断矢量功能的程序描述如下:
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS∶ CSEG
GETINTV PROC FAR
PUSH AX
MOV AH,35H ;调用 DOS功能 35H
INT 21H
POP AX
RET
GETINTV ENDP
CSEG ENDS
END
第 10章 中断和输入 /输出程序设计例 10-3 当用户需要建立一个指定的中断矢量,使其指向用户定义的中断处理程序时,可以使用 DOS的 37号系统功能调用,
将用户定义的中断处理程序的入口地址 DS∶ DX送入由 AL寄存器指定中断号的矢量地址中。现要求编程实现置中断矢量 (60H
号 )指向中断处理程序 MYINT的功能。
此类问题求解的一般方法是:改变中断矢量之前,必须将原中断矢量的入口地址读出,并保存到存储器中,以便自定义的中断程序处理完后进行恢复。下述程序中,GETINTV子程序完成的就是将原中断矢量的入口地址读出的任务。
第 10章 中断和输入 /输出程序设计程序描述如下:
EXTRN GETINTV,FAR,SETINTV,FAR
PUBLIC OLDSEG,OLDOFF
DATA SEGMENT PARA PUBLIC 'DATA'
OLDSEG DW? ;保存段址
OLDOFF DW? ;保存偏移量
DATA ENDS
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS,CSEG,DS,DATA
第 10章 中断和输入 /输出程序设计
START PROC FAR
PUSH ES ;保护 ES
MOV AL,60H ;取 60H号中断矢量
CALL GETINTV
MOV OLDSEG,ES ;并保存到存储器中
MOV OLDOFF,BX
POP ES ;恢复 ES
PUSH DS
PUSH CS
POP DS ;使 DS指向代码段
LEA DX,MYINT ;使 DS∶ DX指向 MYINT
CALL SETINTV ;改变中断矢量
POP DS
RET
第 10章 中断和输入 /输出程序设计
START ENDP
CSEG ENDS
END
MYINT PROC NEAR ;中断处理程序
IRET
MYINT ENDP

第 10章 中断和输入 /输出程序设计值得说明的是,执行上述程序段后,将 60H号中断矢量的内容变为 MYINT。一般情况下,在处理完 MYINT之后,需恢复 60H号中断矢量的原有内容,可执行下述程序段:
EXTRN OLDSEG,WORD,OLDOFF,WORD
EXTRN SETINTV,FAR
PUSH DS ;保护程序的 DS
MOV DS,OLDSEG ; DS∶ DX为原先中断矢量
MOV DX,OLDOFF
CALL SETINTV ;改变中断矢量
POP DS
第 10章 中断和输入 /输出程序设计
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS∶ CSEG
SETINTV ROC FAR
PUSH AX
MOV AH,25H ;调用 DOS功能 25H
INT 21H
POP AX
RET
SETINTV ENDP
CSEG ENDS
END
第 10章 中断和输入 /输出程序设计例 10-4 编一段中断处理程序,在主程序运行的过程中,
每隔 10秒钟响铃一次,同时在屏幕上显示,The bell is ring!”
问题分析:在系统定时器 (中断类型为 8)的中断处理程序中,有一条中断指令 INT 1CH,时钟中断每发生一次 (约每秒中断 18.2次 ),都要调用一次中断类型 1CH的处理程序。使用 1CH
中断类型时,应注意:
第 10章 中断和输入 /输出程序设计
(1) 在 ROM BIOS中,1CH的处理程序只有一条 IRET指令,
实际上它并没有做任何工作,只是为用户提供了一个中断类型号。如果用户有某种周期性的工作需要完成,就可以利用系统定时器的中断间隔,用自己设计的处理程序来代替原有的 1CH
程序。
(2) 1CH是用户的中断类型,可能已被其他功能的程序所引用,所以在编写新的中断程序时,应做下述工作:
① 在主程序的初始化部分,先保存当前中断矢量表的内容,
再置新的中断矢量;
② 在主程序的结束部分恢复保存的 1CH矢量。
第 10章 中断和输入 /输出程序设计程序描述如下:
DATA SEGMENT
COUNT DW 1
MESS DB 'The bell is ring!',0DH,0AH,'$'
DATA DNDS
CODE SEGMENT
ASSUME CS∶ CODE,DS∶ DATA,ES∶ DATA
MAIN PROC FAR
START,PUSH DS
第 10章 中断和输入 /输出程序设计
SUB AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV AL,1CH ;取原中断矢量
MOV AH,35H
INT 21H
PUSH ES ;存原中断矢量段址
PUSH BX ;存原中断矢量偏移量
PUSH DS
MOV DX,OFFSETRING ;新偏移量送 DX
MOV AX,SEG RING
第 10章 中断和输入 /输出程序设计
MOV DS,AX ;新段址送 DS
MOV AL,1CH
MOV AH,25H
INT 21H ;写入新的中断矢量
POP DS
IN AL,21H ;读取中断屏蔽字
AND AL,11111110B ;允许定时器中断
OUT 21H,AL
STI ;开中断
MOV DI,2000
第 10章 中断和输入 /输出程序设计
DELAY,MOV SI,3000 ;延时
DELAY1,DEC SI
JNZ DELAY1
DEC DI
JNZ DELAY
POP DX ;恢复原中断矢量
POP DS
MOV AL,1CH
MOV AH,25H
INT 21H
RET
第 10章 中断和输入 /输出程序设计
MAIN ENDP
RING PROC NEAR
PUSH DS ;各工作寄存器内容入栈
PUSH AX
PUSH CX
PUSH DX
MOV AX,DATA
MOV DS,AX
STI
DEC COUNT ;计秒值
JNZ EXIT
MOV DX,OFFSET MESS
MOV AH,09H
第 10章 中断和输入 /输出程序设计
INT 21H
MOV DX,100
IN AL,61H
AND AL,0FCH
SOUND,XOR AL,02
OUT 61H,AL ;扬声器发声
MOV CX,140H
WAIT1,LOOP WAIT1 ;延时等待
DEC DX
JNE SOUND
MOV COUNT,182
第 10章 中断和输入 /输出程序设计
EXIT,CLI ;关中断
POP DX
POP CX
POP AX
POP DS
IRET ;中断返回
RING ENDP
CODE ENDS
END START
第 10章 中断和输入 /输出程序设计
10.3 DOS功能调用
10.3.1 概述为便于编程,DOS系统把涉及设备驱动和文件管理等方面的子程序编写成相对独立的程序模块并编号,通过功能调用的方法来使用这些子程序,满足用户对设备驱动、文件管理等的需要。减少对系统硬件环境的考虑和依赖,能使应用程序的编制变得简单且有较好的通用性。 DOS系统中,已编号的、可由程序员调用的子程序称为 DOS的功能调用或系统调用。通常,
DOS的各种命令是操作员与 DOS的接口,而功能调用则是程序员与 DOS的接口。
第 10章 中断和输入 /输出程序设计
DOS功能调用主要包括 3方面的子程序:
(1) 设备驱动 (基本 I/O);
(2) 文件管理;
(3) 内存管理、存取时间、存取终端矢量、终止程序等。
第 10章 中断和输入 /输出程序设计
10.3.2 基本 I/O功能调用
1.调用方法为了使用方便,DOS已将所有子程序按功能顺序编了号,
调用时只要按如下方法使用就可以了。
(1) 将要调用功能的功能号送入 AH寄存器;
(2) 根据所调用功能的规定设置入口参数;
(3) 用 INT 21H指令转入子程序入口;
(4) 调用结束后,按规定取得出口参数。
第 10章 中断和输入 /输出程序设计需要指出的是,有的子程序不要入口参数,但大部分需要将参数送入指定地点。编程时,只须给出这三个方面的信息,
而不必关心具体程序如何,在内存中的存放地址如何。 DOS根据所给的信息,自动转入相应的子程序去执行。输出的结果一般是在调用结束后通过出口参数送出,出口参数一般是寄存器。
有些子程序,如屏幕显示字符子程序,调用结束后会在屏幕上显示结果。
第 10章 中断和输入 /输出程序设计例 10-5
MOV DL,','
MOV AH,2
INT 21H
这是 2号功能调用 (编号为 2),实现将字符送入屏幕 (或打印机 )显示的功能。它要求将要显示的字符的 ASCII码值送入 DL,
调用结束,屏幕上显示 DL中的内容“:”。
第 10章 中断和输入 /输出程序设计
2.基本 I/O功能调用
1) 键盘输入 (1号调用 )
1号系统功能调用等待从标准输入设备输入一个字符并送入寄存器 AL,不需入口参数。例 10-6
MOV AH,1
INT 21H
执行上述指令,系统将扫描键盘,等待有键按下,一旦有键按下,就将键值 (相应字符的 ASCII码值 )读入,先检查是否是 Ctrl-Break,若是,则退出命令执行;否则将键值送入 AL
寄存器,同时将这个字符显示在屏幕上。
第 10章 中断和输入 /输出程序设计
2) 控制台输入但无显示 (8号调用 )
8号调用与 1号调用类同,只是不在屏幕上显示输入的字符。
3) 打印输出 (5号调用 )
把 DL中的字符输出到打印机上。
例 10-7
MOV DL,'A'
MOV AH,5
INT 21H
第 10章 中断和输入 /输出程序设计
4) 直接控制台输入 /输出 (6号调用 )
6号调用可从标准输入设备输入字符,也可以向屏幕上输出字符,并且不检查 Ctrl-Break。
若 DL = 0FFH时,表示从键盘输入。
若标志 ZF = 0,表示 AL中为键入的字符值。
若标志 ZF = 1,表示 AL中不是键入的字符值,即尚无键按下。
若 DL≠0FFH时,表示向屏幕输出,DL中为输出字符的
ASCII码值。
第 10章 中断和输入 /输出程序设计例 10-8
MOV DL,0FFH
MOV AH,6
INT 21H;从键盘输入字符
MOV DL,24H
MOV AH,6
INT 21H;将 24H对应的字符 '$' 输出第 10章 中断和输入 /输出程序设计
5) 直接控制台输入但不显示 (7号调用 )
等待从标准输入设备输入字符,然后将其送入 AL,如同 6
号调用,对字符不做检查。
6) 输出字符串 (9号调用 )
调用时,要求 DS∶ DX必须指向内存中一个以,$”作为结束标志的字符串。字符串中每一个字符 (不包括结尾标志 $)都输出显示或打印。
第 10章 中断和输入 /输出程序设计例 10-9
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 21H
CODE ENDS
执行本程序,屏幕将显示,HOW DO YOU DO?




第 10章 中断和输入 /输出程序设计
7) 字符串输入 (0AH号调用 )
从键盘接收字符串到内存输入缓冲区。要求事先定义一个输入缓冲区,缓冲区内第一个字节指出缓冲区能容纳的字符个数,不能为零。第二个字节保留以用作填写输入的字符个数。
从第三个字节开始存放从键盘接收的字符。若实际输入的字符数少于定义的字节数,缓冲区内其余字节填零;若多于定义的字节数,则后来输入的字符丢掉,且响铃。
调用时,要求 DS,DX指向输入缓冲区。
第 10章 中断和输入 /输出程序设计例 10-10
DATA SEGMENT
BUF DB 50 ;缓冲区长度
DB? ;保留为填入实际输入的字符个数
DB 50 DUP (? ) ;定义 50个字节存储空间
DATA ENDS
CODEE SEGMENT
MOV AX,DATA
MOV DS,AX
MOV DX,OFFSET BUF
MOV AH,10
INT 21H
CODE ENDS



第 10章 中断和输入 /输出程序设计
8) 异步通信口输入 (03H)
从标准异步通信接口等待输入一个字符,然后送到寄存器
AL中。启动时 DOS把一个异步通信端口初始化为 2400波特,
没有奇偶校验位,一个停止位,字长为 8位。
9) 异步通信口输出 (04H)
在 DL中的数据被输出到异步通信接口去。
关于异步通信口的输入 /输出,推荐使用 ROM BIOS中断调用 14H。
第 10章 中断和输入 /输出程序设计
10) 日期设置 (28H调用 )
调用时,CX,DX中必须有一个有效的日期,CX中存放年号 (1900~ 2099),DH中存放月号 (1~ 12),DL中存放日号。若日期有效,设置成功,AL= 0;否则 AL= 0FFH。
例 10-11
将日期设置为 2003年 3月 15日,程序段描述如下:
MOV CX,2003
MOV DH,3
MOV DL,15
MOV AH,2BH
INT 21H
第 10章 中断和输入 /输出程序设计
11) 取得日期 (2AH)
调用后返回日期在 CX∶ DX中。 CX中放年号,为二进制数,DH中放月号,DL中放日号。如果日时钟转到下一天,日期将自动调整,也考虑每月的天数和闰年。不需要入口参数。
第 10章 中断和输入 /输出程序设计
12) 设置时间 (2DH)
时间的格式是四个 8位二进制数,具体地说,CH表示小时
(0~ 23),CL表示分 (0~ 59),DH表示秒 (0~ 59),DL表示百分之一秒 (0~ 99),这个格式可转化为打印 /显示形式。也可用来计算,
比如从一个时间值中减去另一个时间值。调用时,要求
CX∶ DX中存放要求的时间。若此时间是有效的,设置成功,
AL返回 0,若时间的组成部分无效,设置操作取消,AL返回
0FFH。
第 10章 中断和输入 /输出程序设计
13) 取得时间 (2CH)
时间的格式如同 2DH功能调用,不需要入口参数,调用结束时,CX∶ DX中为返回的时间。
第 10章 中断和输入 /输出程序设计例 10-12 执行下述程序段:
MOV AH,2DH
MOV CX,5FH
MOV DX,900H
INT 21H
将把系统时间设置为 5点 15分 9秒。执行下述程序段:
MOV AH,2CH
INT 21H
将在 CX∶ DX中得到时间的二进制值。
第 10章 中断和输入 /输出程序设计
10.3.3 应用举例例 10-13 将内存中 BUF单元开始的一个字符串 (长度为 10个字节 )送 CRT显示,并回车换行。
将一个字符串送 CRT显示,使用 DOS的 9号系统功能调用最为方便。 9号系统功能调用要求两个入口参数,一是要求 DX中为字符串首字符的偏移地址,二是要求字符串必须以,$”字符结尾,回车符、换行符的 ASCII码分别是 0DH和 0AH。
第 10章 中断和输入 /输出程序设计编程如下:
DATA SEGMENT
BUF DB 'This is my first program!'
DATA ENDS
CSEG SEGMENT 'CODE'
ASSUME CS∶ CSEG,DS∶ DATA
START,MOV AX,DATA
MOV DS,AX
LEA BX,BUF
MOV AX,0D0AH ;回车换行符的 ASCII码送 AX
第 10章 中断和输入 /输出程序设计
MOV [BX+10],AX ;字符串后加换行、回车符
MOV BYTE PTR [BX+12],'$' ;串尾加结尾符
MOV DX,BX ;字符串首地址送 DX
CALL LIST_1 ;显示字符串
MOV AH,4CH
INT 21H ;返回 DOS
CSEG ENDS
END START
CODE SEGMENT
ASSUME CS∶ CODE
第 10章 中断和输入 /输出程序设计
LIST_1 PROC FAR
PUSH AX ;保护 AX
MOV AH,09H
INT 21H ;调用 9号功能
POP AX ;取回 AX
RET ;返回
LIST_1 ENDP
CODE ENDS
第 10章 中断和输入 /输出程序设计例 10-14 利用 DOS功能调用,模拟实现登录网络时口令的输入。
接收用户的保密口令或其他特殊信息意味着从标准输入设备上读一个字符串,但不在输出设备上显示。具体实现方法是,
从键盘输入最多 8个字符的口令 (不显示 ),送入存储器中,并将口令串的开始地址送 BX保存,然后返回。
利用 DOS的 8号系统功能调用可实现读一个字符不回显的功能。该功能调用从标准输入设备上接收一个 ASCII字符,并送
AL寄存器。程序描述如下:
第 10章 中断和输入 /输出程序设计
DATA SEGMENT PARA PUBLIC 'DATA'
PROMPT DB 'P1ease enter your Password,$'
BUFFER DB 8 DUP(?) ;存放口令
DATA ENDS
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS,CSEG,DS,DATA
PASSWORD PROC FAR
START,PUSH DX ;保存寄存器
PUSH CX
PUSH AX
LEA DX,PROMPT ;给出提示第 10章 中断和输入 /输出程序设计
CALL LIST_1
MOV CX,8 ;输入 8个字符
LEA BX,BUFFER ;口令字符串存放处
NEXTKEY,CALL GETCHR ;读入下一键
CMP AL,0DH ;是回车?
JE LEAVE ;是的,转 LEAVE
MOV [BX],AL ;不是,存字符
INC BX ;并指向下一位置
LOOP NEXTKEY ;取另一键
LEAVE,LEA BX,BUFFER ;口令串地址送 BX
第 10章 中断和输入 /输出程序设计
POP AX ;恢复寄存器
POP CX
POP DX
RET ;返回调用程序
PASSWORD ENDP
CSEG ENDS
END START
PUBLIC GETCHR
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS,CSEG
第 10章 中断和输入 /输出程序设计
GETCHR PROC FAR
PUSH CX
MOV CH,AH
MOV AH,8H
INT 21H
MOV AH,CH
POP CX
RET
GETCHR ENDP
CSEG ENDS
第 10章 中断和输入 /输出程序设计如果输入,Ctrl-C”字符,DOS则产生 23H号中断。为避免产生这种情况,用户可用 7号系统功能调用替换 8号系统功能调用,即把子程序中的指令 MOV AH,08H改成 MOV AH,07H。
另外,子程序需等待键盘上有键输入后才返回调用程序,而很多情况下需要当键盘上有键输入时就读入,否则返回调用程序,
即并不等待键盘输入。为此,该子程序就需将 INT 21H指令前的 MOV AH,08H修改成下列形式:
MOV AH,06H
MOV DL,0FFH
子程序 LIST_1为例 10-13中的子程序 LIST_1。
第 10章 中断和输入 /输出程序设计例 10-15 编程清除屏幕并使光标回到左上角的位置。
要解决以上的问题,首先使用软中断 INT 10H的 15号子功能读取屏幕的现行状态,再使用 0号子功能以同样的模式设置显示方式。这样不仅完成了清屏功能,而且不改变屏幕的显示模式。程序描述如下:
第 10章 中断和输入 /输出程序设计
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS∶ CSEG
CLEARS PROC FAR
START,PUSH AX
PUSH BX
MOV AH,15
INT 10H
MOV AH,0
INT 10H
POP BX
POP AX
RET
CLEARS ENDP
CSEG ENDS
END START
第 10章 中断和输入 /输出程序设计
10.4 BIOS中断调用
10.4.1 BIOS概述
BIOS(Basic Input/Output System)是驻留在 ROM中的程序,提供了系统加电自检,引导装入以及对主要 I/O接口的控制等功能。对 I/O接口的控制主要是对键盘、磁带、磁盘、显示器、打印机、异步串行通信接口等的控制,提供了最基本的系统硬件与软件间的接口。 BIOS在汇编语言一级上向用户或操作系统提供微机所带的一些主要外设的设备控制功能,包括开机自检,显示器、键盘和打印机的字符传送,图形发生等,主要是 I/O设备的处理程序和许多常用例行程序,以中断处理程序的形式存在。这些操作均不需要用户考虑外设的
I/O地址等细节。例如,负责显示输出的显示 I/O中断为 10H号中断,负责打印输出的打印 I/O程序为 17H中断等等。在 BIOS功能调用中,应重点掌握 10H、
16H,17H和 1AH四种类型的功能调用。
第 10章 中断和输入 /输出程序设计主要的 BIOS中断类型有以下 5种。
1) CPU中断类型
0 除法错; 1 单步; 2 非屏蔽中断; 3 断点;
4 溢出; 5 打印屏幕; 6 保留; 7 保留。
2) 8259中断类型
8 8254系统定时器; 9 键盘; A 保留; B 保留 (通信 );
C 保留 (通信 ); D 保留 (打印机 ); E 软盘; F 打印机。
第 10章 中断和输入 /输出程序设计
3) BIOS 中断类型
10 显示器; 11 设备检验; 12 内存大小; 13 磁盘; 14 通信;
15 I/O系统扩充; 16 键盘; 17 打印机; 18 驻留 BASIC;
19 引导; 1A 时钟; 40 软盘。
4) 用户应用程序
1B 键盘 Break; 1C 定时器; 4A 报警。
5) 数据表指针
1D 显示器参量; 1E 软盘参量; 1F 图形字符扩充; 41 1#硬盘参量;
46 2#硬盘参量。
第 10章 中断和输入 /输出程序设计
10.4.2 BIOS中断调用方法用户在自己编制的程序中,可以调用 BIOS提供的这些设备驱动子程序,就像调用用户自己编的子程序一样。调用 BIOS各子程序的方法是利用中断指令 INT,先按调用类型要求设置入口参数,再通过带有类型号的软中断指令进行功能调用。 CPU
响应中断后就把控制权交给所调用的 BIOS的子程序,由它提供中断服务。
第 10章 中断和输入 /输出程序设计
BIOS调用的基本步骤是:
(1) 置入口参数;
(2) 使用中断语句 INT n,其中 n为中断号。
例 10-16
MOV AH,0 ;功能号为 0
INT 1AH ; 1AH为 BIOS中断号,功能为读时间计数器的值第 10章 中断和输入 /输出程序设计
10.4.3 BIOS中断调用与 DOS功能调用的比较
BIOS中断程序处于 DOS功能调用和硬件环境之间,和
DOS功能调用相比其优点是效率高,缺点是编程相对复杂;和直接对硬件编程相比,优点是实现相对容易,缺点是效率相对较低。
第 10章 中断和输入 /输出程序设计在一些情况下既能选择 DOS中断也能选择 BIOS中断来执行同样的功能。例如,打印机输出一个字符的功能,可用 DOS
中断 21H的功能 5,也可用 BIOS中断 17H的功能 0。因为 BIOS比
DOS更靠近硬件。一般情况下,尽可能地使用 DOS功能,但在少数情况下必须使用 BIOS功能。例如,BIOS中断 17H的功能 2
为读打印机状态,DOS就没有等效的功能。因此,对 BIOS和
DOS调用的选择原则是,无法使用 DOS功能调用或 DOS没有提供而 BIOS提供了功能的情况下可以考虑使用 BIOS中断。
第 10章 中断和输入 /输出程序设计例 10-17 根据显示输出不同的内容,对显示器的使用通常需要变换显示模式。这时,可使用 BIOS所提供的视频显示 I/O
驱动程序来设置屏幕的显示模式。屏幕显示方式的设置使用软中断 INT 10H功能来实现,若需设置屏幕显示模式为黑白字符方式,应使用 INT 10H的 0号子功能。
0—— 40× 25 黑白字符方式
1—— 40× 25 彩色字符方式
2—— 80× 25 黑白字符方式
3—— 80× 25 彩色字符方式
4—— 320× 200 彩色图形方式 (4种颜色 )
第 10章 中断和输入 /输出程序设计
5—— 320× 200 黑白图形方式
6—— 640× 200 黑白图形方式
7—— 720× 350 单色字符方式 (与单色适配器兼容 )
8~ 0CH—— 保留
0DH—— 320× 200 彩色图形方式 (16种颜色 )
0EH—— 640× 200 彩色图形方式 (16种颜色 )
0FH—— 640× 350 单色图形方式
10H—— 640× 350 彩色图形方式 (EGA卡 )。显存为 64 KB时 4种颜色;
显存大于 64 KB时 16种颜色
11H—— 640× 480 单色图形方式 (仅 VGA)
12H—— 640× 480 16色图形方式 (仅 VGA)
13H—— 320× 200 256色图形方式 (仅 VGA)
第 10章 中断和输入 /输出程序设计输入参数,AH中为显示方式码,编制的程序描述如下:
CSEG SEGMENT PARA PUBLIC 'CODE'
ASSUME CS∶ CSEG
SETSMODE PROC FAR
START,PUSH AX
MOV AH,0
INT 10H
POP AX
RET
SETSMODE ENDP
CSEG ENDS
END START
第 10章 中断和输入 /输出程序设计
10.5 输入 /输出程序设计
10.5.1 程序直接控制方式
1.直接输入 /输出方式直接输入 /输出方式,也称无条件传送方式或称同步方式。
这种传送方式使用较少,只有在外部控制过程的各个动作时间是固定的,且是已知的条件下才能够应用。它不考虑外设的状态,输入时,就只给出 IN指令。输出时,也只给出 OUT指令,
这种传送方式的优点是程序编写容易,硬件电路简单,调试方便。
第 10章 中断和输入 /输出程序设计例 10-18 一个无条件传送的例子如图 10-4所示。图中 10H、
11H,20H是来自地址总线的端口地址信号。要求编程完成采集不同的模拟量。
图 10-4 无条件传送举例缓冲寄存器功率放大器
P7 … P1 P0
2 0 H
2 0 H 端口写选通
1 1 H 端口读选通
8 位
1 1 H
8 位
1 0 H
1 0 H 端口读选通
C PU
K7

K1 K0
输入数据( 模拟量)
控制总线 CB
地址总线 AB
数据总线 DB
第 10章 中断和输入 /输出程序设计这是一个同步的数据采集系统。被采样的数据是八个模拟量,由继电器绕组 P0,P1,P2,…,P7控制触点 K0,K1、
K2,…,K7逐个接通,用一个四位 (十进制数 )数字电压表测量,
把被采样的模拟量转换成十六位 BCD代码,高八位和低八位通过两个不同的端口输入。它们的地址分别为 10H和 11H。 CPU
通过端口 20H输出控制信号,以控制继电器的吸合,从而实现采集不同的模拟量。数据采集过程可用下列程序实现:
第 10章 中断和输入 /输出程序设计
START,MOV DX,0100H ; 01→DH,设置合第一个继电器代码; 00→DL,设置断开所有继电器代码
LEA BX,DSIOK ;输入数据缓冲区的地址偏移量 → BX
XOR AL ;清 AL及进位标志
AGAIN,MOV AL,DI
OUT 20H,AL ;断开所有继电器线圈
CALL NEAR DELAY1 ;模拟继电器触点的释放时间
MOV AL,DH
OUT 20H,AL ;使 P0吸合第 10章 中断和输入 /输出程序设计
CALL NEAR DELAY2 ;模拟触点闭合及数字电压表的转换时间
IN AX,10H ;输入
MOV [BX],AX
INC BX
INC BX
RCL DH,1 ; DH左移一位,为下一个触点闭合作准备
JNC AGAIN ; 8个模拟量未输入完,循环此段程序第 10章 中断和输入 /输出程序设计
2.查询输入 /输出方式查询输入 /输出方式,也称条件传送方式或称异步方式。当
CPU与外部操作同步时,采用无条件传送是很方便的。但如果两者不同步时,就很难确保其正确性。为解决这个问题,可以采用查询输入 /输出方式。在传送数据前,先去查询一下外设的状态,
当外设准备好以后再进行传送。这样就要求 CPU与外设之间的接口部分除了传送数据的端口以外,还必须设置传送状态信号的端口。端口数据一般是 8位 (或 16位 )的,而状态信息往往是一位的。
这样,不同的外设状态信息可以使用同一端口,只要使用不同的位就可以了,查询输入 /输出方式解决了高速 CPU与慢速外设之间传送数据的问题,并能够保证传送的正确性。
综上,可得到查询输入 /输出方式的工作过程如下所述。
第 10章 中断和输入 /输出程序设计
1) 查询输入工作过程当输入装置的数据已准备好后应发一个信号给 CPU,送出要传送数据的同时给出“准备好” (Ready)信号。数据与状态是由不同的端口输入至 CPU数据总线。当 CPU要由外设输入信息时,CPU先输入状态信息,检查数据是否已准备好,当数据已经准备好后,才输入数据,读入数据的命令,使状态信息清
,0”。读入的数据是 8位的;而读入的状态信息往往是一位的
(比如用 D7位 ),如图 10-5所示。所以,不同外设的状态信息,
可以使用同一个端口的不同位。这种查询输入方式的程序流程图如图 10-6所示。
第 10章 中断和输入 /输出程序设计图 10-5 查询式输入的数据和状态信息数据端口( 8 位)
( 输入)
状态端口( 1 位)
( 输入)
,R E A D Y”( 1 位)
第 10章 中断和输入 /输出程序设计图 10-6 查询式输入程序流程图输入状态信息
Y
R E A D Y?
N
输入数据第 10章 中断和输入 /输出程序设计工作过程描述如下:
① 从状态端口读入状态信息;
② 测试 Ready位是否为 1,若不为 1则转①操作,循环等待;
③ 从数据端口读入数据到 AX寄存器。
POLL,IN AL,STATUS_PORT ;从状态端口输入状态信息
TEST AL,80H ;检查 READY是否是 1
JE POLL ;未准备好,循环
IN AL,AATA_PORT ;准备好,从数据端口输入数据这种 CPU与外设之间状态信息的交换方式,称为应答式,
状态信息称为“联络” (HandShake)信息。
第 10章 中断和输入 /输出程序设计
2) 查询输出工作过程在输出时 CPU必须了解外设的状态,看外设是否为空 (即外设若不处在输出状态,或外设的数据寄存器是空的就可以接收
CPU输出的信息 )。若为空,则 CPU执行输出指令;否则就等待。
输出接口电路的端口信息可设置为:数据端口 8位、状态信息一位。如图 10-7所示。查询式输出的程序流程图如图 10-8所示。
第 10章 中断和输入 /输出程序设计图 10-7 查询式输出的端口信息数据端口( 8 位)
( 输出)
状态端口( 1 位)
( 输入)
,B U S Y”( 1 位)
第 10章 中断和输入 /输出程序设计图 10-8 查询式输出程序流程图输入状态信息
N
B U S Y?
Y
输出数据准备输出数据第 10章 中断和输入 /输出程序设计工作过程描述如下:
(1) 从状态端口读入状态信息;
(2) 检查 BUSY位,若为 1,则转 (1)操作,否则继续;
(3) 从缓冲区取数据输出。
第 10章 中断和输入 /输出程序设计查询部分的程序为:
POLL,IN AL,STATUS_PORT ;从状态端口输入状态信息
TEST AL,80H ;检查 BUSY位
JNE POLL ; BUSY则循环等待
MOV AL,STORE ;否则从缓冲区取数据
OUT DATA_PORT,AL ;从数据端口输出其中,STATUS_PORT是状态端口的符号地址; DATA_PORT
是数据端口的符号地址; STORE是内存数据单元的地址。
查询方式存在的不足是,降低了 CPU的使用效率,造成了硬件资源的浪费。
第 10章 中断和输入 /输出程序设计
3.举例例 10-19 一个有 8个模拟量输入的数据采集系统如图 10-9所示。要求使用查询方式与 CPU交换信息。
8个模拟量,经过多路开关选通后送入 A/D转换器,多路开关由端口 4输出的 3位二进制码 (对应于 D0,D1,D2位 )控制。
000相应于选通 A0输入,001相应于选通 A1输入,002相应于选通 A2输入,……,以此类推,111相应于选通 A7输入。每次只送出一个模拟量至 A/D转换器,同时由端口 4输出的 D4位控制
A/D转换器的启动与停止。 A/D转换器的 READY信号由端口 2的
D0送至 CPU数据总线,经 A/D转换后的数据由端口 3送至数据总线。因此,这样的一个数据采集系统,需要用到 3个端口,它们有各自的端口地址。
第 10章 中断和输入 /输出程序设计图 10-9 查询式数据采集系统
A / D 转换
23
数据端口读选通
C P U
数据
8 位数据
R E A D Y
状态端口读选通
4
启动
D4 D2 D1 D0
多路开关
1 个模拟量控制端口写 选 通
A0
A7

8 个输 入模拟量数据总线 DB
1 位状态第 10章 中断和输入 /输出程序设计程序描述如下:
START,MOV DL,0F8H ;设置启动 A/D转换的信号
MOV DI,OFFSET DSTOR ;输入数据缓冲区的地址偏移量 → DI
AGAIN,MOV AL,DL
AND AL,0EFH ; D4= 0
OUT 4,A ;停止 A/D转换
CALL DELAY ;等待停止 A/D操作的完成
MOV AL,DL
OUT 4,AL ;启动 A/D,且选择模拟量 A0
第 10章 中断和输入 /输出程序设计
POLL,IN AL,2 ;输入状态信息
SHR AL,1
JNC POLL ;若未 READY,程序循环等待
IN AL,3 ;否则,输入数据
STOSB ;送至内存
INC DL ;修改多路开关控制信号,指向下一个模拟量
JNE AGAIN ; 8个模拟量末输入完,循环已完,;执行别的程序段第 10章 中断和输入 /输出程序设计例 10-20 编程使用查询方式实现将寄存器 AL中的字符送打印机输出。打印机数据端口地址为 378H、状态端口地址为 379H、
控制端口地址为 37AH。
用查询方式输出字符到打印机的编程步骤:
(1) 需输出字符送打印机数据端口;
(2) 查询打印机状态端口。若忙则等待,否则,执行第 (3)步;
(3) 选通字送打印机控制端口,将数据端口的内容送至打印机输出。
第 10章 中断和输入 /输出程序设计程序描述如下:
PRINTPROC NEAR
PUSH AX
PUSH DX ;保护所用寄存器内容;以下程序段实现输出数据的功能
MOV DX,378H ;数据端口地址 378H
OUT DX,AL ;输出要打印的字符;以下程序段实现检查打印机状态的功能
MOV DX,379H ;状态端口地址 379H
第 10章 中断和输入 /输出程序设计
WAT,IN AL,DX ;读打印机状态
TEST AL,80H ;检查“忙”位
JE WAT;以下程序段实现选通打印机的功能
MOV DX,37AH ;控制端口地址 37AH
MOV AL,0DH ;选通位= 1(D0位 )
OUT DX,AL ;选通打印机
MOV AL,0CH ;选通位= 0(D0位 )
OUT DX,AL ;关打印机选通
POP DX ;恢复寄存器内容
RET
PRINT ENDP
第 10章 中断和输入 /输出程序设计例 10-21 从终端输入字符,保存在一个 64字节的数组
BUFFER中,当输入一个回车符或字符多于 62时,输入结束。
如果输入的前 63个字符没有发现回车符,则从终端输出信息
,BUFFER OVERFLOW”,否则自动在回车符后填入一个换行符。输入字节的第七位为偶校验位,如果发生偶校验错,转向出错处理程序 ERROR,如无校验错,则将字节的校验位清 0后送 BUFFER。
第 10章 中断和输入 /输出程序设计假设终端接口的数据输入寄存器的端口地址是 0052H,
数据输出寄存器是 0053H,状态寄存器是 0054H,其中第 D1位为 1表示输入寄存器数据准备好,D0位为 1表示输出寄存器是空闲的。这是一个包括输入和输出两种操作的综合问题,数据输入和输出寄存器的端口地址不同,而状态端口共用一个,
用不同的位来指示状态。无论输入还是输出操作都必须先测试状态字。
第 10章 中断和输入 /输出程序设计程序如下:
SSEG SEGMENT STACK 'STACK'
STR DB 100 DUP(?)
SSEG ENDS
DSEG SEGMENT 'DATA'
COUNT DB 63
BUFFER DB 64 DUP(0)
WORDST DB BUFFER OVERFLOW'
ERROR DW?
DSEG ENDS
CSEG SEGMENT 'CODE'
ASSUME CS∶ CSEG,DS∶ DSEG
第 10章 中断和输入 /输出程序设计
START,MOV AX,DSEG
MOV DS,AX
MOV CX,COUNT
LEA BX,BUFFER
LIN,MOV DX,0054H
IN AL,DX ;读取状态字
TEST AL,02H ;测试 D1位
JNE LIN ;未准备好,转 LIN
MOV DX,0052H
IN AL,DX ;准备好,读入一个字符
AND AL,AL ;偶校验判断
JMP ERROR ;偶校验错,则转 ERROR
第 10章 中断和输入 /输出程序设计
AND AL,7FH ;校验正确,清 D7位
MOV [BX],AL ;存入缓冲区
CMP AL,0DH ;判是否回车符
INC BX
JNE BX,NEXT ;不是回车符,则转 NEXT
MOV [BX],0AH ;是回车符,填入换行符
JMP DONE ;转结束
NEXT,LOOP LP ;不够 63个字符,则继续输入
LOUT,MOV CX,15
LEA BX,WORDTS ;超过 62个字符,输出字符串第 10章 中断和输入 /输出程序设计
LOUT1,MOV DX,0054H ; BUFFER OVERFLOW
IN AL,DX
TEST AL,01H
JNE LOUT1
MOV DX,0053H
MOV AL,[BX]
OUT DX,AL
INC BX
LOOP LOUT1
DONE,MOV AH,4CH
INT 21H
ERROR:
CSEG ENDS
END START
第 10章 中断和输入 /输出程序设计
10.5.2 程序中断方式
1.中断传送方式的工作过程中断传送方式是 CPU与外设之间传送信息的重要方式之一。
它提高了 CPU的使用效率,并允许 CPU同时与多个外设之间进行数据交换,即在一段特定时间与某一个外设进行信息交换。
当外设需要和 CPU进行数据交换时,发出一个中断信号。 CPU
在一条指令执行完成后扫描一遍中断源。若有中断请求,转去执行与外设进行数据交换的中断服务程序。中断服务程序处理完后,外设启动,CPU恢复中断现场,CPU与外设开始并行工作。利用中断方式进行 CPU和外设之间进行数据传送,减少了
CPU的查询等待时间,提高了工作效率。
第 10章 中断和输入 /输出程序设计
2.举例例 10-22 编程完成一个打字机输出功能。利用中断方式,
自设定一个中断服务子程序,类型为 70H。设打字机数据端口地址为 378H;状态端口地址为 379H,状态为第 7位,为 1时忙;
控制端口地址为 37AH。
在例 10-20中,是采用程序查询方式解决此问题的,同样的问题,也可以用中断方式来解决。根据题目要求,可在主程序中设定子程序的入口,并将中断矢量送入中断矢量表,然后使用 INT 70H中断指令进中断处理子程序,在子程序中判断、输出字符。
第 10章 中断和输入 /输出程序设计程序描述如下:
SSEG SEGMENT STACK
SDW DW 100H DUP(?)
SSEG ENDS
CSEG SEGMENT 'CODE'
ASSUME CS∶ CSEG,SS∶ SSEG
PRINT0 PROC FAR
STI
PUSH ES
PUSH DI
PUSH DS
PUSH DX
第 10章 中断和输入 /输出程序设计
PUSH CX
PUSH BX
PUSH AX
MOV DX,378H
OUT DX,AL ;输出字符
INC DX
SUB BX,BX
WAIT,IN AL,DX ;读状态
TEST AL,80H ;判忙 /闲
JNZ ALL ;闲
JMP WAIT
第 10章 中断和输入 /输出程序设计
ALL,MOV AL,0DH
INC DX ;形成控制端口地址
OUT DX,AL ;置选通位
MOV AL,0CH
OUT DX,AL ;清选通位
POP AX
POP BX
POP CX
POP DX
POP DS
POP DI
POP ES
IRET
第 10章 中断和输入 /输出程序设计
PRINT0 ENDP
MAIN,MOV AX,SSEG
MOV SS,AX
CLD
MOV AX,0
MOV ES,AX
MOV DI,4*70H
MOV AX,OFFSET PRINT0
STOSW
第 10章 中断和输入 /输出程序设计
MOV AX,SEG PRINT0
STOSW
MOV AL,'A'
INT 70H
MOV AH,4CH
INT 21H
CSEG ENDS
END MAIN
第 10章 中断和输入 /输出程序设计
10.5.3 直接存储器存取 (DMA)方式直接存储器存取 (DMA)方式是数据输入 /输出的一种。这种传送方式不通过 CPU,而是由 DMA控制器来管理内存与外设之间的数据交换。 DMA方式的突出优点是速度快,特别适用于高速外设的成批数据传送。
第 10章 中断和输入 /输出程序设计
1,DMA方式的引入中断传送方式从根本上改变了程序查询方式所存在的问题,保证了对外设的快速响应。在中断方式下,每传送一个数据 (如一个字节或一个字 )都需要有中断请求、中断响应与中断处理,CPU完成保护现场、交换数据、恢复现场等工作过程,这些对设备的服务是由软件完成的,对需要高速存取的外部设备 (例如磁盘 )来说,仍显得速度不够快,不能完全满足高速块设备的传送需要。诸如磁盘类的块存取设备不仅数据传输率很高,而且当它们与 CPU进行数据交换时往往是成批进行的。
第 10章 中断和输入 /输出程序设计为此,可采用 DMA的方式。 DMA方式的基本思想是在主存储器与 I/O设备间直接进行批量数据的直接高速交换,通过硬件控制实现主存与 I/O设备间的直接数据传送,在传送过程中无需 CPU程序干预。目前,微机中广泛使用的 DMA方式就是采用一种专用硬件来完成外部设备和存储器之间的高速数据传送,
这种专用硬件被称为直接存储器存取控制器 DMAC。
第 10章 中断和输入 /输出程序设计
2.直接存储器存取控制器 DMAC
DMAC具有独立访问存储器的能力,它可以提供内存地址和必要的读写控制信号,提供外设与存储器之间直接交换信息的通路,而不必像程序查询或中断传送方式那样需要通过 CPU
用 I/O指令交换。但是由于 DMAC与 CPU共享系统总线,通常系统总线由 CPU控制,因此当需要以 DMA方式传送数据、由
DMAC掌管系统总线时,DMAC需要产生一个请求信号,要求
CPU暂停工作让出系统总线,交由 DMAC控制总线完成数据传送。只有编程对 DMAC进行了初始化,才可进入 DMA方式。
DMAC在数据传送期间,CPU可以继续进行其他不需要总线的操作。
第 10章 中断和输入 /输出程序设计
3,DMA方式在执行一次 DMA传送时,CPU放弃对系统总线的控制,它对数据、地址、控制总线的输出端均呈高阻态。这时,系统总线由 DMA控制器进行控制,占用一个或几个 CPU外部访问周期,
完成一次 DMA操作,即“周期窃取方式”。
1) DMA方式的特点
(1) 以“周期窃取”方式暂停 CPU对系统总线的控制,在
I/O设备与主存之间直接传送数据,占用时间很少;
第 10章 中断和输入 /输出程序设计
(2) 传送时,源与目的地址均直接由硬件逻辑指定;
(3) 主存中需要开辟相应的数据缓冲区,指定数据块长,计数由硬件完成;
(4) 在一批数据传送结束后,一般通过中断方式通知 CPU进行后处理;
(5) CPU与 I/O设备可并行工作,用于高速、批量数据的简单传送。
通过以上讨论可以看出,DMA方式数据传送的绝大部分工作由 DMAC硬件自动完成,编程人员需要做的工作只是对
DMAC进行初始化等少量事情。
第 10章 中断和输入 /输出程序设计
2) DMA工作过程
(1) 初始化:完成各种程序准备。例如,准备数据,数据缓冲区等等。
(2) DMA请求:当接口准备好输入数据或已做好从主存接收新数据的准备时,接口通过有关逻辑向 DMA发出请求信号。
(3) DMA响应,CPU接收到 DMA请求,在当前总线周期操作结束后,暂停对系统总线的控制,发出 DMA应答信号,并将总线控制权交 DMA控制器。
第 10章 中断和输入 /输出程序设计
(4) DMA传送,DMA控制器接收到应答信号后,窃取总线控制权,完成一次 DMA传送。传送结束后可暂时清除 DMA请求,接口再次准备发出请求信号。重复进行,完成整个数据传送过程。
(5) 结束处理:传送完数据后,进行数据处理。
第 10章 中断和输入 /输出程序设计
10.5.4 通道传输方式通道是一种专用控制器,主要通过执行通道程序进行 I/O
操作的管理,为主机与 I/O设备提供一种数据传输通道,故称通道方式。通道有自己的通道指令,利用这些通道指令可以编制通道程序,存放在存储器中。当需要进行 I/O操作时,CPU
按约定格式准备好命令和数据,然后启动通道。通道启动后执行相应程序,完成数据传送。,
第 10章 中断和输入 /输出程序设计有了通道,I/O设备就可以连接在通道上,用通道来控制外设和内存间的信息传送。通道本身就是处理机,可以执行通道程序。通道减轻了 CPU与输入 /输出设备直接通信的负担,并且
CPU的计算工作可以与输入 /输出工作并行进行,不必因等待外设完成输入 /输出操作而浪费时间。
通道有 3种类型:字节多路通道、成组多路通道和选择通道,用以实现同时执行几项 I/O操作。
第 10章 中断和输入 /输出程序设计
I/O设备有两种工作方式:成批交换及字节交换,
选择通道只有一个子通道,并且在每一时刻只可以有一台 I/O设备传送信息,I/O设备总是以成批方式交换信息。这些通常用于高速外设,如磁盘,磁带等。
多路通道就是在其中接有若干子通道 (能独立执行一个 I/O
操作的通道 ),每一子通道接一台 I/O设备。它可以使多台设备并行工作。多路通道又分为字节多路通道和成组多路通道两种。
接在成组多路通道上的 I/O设备总是以成批交换方式工作的。
第 10章 中断和输入 /输出程序设计字节多路通道,能以字节和成批方式进行数据传送。在字节交换方式时,若干 I/O设备可以在各自独立的子通道上并行工作。在成批交换方式时,通道上只有一个 I/O设备可以传送数据。
从输入 /输出程序设计的要求来看,还应知道 CPU、通道及外设是如何协调一致地进行 I/O操作的。它们工作的大致过程是:
(1) 编制通道执行程序,称为通道程序。
第 10章 中断和输入 /输出程序设计
(2) CPU与通道约定一个存储单元,存放通道程序的起始地址,称为通道地址字 (CAW)。
(3) CPU执行输出指令,启动通道去执行通道地址字指示的通道程序,此时通道和 CPU可以并行操作。
(4) 通道通过中断系统向 CPU发出中断请求,并将通道执行通道程序的状态存放在通道状 态字 (CSW)单元中,供 CPU分析。
第 10章 中断和输入 /输出程序设计习 题 十
10.1 如果某计算机系统需新增加一个中断源,在软件方面,
举例说明应该做哪几项工作才能使此中断源投入运行。
10.2 利用 1AH中断调用,编程实现产生 5秒延时功能的程序。
10.3 利用 21H和 1AH中断调用,编写实现在屏幕上显示 1~ 9
之间的随机数功能的程序。
10.4 编写从 COM1口输入一串字符到 BUFFER缓冲区的程序。
10.5 编写实现在循环输出 256个 ASCII字符时,使计算机每隔
10秒钟响铃一次功能的程序。