使用BIOS进行键盘输入和磁盘读写(学习汇编)
1.键盘输入将引发9号中断,BIOS提供了int 9中断例程。CPU在9号中断发生后,执行int 9中断例程,从60h端口读出扫描码,并将其转化为相应的ASCII码或状态信息,存储在内存的指定空间(键盘缓冲区或状态字节)中。一般的键盘输入,在CPU执行完int 9中断例程后,都放到了键盘缓冲区中。键盘缓冲区有16个字单元,可以存储15个按键的扫描码和对应的ASCII码。
2.下面,我们通过下面几个键:
A、B、C、D、E、shift_A、A
的输入过程,简要地看一下int 9中断例程对键盘输入的处理方法:
(1)初始状态下,没有键盘输入,键盘缓冲区空,此时没有任何元素:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(2)按下A键,引发键盘中断:CPU执行int 9中断例程,从60h端口读出A键的通码;然后检测状态字节,看看是否有shift、Ctrl等切换键按下;发现没有切换键按下,则将A键的扫描码1eh和对应的ASCII码,即字母“a”的ASCII码61h,写入键盘缓冲区。缓冲区的字单元中,高位字节存储扫描码,低位字节存储ASCII码。此时缓冲区中的内容如下:
1E61 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(3)按下B键,引发键盘中断:CPU执行int 9中断例程,从60h端口读出B键的通码;然后检测状态字节,看看是否有切换键按下;发现没有切换键按下,将B键的扫描码30h和对应的ASCII码,即字母“b”的ASCII码62h,写入键盘缓冲区。此时缓冲区中的内容如下:
1E61 |
3062 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(4)按下C、D、E键后,缓冲区中的内容如下:
1E61 |
2062 |
2E63 |
2064 |
1265 |
|
|
|
|
|
|
|
|
|
|
|
(5)按下左shift键,引发键盘中断:int 9中断例程接收左shift键的通码,设置0040:17处的状态字节的第1位为1,表示左shift键按下。
(6)按下A键,引发键盘中断:CPU执行int 9中断例程;从60h端口读出A键的通码;检测状态字节,看看是否有切换键按下,发现左shift键被按下,则将A键的扫描码1Eh和shift_A对应的ASCCII码,即字母“A”的ASCII码41,写入键盘缓冲区,此时缓冲区中的内容如下:
1E61 |
2062 |
2E63 |
2064 |
1265 |
1E41 |
|
|
|
|
|
|
|
|
|
|
(7)松开左shift键,引发键盘中断:int 9中断例程接收左shift键的断码,设置0040:17处的状态字节的第1位为0,表示左shift键松开。
(8)按下A键,引发键盘中断:CPU执行int 9中断例程,从60h端口读出A键的通码,然后检测状态字节,看看是否有切换键按下,发现没有切换键按下,则将A键的扫描码1Eh和A对应的ASCCII码,即字母“a”的ASCII码61h,写入键盘缓冲区,此时缓冲区中的内容如下:
1E61 |
2062 |
2E63 |
2064 |
1265 |
1E41 |
1E61 |
|
|
|
|
|
|
|
|
|
3.int 16h中断例程中包含的一个最重要的功能是从键盘缓冲区中读取一个键盘输入,该功能的编号为0。下面的指令从键盘缓冲区中读取一个键盘输入,并将其从缓冲区中删除:
mov ah,0
int 16h
结果:(ah)=扫描码,(al)=ASCII码。
int 16h中断例程的0号功能,进行如下的工作:
1)检测键盘缓冲区中是否有数据;
2)没有则继续做第1步;
3)读取缓冲区第一个字单元中的键盘输入;
4)将读取的扫描码送入ah,ASCII码送入al;
5)将已读取的键盘输入从缓冲区中删除。
可见,BIOS的int 9中断例程和int 16h中断例程是一对相互配合的程序,int 9中断例程向键盘缓冲区中写入,int 16h中断例程从缓冲区中读出。它们写入和读出的时机不同,int 9中断例程是在有按键按下的时候向键盘缓冲区中写入数据;而int 16h中断例程是在应用程序对其进行调用的时候,将数据从键盘缓冲区中读出。
4.附上一个程序,实现输入'r',将屏幕上的字符设置为红色;输入'g',将屏幕上的字符设置为绿色;输入'b',将屏幕上的字符设置为蓝色。
1 assume cs:code 2 code segment 3 4 start: mov ah,0 5 int 16h 6 mov ah,1 ;1为blue字节的属性 7 cmp al,'r' 8 je red 9 cmp al,'g' 10 je green 11 cmp al,'b' 12 je blue 13 jmp short sret 14 15 red: shl ah,1 ;执行red:green:左移2次则为...100 16 17 green: shl ah,1 ;...010 18 19 blue: mov bx,0b800h ;...001 20 mov es,bx 21 mov cx,2000 22 23 s: add byte ptr es:[bx],11111000b 24 or es:[bx],ah 25 add bx,2 26 loop s 27 28 sret: mov ax,4c00h 29 int 21h 30 31 32 code ends 33 end start 34 35