8086PC机当中,键盘的输入将会引发9号中断,BIOS提供了int 9的中断例程。CPU在9号中断发生之后,会去执行int 9中断例程,然后从60h端口当中读取出扫描码,并且将其转换为相应的ASCII码和状态信息,存储在内存的指定的空间(键盘缓冲区或状态字节)当中
一般的键盘输入,在CPU执行完int 9 中断例程之后都放到了键盘缓冲区当中,键盘缓冲区有16个字单元,可以存储15个按键扫描码和对应的ASCII码,这里之所以只能放15个是因为键盘缓冲区是用环形队列结构管理的内存区域,虽然缓冲区的本身长度为16个字,但出于判断“对列满”的考虑,它最多只能保存15个键盘信息。
环形队列的关键是判断队列为空,还是为满。当tail追上head时,队列为满时,当head追上tail时,队列为空。要知道是满还是空,可以根据下面的方法来判断
1、添加一个标志位tag
当head赶上tail,队列空,则令tag=0
当tail赶上head,队列满,则令tag=12、限制tail赶上head,即队尾结点与队首结点之间至少留有一个元素的空间
队列空: head==tail
队列满: (tail+1)% MAXN ==head
上面提到了我们使用shift+A的时候,其实输出到屏幕的是大写字母A,我在Mac下面试验也是一样的,说明其实大致的机制都是差不多的
程序如下所示
assume cs:code
code segment
start:mov ah,0
int 16h
mov ah,1
cmp al,'r' ;要是输入的是r,就跳到Red处
je red
cmp al,'g' ;如果输入的是g,那么就跳到green处
je green
cmp al,'b' ;如果输入的是b,那么就跳到blue处
je blue
jmp short sret
red: shl ah,1
green: shl ah,1
blue:mov bx,0b800h ;设置要改变的字符地址处
mov es,bx
mov bx,1
mov cx,2000
s:and byte ptr es:[bx],11111000b ;要改变的是第0、1、2位
or es:[bx],ah
add bx,2
loop s
sret:mov ax,4c00h
int 21h
code ends
end start
执行结果如下所示