第六章 输入/输出方法
输入输出是指计算机主机与外部设备之间进行的数据交换。计算机主机部分与外部设备之间有大量的信息需要传送,比如数据、程序、现场采集的信号等信息需要通过输入设备输入至计算机中给CPU处理,同时CPU处理的结果和各种控制信号需要通过输出设备输出,以实现显示或各种控制动作。
键盘和显示器就是最常用的输入和输出设备。前面章节讲述了如何通过DOS功能调用实现输入输出,并且输入输出操作都是以INT 21H的形式调用操作系统预先存放在内存中的程序段实现的。采用这种方式,不需要考虑处理细节和输入输出设备的硬件结构,只要掌握DOS功能调用的入口参数和出口参数及调用方法即可。但是仅仅会调用系统已有的标准子程序是不够的,要想充分发挥汇编语言可直接控制硬件的优势,还必须学会直接通过输入输出方法与外部设备进行数据交换。
6.1 输入/输出概述
每种输入输出设备都要通过一个硬件接口或控制器与主机连接。例如,打印机通过打印接口与主机相连,显示器通过显示控制器与主机相连。而从程序设计的角度看,接口可以看成是由一组寄存器组成的,通过这些寄存器,输入输出设备接收由主机传送的数据或命令,同时将一些数据或外设的各种状态传送给主机,由主机进一步的处理。因此,输入输出方法实际上是利用一组I/O命令对接口上的寄存器进行存取,从而使主机获得外设的状态信息并控制外设的各种活动,最终实现信息的输入和输出。
6.1.1 输入/输出端口地址
为了访问接口上的寄存器,系统给这些寄存器分配了专门的存取地址,这样的地址称为I/O端口地址。
端口的编址方式有两种:I/O端口与内存统一编址方式以及I/O端口独立编址方式。 1. 统一编址方式
统一编址方式指的是赋予I/O端口地址和内存单元的地址为一系列连续编码,这相当于将I/O接口视为一个或几个存储单元,访问接口上的寄存器与访问存储单元无任何区别。这种编码方式的优点是访问端口无须特殊的指令,所以指令既可以是访问端口又可以访问存储器,而具体是访问端口还是存储器就靠指令中给出的地址是属于端口地址还是属于存储单元地址。这种编址方式的缺点是端口占用了存储器空间,使存储区域减少。统一编址方式如图6-1(a)所示。
2. 独立编址方式
在以INTEL 80X86家族处理器系统中,均采用独立编址。独立编址方式指的是I/O端口地址和存储器地址是各自独立的,虽然地址编码可能重复,但是属于两个不同的地址空间。独立编址方式下,为了区分I/O端口地址和存储器地址,系统规定,当访问I/O端口时,必须使用专用I/O指令进行操作。独立编址方式如图6-1(b)所示。
图6-1 编址方式
对于8086/8088系统,I/O端口地址区域为0000H~0FFFFH,因此8086/8088系统提供的I/O端口地址空间达64K,可接64K个8位端口,或者32K个16位端口。PC机部分端口地址见表6-1。
表6-1 I/O端口地址分配表(十六进制) I/O端口地址 功能 00~0F 20~3F 40~5F 60~63 70~71 81~8F 93~9F A0~A1 C0~CE F0~FF 170~1F7 200~20F 278~27A 2E0~2E3
DMA控制器8237A 可编程中断控制器8259A 可编程中断计时器 8255A PPI CMOS RAM DMA页面地址寄存器 DMA控制器 可编程中断控制器2 协处理器 硬盘控制器 游戏控制端口 3号并行口(LPT2) EGA/VGA使用 I/O端口地址 功能 2F8~2FE 320~324 366~36F 372~377 378~37A 380~38F 390~393 3A0~3AF 3BC~3BE 3C0~3CF 3D0~3D7 3F0~3F7 3F8~3FE 2号串口(COM2) 硬盘适配器 PC网络 软盘适配器 2号并行口(打印口) SDLC及BSC通信 Cluster适配器 BSC通信 MDA视频寄存器 1号并行口 EGA/VGA视频寄存器 CGA视频寄存器 软盘控制寄存器 1号串行口(COM1) DMA通道,内存/传输地址寄存器 3B0~3BF 6.1.2 I/O指令
由于I/O端口采用独立编址方式,因此8086对I/O端口的访问必须采用专门的I/O指令,其他指令对外设的访问均为无效。
1. 输入指令IN
指令格式:IN 累加器 ,端口地址
功能:从一个端口读取一个字节或一个字,传送至累加器AL或AX。
说明:端口地址可以采用直接方式表示,也可以采用间接方式表示。当采用直接方式表示端口地址时,IN指令中允许出现00H~0FFH 范围内的端口地址;当采用间接方式表示端口地址时,端口地址0000H~0FFFFH必须事先存放到DX寄存器中,然后使DX作为源操
作数出现。
输入指令IN有以下四种形式:
IN AL,PORT ;端口字节内容送AL IN AX,PORT ;端口字内容送AX IN AL,DX ;AL←(DX) IN AX,DX ;AL←(DX),AH←(DX+1) 注意:
(1)输入指令的目的寄存器只能为累加器AL或AX,不允许为其他的通用寄存器。 (2)端口地址如果超过0FFH,则必须采用间接方式,并且端口地址只允许送入DX。 (3)当从端口n输入一个字时,相当于从端口n和n+1分别读取一个字节的内容,其中端口n的内容送AL,端口n+1的内容送AH。
例6-1 编写一个程序,提取端口21H中的数据至AL寄存器。
解:根据题意,使用“IN AL ,21H”指令或“MOV DX,0021H IN AL,DX”指令均可实现。
程序代码编写如下: CSEG SEGMENT ASSUME CS:CSEG START:
IN AL ,21H ; 21H端口字节内容送AL MOV AH,4CH INT 21H CSEG ENDS END START
将以上程序输入完毕后保存为111.ASM文件后,通过MASM程序对其汇编,再通过LINK程序连接成111.exe。输入DEBUG 111.exe命令,使用U命令反汇编后,再输入“G 0004”命令执行该程序。如图6-2所示。
图6-2查看结果
由图6-2可知,AL=18H,即21H端口内容为18H。 在DEBUG命令中,也有一个输入端口内容命令I。 命令格式:I 端口地址
功能:输入端口地址内容并显示。
在以上程序执行完毕后,还可以使用DEBUG命令中的I 21命令查看21H单元内容,结果如图6-3所示。
图6-3 I命令
DEBUG中的I命令可以查看所有的端口地址,即“I 0000”一直到“I FFFF”都为有效命令,但是I命令只能查看端口的字节内容,而无法查看端口的字内容。并且I命令所接的端口地址后面不加H。
例6-2 编写一个程序,将地址为00FFH的字端口内容送于AX寄存器。然后将AX内容保存到BX寄存器中。
解:该题的要求是将00FFH端口内容送AL寄存器,0100H端口内容送AH,为了方便观察结果,所以将AX的内容送到BX寄存器。
程序代码编写如下: CSEG SEGMENT ASSUME CS:CSEG START:
MOV DX,0FFH ;端口地址赋予DX IN AX ,DX ;端口输入 MOV BX,AX ;保存结果 MOV AH,4CH
INT 21H ;返回DOS CSEG ENDS END START
将以上程序输入后保存退出,经过MASM汇编及LINK连接后,输入DEBUG 111.EXE命令,以及使用U命令查看代码后,直接使用G 0008命令执行该程序即可得到结果。如图6-4所示。
图6-4 查看结果
由图6-4可知,端口地址为00FFH的字端口内容为0FFFFH。 2. 输出指令OUT
指令格式:OUT 端口地址,累加器
功能:输出指令将累加器AL或AX的内容输出到指定端口。
说明:与输入指令一样,端口地址可以采用直接方式表示,也可以采用间接方式表示。当采用直接方式表示端口地址时,OUT指令中允许出现00H~0FFH 范围内的端口地址;当采用间接方式表示端口地址时,端口地址0000H~0FFFFH必须事先存放到DX寄存器中,然后使DX作为目的操作数出现。
输出指令OUT有以下四种形式:
OUT PORT,AL ;AL内容送字节端口 OUT PORT,AX ;AX内容送字端口 OUT DX ,AL ;(DX)←AL OUT DX,AX ;(DX)←AL,(DX+1)←AH 注意:
(1)OUT指令中的源操作数只允许使用累加器AX或AL,其他寄存器不允许出现。 (2)端口地址如果超过0FFH,则必须采用间接方式,并且端口地址只允许送入DX。 (3)当向端口n输出一个字时,相当于将AL内容送端口n,AH内容送端口n+1。
6.1.3 数据传送方式
1. 交换信息的性质
CPU与外设之间交换的信息包括数据信息、控制信息和状态信息。尽管这三种信息具有不同的性质,但它们都应采用IN和OUT指令进行输入和输出操作。
数据是CPU和外设真正要交换的信息,可以是8位或16位数据。 控制信息是主机输出至I/O接口的信息,告诉外设要做什么工作。 状态信息是接口反馈给CPU的信息,表示外设的当前状态(闲/忙)。CPU通过对状态端口的查询可以决定后面将要采取的动作。一般在从外设读取数据前,CPU通常要先取得表示外设是否已将数据准备好的状态信息;而在将数据输出到外设前,CPU要先取得外设是否闲的状态信息。
2. 传送方式
系统中各种数据的传送方式主要有四种,即无条件传送方式、查询方式、中断方式和DMA方式。
(1)无条件传送方式
无条件传送方式是指不管外设的工作状态如何,在CPU需要进行传输时就直接进行信息传输。这种方式程序设计比较简单,但要求外设的工作速度与CPU同步,否则就有可能出错。
无条件传送方式一般用于一些简单外设的操作,如开关、切断数码管等。在这种方式下硬件接口电路很简单。一般情况下,输入时需要加缓冲器,输出时需要加锁存器。CPU只要在输入输出指令中指明端口地址,就可以对指定的外设进行输入输出了。
(2)查询方式
查询方式的基本思想是由CPU主动地通过输入输出指令查询外设的当前状态,若设备准备就绪,则与设备进行数据交换;否则循环查询直到设备准备好为止。
当CPU要从输入设备接收数据时,在输入之前要查询外设的数据是否已经准备好,若设备已经准备好数据则立即输入数据。同样,当CPU要输出数据时,在输出之前要先查询外设是否“忙”(即外设是否已处于准备好接收状态),若外设“忙”,则等待直到外设已处于准备好的状态。
查询方式适用于CPU与外设不同步的情况。由上述可知,为了采用查询方式输入或输出,相应的外设接口不仅要有数据端口,而且还要有状态端口,有些外设还必须具有控制端