实验6 I/O程序设计
输入/输出是对外部设备进行控制和数据交换的过程。CPU与外设之间的信息交换,是通过接口电路中的I/O端口进行的。I/O程序设计必须使用IN、OUT指令,对端口进行读、写操作。
6.1 读取实时时钟
现代微机中都包含一个实时钟,它自动地定时更新时间与日期。实时钟信息(年、月、日、时、分、秒)保存在CMOS RAM中,在系统关机后,时钟电路自带的后备电池继续向RAM供电,并且继续更新时间与日期。
1. 实时钟信息的内容
实时钟信息存储在CMOS RAM最前面的14个字节,而其他的字节用于保存微机的配置信息,例如系统的内存容量、软盘、硬盘类型等。实时钟信息的格式如表6-1所示。
表6-1 实时钟信息的格式
位移 |
内容 |
取值范围 |
格 式 |
0 |
秒 |
00H~59H |
BCD码,如10H表示10秒,59H表示59秒。 |
1 |
报警秒 |
00H~59H |
BCD码,同上。设为 0C 0H~0FFH时,不报警。 |
2 |
分 |
00H~59H |
BCD码,如06H表示06分,45H表示45分。 |
3 |
报警分 |
00H~59H |
BCD码,同上。设为 0C 0H~0FFH时,不报警。 |
4 |
小时 |
00H~23H |
BCD码,如12H表示12点,16H表示16点。 |
5 |
报警小时 |
00H~23H |
BCD码,同上。设为 0C 0H~0FFH时,不报警。 |
6 |
星期几 |
1~7 |
1=星期日,2=星期一……7=星期六 |
7 |
日 |
01H~31H |
BCD码,如31H表示31日。 |
8 |
月 |
01H~12H |
BCD码,如04H表示4月,12H表示12月。 |
9 |
年 |
00H~99H |
BCD码,年份的后面2位。如03H表示2003年。 |
10 |
状态/控制A |
|
Bit 7=1,正在刷新。Bit 6~4=010b,基准频率=32768Hz。 |
11 |
状态/控制B |
|
Bit 1=1,使用24小时制。Bit 0=1,使用夏时制。 |
12 |
状态C |
|
Bit 7=1,产生中断请求。Bit 6~4,中断原因。 |
13 |
状态D |
|
Bit 7=1,CMOS电池正常。 |
其中,报警信息记录在1、3、5单元中。若这些单元的内容为 0C 0~0FFH时,则报警功能无效。当实时钟到达设定报警时间时,立即产生一个中断信号,并设置状态C中的Bit5为1。
2. 实时钟信息的读取方法
对CMOS RAM的访问必须用I/O指令来完成。接口电路设置了两个寄存器,其I/O地址分别是70H和71H。70H是RTC地址寄存器,71H是RTC数据寄存器。要访问某个CMOS RAM单元时,CPU先用OUT指令将该单元的地址(00H~7FH)写入到70H端口中,再使用IN指令读入该CMOS RAM单元的内容。如图6-1所示。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
I/O地址 |
|
70H |
|
|
|
|
|
|
RTC地址寄存器 |
|
RTC地址 |
|
CPU |
数据 |
|
|
|
|
CMOS |
|
|
|
71H |
|
|
RAM |
|
读/写 |
|
RTC数据寄存器 |
|
数据 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RTC接口电路 |
|
|
|
图6-1 RTC输入/输出接口
3. 在用户模式下执行IN、OUT指令
在Windows NT/2000/XP/2003中,应用程序运行最低特权级(CPL=3)。标志寄存器中的IO特权级被设置为3(IOPL=3),而且任务状态段中I/O位图中所有位为1,这样,不允许应用程序使用I/O指令。如果在程序中执行IO指令,会产生异常,程序被中止运行。
为避免该问题,可以将giveio.sys驱动程序装入内核,应用程序打开//./giveio设备文件,驱动程序就将任务状态段中I/O位图的全部位设为0。这样,在应用程序中就可以执行IN、OUT指令了。
将giveio.sys驱动程序装入内核的命令为:
c:/asm/bin/allowio -load c:/asm/bin/giveio.sys
从内核中卸载giveio.sys驱动程序的命令为:
c:/asm/bin/allowio -unload
;程序清单:cmosram.asm(读取实时钟)
.386
.model flat,stdcall
option casemap:none
includelib msvcrt.lib
includelib kernel32.lib
printf PROTO C format:ptr sbyte,:vararg
CreateFileA PROTO stdcall,
lpFileName:NEAR32, dwDesiredAccess:dword, dwShareMode:dword,
lpSecurityAttributes:NEAR32, dwCreationDisposition:dword,
dwFlagsAndAttributes:dword, hTemplateFile:dword
CloseHandle PROTO stdcall, hObject:dword