第十五章 外中断

在第十四章介绍端口的时候,我们知道了CPU不仅和存储器相连,还和一些其他的芯片(可以理解为外设)有交互,我们知道了通过in/out命令可以从端口读出/写入数据,到目前为止,都是我们控制CPU主动向芯片发起读写,见图1。而这一章恰恰就要讲到,外设向CPU发起信号时,CPU该如何处理,见图2。

CPU主动向芯片发起读写命令

外设主动向CPU发起数据

这一章可以分为两个部分——外设的输入随时可能发生,CPU如何得知CPU从何处获取该外设的输入

接口芯片和端口

这部分还是先理清一下 接口芯片端口I/O外设芯片内寄存器都是啥玩意。

其实 接口芯片I/O外设可以理解为同个东西,因为它们本质上就是提供输入输出的东东。
端口芯片内寄存器是同个东西,CPU和芯片(I/O设备)之间就是通过这个芯片内寄存器进行沟通的,而我们为了更加术语一些,将这种作为输入输出中介的寄存器当作端口(所以也只是我们人为命名啦~)。

这里举个写例子:

  1. CPU通过地址线将地址信息 71H 发出
  2. CPU通过数据线提供要写入的数据
  3. CPU通过控制线发出写命令,端口收到命令数据后,芯片会根据控制命令,将 从CPU获取的数据 写入到芯片内

外中断信息

当外设通知CPU有需要的事情处理时,就会向CPU发出相应的中断信息,当CPU在执行完当前指令后,可以检测到发送过来的终端信息,随后引发中断过程,处理外设的输入。外中断分为两类,一类是可屏蔽外中断,一类是不可屏蔽外中断

可屏蔽外中断

可屏蔽外中断是CPU可以不响应的外中断。CPU可通过控制标志寄存器的IF位来设置是否响应可屏蔽中断:

  • 当IF = 1时,CPU在执行完指令后响应该中断,引发中断过程
  • 当IF = 0时,不响应中断。

我们回顾一下之前学的内中断的中断处理过程:

  1. 取中断类型码n
  2. 标志寄存器入栈,IF=0,TF=0
  3. CS、IP入栈
  4. (IP)=(n * 4),(CS)= (n * 4 + 2)

我们着重关注第二步,IF=0表示在执行内中断中断例程时,禁止被其他可屏蔽中断中断。

当然,如果有需要的话,可以在中断处理例程里面,手动将IF设置为1。8086提供的设置IF的指令如下:

  • sti,设置IF=1
  • cli,设置IF=0

不可屏蔽中断

不可屏蔽中断是CPU必须要响应的外中断,当CPU检测到不可屏蔽中断信息时,在执行完当前指令后,必须立即响应,引发中断过程。

8086CPU的不可屏蔽中断的中断类型码固定为2,所以中断过程中,不需要再取出中断类型码。不可屏蔽中断的中断过程为:

  1. 标志寄存器入栈,IF=0,TF=0
  2. CS、IP入栈
  3. (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号中断例程主要做了以下三件事

  1. 读出60H端口中的扫描码

  2. 如果扫描码是字符键的扫描码,则将该扫描码和其对应的ASCII码送入内存中的BIOS键盘缓冲区;如果是控制键(Ctrl等)或切换键(CapsLock等)的扫描码,则将其转为一个0或1的bit位(占存储状态字节的一个bit位),并写入内存中存储状态字节的单元(该单元在0040:17),如下图所示。
    状态字节单元

  3. 对键盘系统进行相关的控制,比如说,向相关芯片发出应答信息。

BIOS键盘缓冲区是系统启动后,BIOS用于存放int 9中断例程所接收的键盘输入的内存区。内存区总共可以存储15个键盘输入,由于每一次的输入除开扫描码外还有对应的字符码,所以BIOS键盘缓冲区会有30个内存单元,即30个字节。一个键盘输入用一个字单元存放,高位放扫描码,低位放字符码。

15.4 编写int 9中断例程

由于dos自带的int 9比较复杂,涉及到比较底层的内容,不用不行(比如保存状态字节,键盘缓冲区?重复的代码太多,我们就复用以下),但是还要新增自己的代码,我们可以选择组合,我们编写一个新的int 9程序,在这个程序里面调用原来dos的int 9

断更啦~~~

到目前为止,汇编的基本内容都学的差不多了。整本书里面,个人觉得最重要的就在中断这一块,因为IO处理方式和这个关系很大~
由于刚上班,时间比较紧还有很多内容需要学习,所以汇编大致学到这里,暂时够用。

posted @ 2019-06-22 18:10  CoDeleven  阅读(370)  评论(0编辑  收藏  举报