在第十四章介绍端口的时候,我们知道了CPU不仅和存储器相连,还和一些其他的芯片(可以理解为外设)有交互,我们知道了通过in/out命令可以从端口读出/写入数据,到目前为止,都是我们控制CPU主动向芯片发起读写,见图1。而这一章恰恰就要讲到,外设向CPU发起信号时,CPU该如何处理,见图2。
这一章可以分为两个部分——外设的输入随时可能发生,CPU如何得知,CPU从何处获取该外设的输入
接口芯片和端口
这部分还是先理清一下 接口芯片、端口、I/O外设、芯片内寄存器都是啥玩意。
其实 接口芯片、I/O外设可以理解为同个东西,因为它们本质上就是提供输入输出的东东。
端口和芯片内寄存器是同个东西,CPU和芯片(I/O设备)之间就是通过这个芯片内寄存器进行沟通的,而我们为了更加术语一些,将这种作为输入输出中介的寄存器当作端口(所以也只是我们人为命名啦~)。
这里举个写例子:
- CPU通过地址线将地址信息 71H 发出
- CPU通过数据线提供要写入的数据
- CPU通过控制线发出写命令,端口收到命令数据后,芯片会根据控制命令,将 从CPU获取的数据 写入到芯片内
外中断信息
当外设通知CPU有需要的事情处理时,就会向CPU发出相应的中断信息,当CPU在执行完当前指令后,可以检测到发送过来的终端信息,随后引发中断过程,处理外设的输入。外中断分为两类,一类是可屏蔽外中断,一类是不可屏蔽外中断。
可屏蔽外中断
可屏蔽外中断是CPU可以不响应的外中断。CPU可通过控制标志寄存器的IF位来设置是否响应可屏蔽中断:
- 当IF = 1时,CPU在执行完指令后响应该中断,引发中断过程
- 当IF = 0时,不响应中断。
我们回顾一下之前学的内中断的中断处理过程:
- 取中断类型码n
- 标志寄存器入栈,IF=0,TF=0
- CS、IP入栈
- (IP)=(n * 4),(CS)= (n * 4 + 2)
我们着重关注第二步,IF=0
表示在执行内中断中断例程时,禁止被其他可屏蔽中断中断。
当然,如果有需要的话,可以在中断处理例程里面,手动将IF
设置为1。8086提供的设置IF的指令如下:
- sti,设置IF=1
- cli,设置IF=0
不可屏蔽中断
不可屏蔽中断是CPU必须要响应的外中断,当CPU检测到不可屏蔽中断信息时,在执行完当前指令后,必须立即响应,引发中断过程。
8086CPU的不可屏蔽中断的中断类型码固定为2,所以中断过程中,不需要再取出中断类型码。不可屏蔽中断的中断过程为:
- 标志寄存器入栈,IF=0,TF=0
- CS、IP入栈
- (IP)= 8,(CS)=(0AH)
几乎所有由外设引发的中断都是可屏蔽中断,比如键盘产生输入时,相关芯片就会向CPU发送可屏蔽中断;不可屏蔽中断是在系统中有必须处理的紧急情况发生时用来通知CPU的中断信息(目前网上查到的一些例子:产生奇偶错误,协处理器上来的中断,I/O通道检查出错等)。
外设输入时,CPU的处理过程(以键盘输入为例)
关于键盘的一些知识
键盘上的每一个键相当于一个开关,按下时会产生一个扫描码;松开时也会产生一个扫描码。一般将按下时产生的扫描码称为通码,松开键产生的扫描码称为断码,扫描码的长度通常为一个字节,通码的第7位为0,断码的第7位为0。
断码 = 通码 + 80H
比如,键盘上U键的通码是16H,那么其断码就是96H
???? 键盘码表大全
引发9号中断
键盘的输入到达 60H端口时,相关的芯片就会向CPU发出中断类型码为 9的可屏蔽中断信息(这里不是直接发出的,主要是通过INTR这个东西发起的。具体可以参考《计算机组成原理》笔记的中断一章)。CPU检测到该中断信息后,去判断一下 标志寄存器上的IF
信息,如果IF=1
就响应中断,转去中断例程。
9号中断例程
DOS系统自带的9号中断例程主要做了以下三件事
- 读出60H端口中的扫描码
如果扫描码是字符键的扫描码,则将该扫描码和其对应的ASCII码送入内存中的BIOS键盘缓冲区;如果是控制键(Ctrl等)或切换键(CapsLock等)的扫描码,则将其转为一个0或1的bit位(占存储状态字节的一个bit位),并写入内存中存储状态字节的单元(该单元在0040:17),如下图所示。
对键盘系统进行相关的控制,比如说,向相关芯片发出应答信息。
BIOS键盘缓冲区是系统启动后,BIOS用于存放
int 9
中断例程所接收的键盘输入的内存区。内存区总共可以存储15个键盘输入,由于每一次的输入除开扫描码外还有对应的字符码,所以BIOS键盘缓冲区会有30个内存单元,即30个字节。一个键盘输入用一个字单元存放,高位放扫描码,低位放字符码。
15.4 编写int 9
中断例程
由于dos自带的int 9
比较复杂,涉及到比较底层的内容,不用不行(比如保存状态字节,键盘缓冲区?重复的代码太多,我们就复用以下),但是还要新增自己的代码,我们可以选择组合,我们编写一个新的int 9
程序,在这个程序里面调用原来dos的int 9
。
断更啦~~~
到目前为止,汇编的基本内容都学的差不多了。整本书里面,个人觉得最重要的就在中断这一块,因为IO处理方式和这个关系很大~
由于刚上班,时间比较紧还有很多内容需要学习,所以汇编大致学到这里,暂时够用。