本文的框架
中断的作用
- 从用户态切换到核心态的唯一方式
- 使操作系统重新夺回CPU的控制权
中断的类型
- 其实这里所说的中断指的是外中断,内中断统称为异常
内外中断的区别:
- 内中断:中断与CPU正在执行的指令有关
- 外中断:与CPU执行的指令无关,中断来自外部硬件
陷入
- 这是应用程序自己要求进行的中断,用户程序想要调用系统调用
- 陷入其实就是应用程序实现系统调用的手段
- 陷入通过**陷入指令(trap)**实现,陷入指令可以运行在应用程序中,不是特权指令
- 陷入引发的异常在异常处理完后,可以继续执行
- 例子:其实就像C语言中的printf(“Hello World!”);其实可以看做一个陷入,这个操作需要进行系统调用,将字符串“Hello World!”输出到屏幕上
故障
- 故障是由错误条件引起的,可能会被内核程序修复
- 用户程序若可以修复故障,则在修复后会继续将CPU的使用权交给应用程序
- 典型的故障为:缺页中断(虚拟内存管理的内容)
终止
- 终止是由于程序的致命错误引起的,内核程序无法修复
- 一般不会再将CPU使用权交给应用程序,会直接剥夺处理机,终止程序
- 典型的终止为:整数除0,非法使用特权指令等
时钟中断
- 主要表现为进程的时间片轮转调度,这是实现并发的一种手段
I/O中断
- 由输入输出设备发出的中断,外部设备想要输入或输出数据
中断机制
检查中断
- 对于内中断:在执行指令的过程中检查是否有异常
- 对于外中断:每个指令周期末尾,CPU检查是否有外中断信号需要处理
处理中断过程(针对外中断)
1. 检查中断
- 在每个指令周期末尾,CPU进行中断检查,如果检查到中断,则进行中断处理
2. 中断处理
- 检查到中断之后,开始处理中断
3. 关中断
- CPU响应中断后,首先要保护程序现场状态,在保护的过程中CPU不可以响应更高优先级的中断请求。
- 如果响应了更高优先级的程序,那低优先级的程序现场保存不完整,之后处理完中断后就不能正确的回到中断前的状态
4. 保存断点
- 为保证中断服务程序执行完毕能正确的返回到原来的程序,必须将程序断点(程序计数器PC的值)保存起来
5. 寻找中断服务程序入口地址
- 实质是取出中断服务程序的入口地址送入到程序计数器PC中
- 入口地址的获取:查询"中断向量表",找到相应的中断处理程序在内存中的存放位置
6. 进入中断服务程序
- 进入中断服务程序,开始执行中断服务程序
7. 保护现场和屏蔽字
- 进入中断服务程序后的第一件事,就是保护现场和屏蔽字,主要是保存程序状态字PSWR和某些通用寄存器的内容
8. 开中断
- 允许响应更高级中断
- 此时如果有高级中断到来,可以去执行高级中断,因为被中断程序的现场信息已经被保存,响应高级中断不会导致被中断程序在恢复时现场信息不完整
9. 中断服务程序处理
- 执行中断服务程序,这也是中断的目的所在
10. 关中断
- 执行完中断服务程序,在程序结束前,要恢复现场,这个操作也不可以被打断
11. 恢复现场
- 中断服务程序将之前保存的相关寄存器的值恢复到原来的状态
12. 开中断
- 中断服务程序即将结束,重新打开中断,允许响应其他中断
13. 返回到断点继续执行
- 中断服务程序的最后一条指令通常是一条中断返回指令,使其返回到程序断点处,以便原程序继续执行
处理异常
- 依赖于当前程序的运行环境
- 异常不能被屏蔽
- 一旦出现应立即处理
小总结
- 中断处理主要包括硬件处理部分和软件处理部分
- 硬件处理:响应中断请求,关闭中断,保存断点,并且引出中断服务程序的入口地址(由中断隐指令完成)
- 软件处理:保护现场,执行中断服务程序,恢复现场,返回断点
- 在中断服务程序中恢复现场可以直接使用原语实现