BIOS中断
固化在ROM中的基本输入输出系统BIOS(Basic Input/Output System)包含了主要I/O设备的管理程序和许多常用例行程序,它们一般以中断处理程序的形式存在。BIOS直接建立在硬件基础上。
DOS建立在BIOS的基础上,通过BIOS操纵控制硬件。
通常应用程序应优先使用DOS提供的功能完成输入输出或其它的操作。这样的软件对硬件的依赖性更小。但在下列两种场合可考虑用BIOS:一是要使用DOS不提供的某个功能的场合;二是不能利用DOS功能调用的场合。
1. BIOS键盘中断
1)键盘中断
当用户按键时,键盘接口会得到一个被按键的键盘扫描码,同时产生一个中断请求。如果键盘中断是允许的(中断屏蔽字中的bit1为0),并且CPU处于中断状态(I=1),那么CPU通常就会响应中断请求,转入键盘中断处理程序。
键盘中断处理程序首先从键盘接口取得代表被按键的扫描码,然后根据扫描码判别用户所按的键并做相应的处理。我们把键盘上的键简单地分成五种类型:字符键(字母、数字和符号等),功能键(如F1和PgUp等),控制键(Ctrl、Alt和左右Shift键),双态键(如Num Lock和Caps Lock等),特殊请求键(如Print screen等)。键盘中断处理程序对五种键的基本处理方法如下:
如果用户按的是双态键,那么就设置有关标志,在AT以上档次的系统上还要改变LED指示状态。
如果用户按的是控制键,那么就设置有关标志。
如果用户按的是功能键,那么就根据键盘扫描码和是否按下某些控制键(如Alt)确定系统扫描码,把系统扫描码和一个全0字节一起存入键盘缓冲区。
如果用户按的是字符键,那么就根据键盘扫描暗码和是否按下某些控制键(如Ctrl)确定系统扫描码,并且得出对应的ASCII码,把系统扫描暗码和ASCII 码一起存入键盘缓冲区。
如果用户按的是一个特殊请求键,那么就产生一个相对应的动作,例如用户按Print screen键,那么就调用5H号中断处理程序打印屏幕。
2)键盘缓冲区
键盘缓冲区是一个先进先出的环行队列,结构和占用的内存区域如下:
BUFF_HEAD DW ? ;0040:001AH
BUFF_TALL DW ? ;0040:001CH
KB_BUFFER DW 16 DUP (?) ;0040:001EH—003DH
BUFF_HEAD和BUFF_TALL是缓冲区的头指针和尾指针,当这两个指针相等时,表示缓冲区为空。由于缓冲区本身长16个字节,而存放一个键的扫描码和对应的ASCII码需要占用一个字,因此,键盘缓冲区可实际存放15个键的扫描码和ASCII码。键盘中断处理程序把所键入的字符键或功能键的扫描码和对应的ASCII码(如为功能键,对应的ASCII码理解为0)依次存入键盘缓冲区。如缓冲区已满,则不再存入,而发出“嘟”的一声。
顺便说一下,键盘中断处理程序根据控制键和双态键建立的标志在内存单元0040:0017H字单元中。
3)键盘I/O程序的功能和调用方法
键盘I/O程序以16H号中断处理程序的形式存在,它属于软中断处理程序。键盘I/O程序提供的主要功能列于表4.3,每一个功能有一个编号。
在调用键盘I/O程序时,把功能编号置入AH寄存器,然后发出中断指令“INT 16H”。调用返回后,从有关寄存器中取得出口参数。
下面的程序片段从键盘读一个字符:
MOV AH,0
INT 16H
如果键盘缓冲区中有字符,那么中断处理程序就会极快结束,即调用就会极快返回,读到的字符是调用发出之前用户按下的字符。如果键盘缓冲区空,那么要等待用户按键后调用才会返回。
表4.3 16H号中断处理程序的基本功能
功能 |
出口参数 |
说明 |
(AH) = 0 从键盘读一个字符 |
(AL)=字符的ASCII码 (AH)= 字符的扫描码 |
如果无字符可读则等待;字符也包括功能键,对应ASCII码为0 |
(AH) = 1 判断键盘是否有键可读 |
Z = 1表示无键可读 Z = 0表示有键可读 |
不等待,立即返回 (AL)=字符的ASCII码 (AH)=字符的扫描码 |
(AH) = 2 取变换键当前状态 |
(AL)=变换键状态字节 |
|
AH = 10H 从键盘读一个字符 |
同0号功能 |
所不同的是它不删除扩展的键,在早期的系统中没有此功能 |
AH = 11H 判断键盘是否有键可读 |
同1号功能 |
所不同的是它不删除扩展的键,在早期的系统中没有此功能 |
例4.21:
…
AGAIN:MOV AH,1
INT 16H :判缓冲区空?
JZ NEXT ;空,转
MOV AH,0
INT 16H ;从键盘缓冲区取一个字符
JMP AGAIN ;继续
NEXT: MOV AH,0
INT 16H ;等待键盘输入
…
当然,程序员也可以通过直接修改键盘缓冲区头指针的方法清除键盘缓冲区,但我们不鼓励这样做。
例4.22:
写一个程序完成如下功能:读键盘,并把所按键显示出来,在检测到按下SHIFT键后,就结束运行。
分析:调用键盘I/O程序的2号功能取得变换键状态字节,进而判断是否按下了Shift键。在调用0号功能读键盘之前,先调用2号功能判键盘是否有键可读,否则会导致不能及时检测到用户按下的SHIFT键。
程序如下:
;…………源程序…………
;………常量定义………
L_SHIFT = 00000010B
R_SHIFT = 00000001B
;…………代码段…………
CODE SEGMENT
ASSUME CS:CODE
START:MOV AH,2 ;取变换键状态字节
INT 16H
TEST AL,L_SHIFT R_SHIFT ;判是否按下SHIFT键
JNZ OVER ;按下,转
MOV AH,1
INT 16H ;是否有键可读
JZ START ;没有,转
MOV AH,0 ;读键
INT 16H
MOV DL,AL ;显示所读键
MOV AH,6
INT 21H
JMP START ;继续
OVER: MOV AH,4CH
INT 21H
CODE ENDS
END START