第六章 输入输出.docx
《第六章 输入输出.docx》由会员分享,可在线阅读,更多相关《第六章 输入输出.docx(26页珍藏版)》请在冰豆网上搜索。
![第六章 输入输出.docx](https://file1.bdocx.com/fileroot1/2023-2/13/049003f4-3e26-4d93-8ab8-e08e93d8c7d5/049003f4-3e26-4d93-8ab8-e08e93d8c7d51.gif)
第六章输入输出
第六章输入/输出方法
输入输出是指计算机主机与外部设备之间进行的数据交换。
计算机主机部分与外部设备之间有大量的信息需要传送,比如数据、程序、现场采集的信号等信息需要通过输入设备输入至计算机中给CPU处理,同时CPU处理的结果和各种控制信号需要通过输出设备输出,以实现显示或各种控制动作。
键盘和显示器就是最常用的输入和输出设备。
前面章节讲述了如何通过DOS功能调用实现输入输出,并且输入输出操作都是以INT21H的形式调用操作系统预先存放在内存中的程序段实现的。
采用这种方式,不需要考虑处理细节和输入输出设备的硬件结构,只要掌握DOS功能调用的入口参数和出口参数及调用方法即可。
但是仅仅会调用系统已有的标准子程序是不够的,要想充分发挥汇编语言可直接控制硬件的优势,还必须学会直接通过输入输出方法与外部设备进行数据交换。
6.1输入/输出概述
每种输入输出设备都要通过一个硬件接口或控制器与主机连接。
例如,打印机通过打印接口与主机相连,显示器通过显示控制器与主机相连。
而从程序设计的角度看,接口可以看成是由一组寄存器组成的,通过这些寄存器,输入输出设备接收由主机传送的数据或命令,同时将一些数据或外设的各种状态传送给主机,由主机进一步的处理。
因此,输入输出方法实际上是利用一组I/O命令对接口上的寄存器进行存取,从而使主机获得外设的状态信息并控制外设的各种活动,最终实现信息的输入和输出。
6.1.1输入/输出端口地址
为了访问接口上的寄存器,系统给这些寄存器分配了专门的存取地址,这样的地址称为I/O端口地址。
端口的编址方式有两种:
I/O端口与内存统一编址方式以及I/O端口独立编址方式。
1.统一编址方式
统一编址方式指的是赋予I/O端口地址和内存单元的地址为一系列连续编码,这相当于将I/O接口视为一个或几个存储单元,访问接口上的寄存器与访问存储单元无任何区别。
这种编码方式的优点是访问端口无须特殊的指令,所以指令既可以是访问端口又可以访问存储器,而具体是访问端口还是存储器就靠指令中给出的地址是属于端口地址还是属于存储单元地址。
这种编址方式的缺点是端口占用了存储器空间,使存储区域减少。
统一编址方式如图6-1(a)所示。
2.独立编址方式
在以INTEL80X86家族处理器系统中,均采用独立编址。
独立编址方式指的是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-1I/O端口地址分配表(十六进制)
I/O端口地址
功能
I/O端口地址
功能
00~0F
DMA控制器8237A
2F8~2FE
2号串口(COM2)
20~3F
可编程中断控制器8259A
320~324
硬盘适配器
40~5F
可编程中断计时器
366~36F
PC网络
60~63
8255APPI
372~377
软盘适配器
70~71
CMOSRAM
378~37A
2号并行口(打印口)
81~8F
DMA页面地址寄存器
380~38F
SDLC及BSC通信
93~9F
DMA控制器
390~393
Cluster适配器
A0~A1
可编程中断控制器2
3A0~3AF
BSC通信
C0~CE
DMA通道,内存/传输地址寄存器
3B0~3BF
MDA视频寄存器
F0~FF
协处理器
3BC~3BE
1号并行口
170~1F7
硬盘控制器
3C0~3CF
EGA/VGA视频寄存器
200~20F
游戏控制端口
3D0~3D7
CGA视频寄存器
278~27A
3号并行口(LPT2)
3F0~3F7
软盘控制寄存器
2E0~2E3
EGA/VGA使用
3F8~3FE
1号串行口(COM1)
6.1.2I/O指令
由于I/O端口采用独立编址方式,因此8086对I/O端口的访问必须采用专门的I/O指令,其他指令对外设的访问均为无效。
1.输入指令IN
指令格式:
IN累加器,端口地址
功能:
从一个端口读取一个字节或一个字,传送至累加器AL或AX。
说明:
端口地址可以采用直接方式表示,也可以采用间接方式表示。
当采用直接方式表示端口地址时,IN指令中允许出现00H~0FFH范围内的端口地址;当采用间接方式表示端口地址时,端口地址0000H~0FFFFH必须事先存放到DX寄存器中,然后使DX作为源操作数出现。
输入指令IN有以下四种形式:
INAL,PORT;端口字节内容送AL
INAX,PORT;端口字内容送AX
INAL,DX;AL←(DX)
INAX,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寄存器。
解:
根据题意,使用“INAL,21H”指令或“MOVDX,0021HINAL,DX”指令均可实现。
程序代码编写如下:
CSEGSEGMENT
ASSUMECS:
CSEG
START:
INAL,21H;21H端口字节内容送AL
MOVAH,4CH
INT21H
CSEGENDS
ENDSTART
将以上程序输入完毕后保存为111.ASM文件后,通过MASM程序对其汇编,再通过LINK程序连接成111.exe。
输入DEBUG111.exe命令,使用U命令反汇编后,再输入“G0004”命令执行该程序。
如图6-2所示。
图6-2查看结果
由图6-2可知,AL=18H,即21H端口内容为18H。
在DEBUG命令中,也有一个输入端口内容命令I。
命令格式:
I端口地址
功能:
输入端口地址内容并显示。
在以上程序执行完毕后,还可以使用DEBUG命令中的I21命令查看21H单元内容,结果如图6-3所示。
图6-3I命令
DEBUG中的I命令可以查看所有的端口地址,即“I0000”一直到“IFFFF”都为有效命令,但是I命令只能查看端口的字节内容,而无法查看端口的字内容。
并且I命令所接的端口地址后面不加H。
例6-2编写一个程序,将地址为00FFH的字端口内容送于AX寄存器。
然后将AX内容保存到BX寄存器中。
解:
该题的要求是将00FFH端口内容送AL寄存器,0100H端口内容送AH,为了方便观察结果,所以将AX的内容送到BX寄存器。
程序代码编写如下:
CSEGSEGMENT
ASSUMECS:
CSEG
START:
MOVDX,0FFH;端口地址赋予DX
INAX,DX;端口输入
MOVBX,AX;保存结果
MOVAH,4CH
INT21H;返回DOS
CSEGENDS
ENDSTART
将以上程序输入后保存退出,经过MASM汇编及LINK连接后,输入DEBUG111.EXE命令,以及使用U命令查看代码后,直接使用G0008命令执行该程序即可得到结果。
如图6-4所示。
图6-4查看结果
由图6-4可知,端口地址为00FFH的字端口内容为0FFFFH。
2.输出指令OUT
指令格式:
OUT端口地址,累加器
功能:
输出指令将累加器AL或AX的内容输出到指定端口。
说明:
与输入指令一样,端口地址可以采用直接方式表示,也可以采用间接方式表示。
当采用直接方式表示端口地址时,OUT指令中允许出现00H~0FFH范围内的端口地址;当采用间接方式表示端口地址时,端口地址0000H~0FFFFH必须事先存放到DX寄存器中,然后使DX作为目的操作数出现。
输出指令OUT有以下四种形式:
OUTPORT,AL;AL内容送字节端口
OUTPORT,AX;AX内容送字端口
OUTDX,AL;(DX)←AL
OUTDX,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与外设不同步的情况。
由上述可知,为了采用查询方式输入或输出,相应的外设接口不仅要有数据端口,而且还要有状态端口,有些外设还必须具有控制端口。
其中,数据端口存放要传送的数据,状态端口用来存放表示设备“就绪”或“忙”的当前状态,控制端口则存放CPU发送过来的控制命令(命令字),以控制设备的工作方式。
(3)中断方式
程序中断通常简称中断,是指CPU在正常运行程序的过程中,由于预选安排或发生了各种随机的内部或外部事件,使CPU中断正在运行的程序,而转到相应的服务程序去处理,这个过程称为程序中断。
80x86微处理器的中断类型一般分为2类,即由于执行某些指令引起的软中断和由处理器以外其他控制电路发出中断请求信号引起的硬中断。
中断传送方式是计算机中最重要的一种数据交换手段。
在速度较慢的外围设备准备自己的数据时,CPU照常执行自己的程序。
从这个意义上说,CPU和外围设备的一些操作是并行地进行的,因而计算机系统的效率是大大提高了。
(4)DMA传送方式
所谓DMA方式就是直接存储器存取(DirectMemoryAccess)方式。
在DMA方式下,外设通过DMA的一种专门接口电路――DMA控制器(DMAC),向CPU提出接管总线控制权的总线请求,CPU在当前的总线周期结束后,响应DMA请求,把对总线的控制权交给DMA控制器。
于是在DMA控制器的管理下,外设和存储器直接进行数据交换,而不需CPU干预,这样可以大大提高数据传送速度。
由于DMA传送方式涉及计算机硬件内容过多,本书不做详细介绍。
小结:
无条件传送方式虽然具有很多优点,但对于传送数据量很大的高速外设,如磁盘控制器或高速数据采集器,它又满足不了速度方面的要求。
中断方式和查询方式一样,仍然是通过CPU执行程序来实现数据传送的,每进行一次传送,CPU都必须执行一遍中断处理程序。
而每进入一次中断处理程序,CPU都要保护断点和标志,这要花费大量的处理时间。
此外,在服务程序中,通常还需要保护寄存器和恢复寄存器的指令,这些指令的执行又需花费CPU的时间。
还有,对8086系列的CPU来说,内部结构中包含了总线接口部件BIU和执行部件EU,它们是并行工作的,即EU在执行指令时,BIU要把后面将执行的指令取到指令队列中缓存起来。
但是,一旦转去执行中断处理程序,指令队列要被废除,EU须等待BIU将中断处理程序中的指令取到指令队列中才能开始执行程序。
同样,返回断点时,指令队列也要被废除,EU又要等待BIU重新装入从断点开始的指令后才开始执行,这些过程也要花费时间。
因此,可以看出中断方式下这些附加的时间将影响传输速度的提高。
另外,在查询方式和中断方式下,每进行一次传输只能完成一个字节或一个字的传送,这对于传送数据量大的高速外设是不适用的,必须要将字节或字的传输方式改为数据块的传输方式,这就需要DMA传送方式。
6.1.4存取RT/CMOSRAM
1.RT/CMOSRAM基本概念
在IBMPC/AT及其兼容机上均安装有一个RT/CMOSRAM芯片(互补金属氧化物半导体随机存取存储器),该芯片不仅可长期保存系统配置状况,而且记录包括世纪、年、月、日和时分秒的实时钟(Real_TimeClock)信息。
RT/COMSRAM作为一个I/O接口芯片,系统分配的I/O端口地址区为70H至7FH,通过IN和OUT指令可对其进行存取。
该芯片内部集成了64个字节的RAM单元,分配使用情况见表6-2。
其中,前14个字节单元用于实时时钟,剩下的50个字节单元用于存储系统的配置信息。
表6-2RT/CMOSRAM内部信息布局
位移
用途
位移
用途
0
秒
10
软盘驱动器类型
1
报警秒
11
保留
2
分
12
硬盘驱动器类型
3
报警分
13
保留
4
时
14
设备标志
5
报警时
15
常规RAM容量低字节
6
星期
16
常规RAM容量高字节
7
日
17
扩展RAM容量低字节
8
月
18
RAM容量高字节
9
年
19-1A
硬驱类型扩展字节
A-D
状态寄存器A-D
1B-2D
保留
E
诊断状态
2E-2F
配置信息字节累加和
F
停止状态
30-3F
其他(含世纪信息)
2.存取RT/COMSRAM
在存取RT/COMSRAM芯片内部的64个字节单元内容时,往往要分两步进行。
先把要存取单元的地址送端口70H,然后再存取端口71H。
还需要注意,14个记录实时时钟信息的单元的地址(位移0至0DH)就是表中位移,其他单元的地址是表6-1中的位移还要加80H。
(1)读操作代码片段如下:
MOVAL,n;n是要访问单元地址
OUT70H,AL;把要访问单元的地址送70H
NOP
NOP;延时
INAL,71H;从数据端口取访问单元的内容
(2)写操作代码片段如下:
MOVAL,n;n是要访问单元地址
OUT70H,AL;把要访问单元的地址送70H
NOP
NOP;延时
MOVAL,m;m是要输出数据
OUTAL,71H;从数据端口取访问单元的内容
在对同一个I/O设备或端口连续发送I/O指令时,为确保I/O设备或端口有足够的电路恢复时间,一般在I/O指令之间使用NOP指令进行延时,以满足I/O端口的需要。
例6-3读取当前计算机的年,送入AL寄存器。
CSEGSEGMENT
ASSUMECS:
CSEG
START:
MOVAL,9;“年”的地址为9。
OUT70H,AL;“年”的单元地址送70H单元
NOP
NOP;延时
INAL,71H;将端口71H的内容送AL
MOVAH,4CH
INT21H
CSEGENDS
ENDSTART
将以上程序输入完毕后保存为111.ASM文件后,通过MASM程序对其汇编,再通过LINK程序连接成111.exe。
输入DEBUG111.exe命令,使用U命令反汇编后,观测到结束地址为000AH,所以输入“G000A”命令执行该程序。
如图6-5所示。
图6-5调试结果图
由图6-6可知,AL内容为08D,即读取年份内容为BCD码的形式表示。
如果将程序的MOVAL,9指令中的单元地址9改为0、2、4、6、7或8可以得到秒、分、时、星期、日、月。
3.CMOSRAM累加和检查
在对系统配置时,要对CMOSRAM的位移10H~2DH的系统配置信息按字节求累加和,其值存放在位移2E~2FH的单元中。
低字节存放在2EH单元中,高字节存放在2FH单元中。
在系统加电自检时,将对CMOSRAM的位移10H~2DH单元的内容求和,并与保存的累加和比较。
若两者不等,则设置诊断状态字的第6位为1,表明累加和错。
这往往会导致要求用户重新进行系统设置。
例6-3编写一个检测程序,当累加和错时,设置诊断状态字节的第6位为1。
解:
从90H单元开始依次取出内容相加,一直累加至0ADH为止。
然后将累加和与2EH和2FH单元组成的字单元内容进行比较,若累加和相同,则结束;否则将8EH单元的第6位设置为1。
程序编写如下:
CSEGSEGMENT
ASSUMECS:
CSEG
START:
MOVAX,0000H;AX←0000H
MOVBX,AX;BX←0000H
MOVDL,90H;位移为10H的单元地址送DL
MOVDH,0AEH;DH指向结束地址后一单元
ACC1:
MOVAL,DL;访问单元地址送AL
OUT70H,AL;送70H地址端口
NOP
NOP;延时
INAL,71H;读单元内容
ADDBX,AX;求累加和
INCDL;DL指向下一单元
CMPDL,DH;和结束地址比较
JNZACC1;不相等继续求累加和
MOVAL,0AFH;取CMOSRAM的累加和高字节单元地址
OUT70H,AL;单元地址送70H端口
NOP
NOP;延时
INAL,71H;读累加和高字节内容
MOVAH,AL;送AH
MOVAL,0AEH;取CMOSRAM的累加和低字节单元地址
OUT70H,AL
NOP
NOP;延时
INAL,71H;读累加和低字节内容
CMPCX,BX;原始累加和CX与当前累加和比较
JZRIGHT;相等则正确,转RIGHT标志
MOVAL,8EH;否则将诊断状态地址送AL
OUT70H,AL
NOP
NOP;延时
INAL,71H;读诊断状态并送入AL
MOVAH,AL;将AL送AH进行处理
ORAH,40H;AH的第6位设置为1
MOVAL,8EH;诊断状态地址送AL
OUT70H,AL
NOP
NOP;延时
MOVAL,AH;将AH送回AL
OUT8EH,AL;输出到诊断状态单元
RIGHT:
MOVAH,4CH
INT21H;返回DOS
CSEGENDS
ENDSTART
6.2无条件方式输入输出
计算机系统中的扬声器(面板喇叭)是一种简单的输出设备,可以随时从CPU接收控制命令。
扬声器连接原理如图6-6所示。
图6-6扬声器控制原理
扬声器发声的基本原理是振动。
扬声器上的一层薄膜在电信号控制下往复振动产生声音,每秒钟振动的次数就是所发出声音的频率,振动的幅度决定声音的强度。
由于控制扬声器的信号是二进制的开关信号,不能控制流过扬声器的电流大小,因而不能控制扬声器薄膜的振幅,所以扬声器只能发出固定强度的声音。
但开关信号变化的频率是可以控制的,CPU正是通过控制开关信号的频率,使扬声器发出不同频率的声音。
控制扬声器的信号有两个来源,它们通过与门之后送放大电路使扬声器发声。
系统中的61H端口是一个可读写的外设端口,能够存放1字节数据,其中最低的两位P0和P1就用来控制送往扬声器的两个信号源。
最低位P0为0将使定时器送入与门A输入端的信号为高电位,这时只需要交替变化P1位的值送入与门的另外一个输入端B,这就使与门的输出端C上的信号在高低电位进行变化形成方波,该方波通过放大电路放大信号后,使扬声器产生振动。
人类可以识别的声音频率在20~20000HZ之间,其它频率的声音无法识别。
例如要使扬声器发出500HZ的声音,就要使P1位上的信号在每秒钟变化500次,即每0.002秒为一个变化周期,因而要使P1位在0.001秒内保持高电位,再下一个0.001秒内保持低电位,如此交替变化。
但是想精确控制0.001秒的时间需要掌握定时器的控制原理,此处只是为了说明无条件传送的原理,故简化时间控制的方法,采用软件延时方法实现。
扬声器发声时间则由P1位的变化次数来掌握,P1位变化次数越大,扬声器发声时间就越长。
对于500HZ的声音,P1变化5000次可以使扬声器发声10秒。
例6-4利用无条件传送方式,使计算机扬声器在10秒内保持发出500HZ的声音。
STACK1SEGMENTSTACK
DW1024DUP(?
)
STACK1ENDS
CSEGSEGMENT
ASSUMECS:
CSEG,SS:
STACK1
START:
MOVAX,STACK1
MOVSS,AX
MOVCX,5000;P1位变化次数送CX
AGAIN:
INAL,61H;读取61H端口内容
ANDAL,11111100B;清除P0和P1位
OUT61H,AL;关闭与门的输入端B
CALLDELAY;调用延时子程序,使与门关闭0.001秒
INAL,61H;读取61H端口内容
ORAL,00000010B;使P1位为1
OUT61H,AL;使与门的输入端B打开
CALLDELAY;调用延时子程序,使与门打开0.001秒
LOOPAGAIN;变化次数不为0则继续开闭与门
MOVAH,4CH
INT21H;返回DOS
DELAYPROC;延时子程序
PUSHCX
PUSHDX
MOVCX,0FFH;外循环次数
DELAY2:
MOVDX,0AFFH;内循环次数
DELAY1:
SUBDX,0001H
JNZDELAY1
LOOPDELAY2
POPDX
POPCX
RET
DELAYENDP
CSEGENDS
ENDSTART
该程序经保存、汇编、连接后,直接输入111文件名即可。
从