System Interruption
Jun 15th, 2020
BIOS 调用
在主板内存较高地址区内的ROM(只读存储器)中,固化了PC机的基本输入/输出系统BIOS(Basic Input/Output System)。 BIOS 提供了系统加电自检、引导并装人操作系统、主要I/O设备的控制等功能。主要的外部设备,如键盘、显示系统、磁盘(软盘和硬盘)、打印机、系统时钟等,都有相应的中断调用。主要的BIOS中断类型如下表所示。
中断号 | 功能 | 中断号 | 功能 |
0H | 除法出错 | 10H | 显示器 |
1H | 单步中断 | 11H | 设备校验 |
2H | 不可屏蔽中断 | 12H | 内存大小检查 |
3H | 断点中断 | 13H | 磁盘 |
4H | 溢出中断 | 14H | 异步通信 |
5H | 打印屏幕中断 | 15H | I/O系统扩充 |
8H | 8254系统定时中断 | 16H | 键盘 |
9H | 键盘中断 | 17H | 打印机 |
BH | 异步通信串口1中断 | 18H | 驻留BIOS |
CH | 异步通信串口0中断 | 19H | 引导 |
DH | 硬件中断 | 1AH | 时钟 |
EH | 软盘中断 | 1BH | 键盘Break |
FH | 并行打印机中断 | 1CH | 定时器 |
左侧栏中的中断号都小于10H,为系统的硬中断,所谓硬中断,是由I/O硬件事件触发的,一般不由程序调用(尽管可以调用它们)。这类中断提供的是真正面向I/O硬件的中断例程。
右侧栏中的中断号大于等于10H的,为软中断,它不由I/O硬件事件触发,是供系统软件和用户程序调用的一组功能。
一些主要的I/O设备,如键盘、显示器、打印机、磁盘、异步通信口、时钟等都拥有这两种中断。
DOS中断调用
DOS是磁盘操作系统(Disk Operating System)的简称.DOS是由BIOS在开机后装入内存的,它提供了任务管理、设备管理、用户界面管理、文件管理等各种服务。
本来DOS是一套标准的软件,不会产生什么中断。但DOS借用了BIOS用软中断提供功能调用的方法,将它为编程者准备的API(应用程序编程接口)都以中断调用方式来提供。这些功能调用也不仅仅是1/O设备的功能调用。
大多数为用户提供的功能调用都位于软中断21H中,但还有其他一些DOS中断调用。主要的DOS中断调用如下表所示。
中断号 | 功能 |
20H | 程序终止 |
21H | 主要的DOS功能调用 |
22H | 结束地址 |
23H | Ctrl+Break出错地址 |
24H | 严重出错处理 |
25H | 绝对磁盘读 |
26H | 绝对磁盘写 |
27H | 终止并驻留内存 |
28H~3EH | DOS内部使用的中断 |
2FH | 补充的DOS中断 |
30H~3FH | 保留给DOS |
对编程者来说,使用的主要是21H中断调用。
DOS在21H中断调用中给出了绝大多数用户编程所需的功能,所以有时也将对21H的调用称为DOS功能调用。
对DOS21H功能的调用,只需将AH置成功能号,其他寄存器置上该功能号所规定的参数,即可完成所需的功能。
例如,要从应用程序中返回DOS的功能调用方法是:
平时我们直接使用
MOV AX, 4C00H
就是返回码为0的返回到DOS。
键盘I/O调用
这里大部分使用栗子进行说明。
IBM键盘的扫描码表
键盘缓冲区
用户每按下一个键,都会产生一个键盘中断(如果允许中断的话)。
键盘的中断处理程序会根据用户按下的键,决定是否求出所按键的ASCII码,否则,将只给出该键的扫描码。
由于所按键并不会马上被用户程序读取,所以在BIOS的参数区中,定义了一个键盘输人缓冲区KB_ BUFFER。它的位置在内存0040: 001A处,结构如下:
地址 | 属性 | 空间定义 | 说明 |
0040:001A | BUFF_HEAD | DW ? | 首指针 |
0040:001C | BUFF_TAIL | DW ? | 尾指针 |
0040:001E | KB_BUFFER | DW 16 DUP(?) | 16个字的缓冲区 |
0040:003E | KB_BUFFER_END | LABEL, WORD | 尾地址 |
上述缓冲区是一个先进先出的循环队列,BUFF_HEAD及BUFF_TAIL是缓冲区的两个指针。这两个指针相等,缓冲区为空。程序调用BIOS获取键盘输人时,BIOS就会从缓冲区中取出内容,同时移动指针。缓冲区满,会响铃告警。
键盘状态及键盘状态字节
用户按下Shift ,Ctrl, Alt ,NumLock ,Scroll,Ins及CapsLock键时, BIOS并不返回扫描码, 而是置上一种状态。
程序可通过查询状态字节获知这些键的状态。
利用 INT 16H 的 AH=2 功能可以返回此状态字节。
下图为键盘状态对应的字节:
BIOS键盘功能调用
BIOS提供给键盘的调用为16H,有三个功能,分别为:
AH号 | 功能 | 结果 | 说明 |
0 | 从键盘读 | AH为键盘扫描码 AL为对应的ASCII(如果可以转换为ASCII) | 该功能为强制读 若用户没有按键则一直等待 |
1 | 从缓冲区读 | ZF=0时:AH=键盘扫描码,AL=对应的ASCII或0 ZF=1时:表示无键被按下,KB_BUFFER为空 | 该功能为探测读 若用户已按键,则与0相同 若用户未按键,则直接返回 |
2 | 取键盘状态字节 | AL=键盘状态字节 | 参见上图的键盘状态字节 |
实用栗子:
输入汉字:
在程序运行过程中检测是否有键按下:
在一个长时间运行的程序中,可以加入上面的语句序列控制程序的运行,比如按下ESC时终止程序运行,则将
cmp ah,xx
中 xx 替换为 01 即可。
DOS键盘功能调用
BIOS使用的是16h进行调用,DOS的21h也为键盘提供了一些列的功能如下:
AH | 功能说明 | 输入参数 | 返回结果 |
1 | 从键盘读入并回显 | AL=字符 | |
6 | 测试读键盘 | DL=0FFH | AL=字符(如有输入) |
7 | 从键盘输入一个字符并不回显 | AL=字符 | |
8 | 从键盘输入一个字符并不回显,检测Ctrl+Break | ||
A | 读字符至缓冲区 | DS:DX=缓冲 | 字符及计数已经设置好 |
B | 读键盘状态 | AL=0FFH(有输入) AL=00H(无输入) | |
C | 清除键盘缓冲区并调用一种功能 | AL=功能号(1,6,7,8,A) |
下面以栗子来说明A和C功能:
清除键盘缓冲区:
注意是键盘的缓冲区,不是设置的DS:DX内存的缓冲区
读入字符串,实现将其中的所有小写转大写的功能
运行实例:
in_buf 位于 DS:46,输入
huiH231-
第一个byte为78H,十进制为120
第二个byte为08H,为实际输入的字符个数
in_buf+2 开始为实际存储,如果要直接输出需要在末尾加'$'
Last updated