2021-04-23

键盘,萌宝相信大家都不陌生,天天与它打交道。

但熟归熟,清楚键盘背后的原理吗?

键盘上都标有各键的名称,表明了各键所代表的意义,但是计算机是如何知道的?

组合键是怎样实现的?

按下一个代表字符的键,怎么变成平常使用的ASCII码的?

#第七魂技‧武魂真身#


01—— 相关介绍

键盘编码器

键盘编码器(i8048),是键盘里的芯片,主要用来监控是否有键按下,弹起,然后向键盘控制器报告此键的相关信息。

键盘扫描码

一个键有按下就会有弹起,所以每个键会有两个状态,即每个键将会对应两个扫描码,键被按下时的编码叫做通码(makecode),弹起时的编码叫做断码(breakcode)。

键盘控制器

键盘控制器(i8042),不在键盘内部,被集成在南桥芯片上。

它主要是接收键盘编码器发来的扫描码(第二套),解码(转成第一套)后保存到自己的寄存器中,然后通过中断控制器发送中断请求。

i8042有4个寄存器,如下所示:

注:输入输出要视对象决定,对键盘控制器来说是输出,那么对CPU来说则是输入,使用 in 指令。

02——键盘中断流程

其实上述的相关介绍已经涉及了部分键盘中断流程,在此从头至尾具体说说,先看流程图:

03——键盘中断服务程序

键盘中断在所有的可屏蔽中断中优先级仅次于时钟中断,也需要尽快的处理。

在Linux 0.11里的整个键盘服务程序都是用汇编来写的,汇编语言直接操作底层的指令,没有编译器来增加额外的东西,所以运行起来比高级语言写的程序快,但也增加了编写程序的难度。

linux0.11版本的键盘中断服务程序的框架源码如下图所示:

这个框架程序主要做了以下事情:

保护现场——压栈

上文中写到压栈ss, esp,  eflags, cs, eip, error_code (若有特权级变化且中断带有错误码) 来保存现场,那只是CPU自动执行的部分,完全保存原任务的信息还是在中断处理程序中进行的。

如上图所示,键盘中断服务程序里通用寄存器只保存了4个,eax, ebx, ecx, edx,若为了省事不追求效率完全可以无脑操作pushad压榨所有的通用寄存器。

#坏了坏了#


读取扫描码

inb $0x60, al  从键盘控制器的输出缓存区0x60端口读取扫描码。

若不从输出缓冲区读取数据的话,键盘控制器是不会继续工作的,意思是无论你怎么按键,键盘控制器不会响应键盘操作,不会存下新的扫描码发送中断信号等。

当然不读取扫描码后续的键盘中断程序也没法工作没有意义。

判断是否为 0xe0 或 0xe1

如果扫描码是 0xe0 或者 0xe1,那说明这个键的扫描码是有多个字节的,需要先保存下来等待接下来的扫描码组合成完整的扫描码。 

寻址、调用相应的键处理程序

拿到完整的扫描码之后就该去寻找相应的键处理程序了

源码中有个key_table,table, 说明它是一张表,或者说一个数组

这里面就按照扫描码大小存放了各个键的实际处理程序地址。

如何找到相应的键处理程序呢?

其实跟数组用下表获取元素一样

据源码所示采用比例变址寻址的方式,即key_table(, %eax, 4)

也就是说相应的键处理程序的地址是key_table + eax * 4。key_table

相当于数组首地址;

eax里面存放的扫描码,扫描码可以看成数字索引号

相当于数组下标;

地址32位,4字节,所以乘4

回复现场—出线

压栈保护现场的逆过程,在此不再赘述

萌宝要提醒各位,需要注意执行到 iret 时的栈顶应是 eip哦~

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • python小游戏 工具: idea +python3.8+pygame 1.猜字小游戏 import rando...
    怦怦在左边_3e89阅读 442评论 0 0
  • 进程 进程定义(程序段,相关数据段和PCB构成进程实体,又称为进程映像): 进程是程序的一次执行 进程是一个程序机...
    岁杪二十七阅读 646评论 0 1
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,606评论 28 53
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,227评论 4 8
  • 怎么对待生活,它也会怎么对你 人都是哭着来到这个美丽的人间。每个人从来到尘寰到升入天堂,整个生命的历程都是一本书,...
    静静在等你阅读 5,023评论 1 6