段和页的主要知识,差不多就告一段落了,这篇文章简单介绍一下中断与异常的相关概念,结合之前学习的IDT表,形成一个整体的框架,在后续文章中,会再详细解析中断和异常的处理过程。
中断
什么是中断
- 中断通常是由CPU外部的输入输出设别(硬件)所触发的,供外部设备通知CPU“有事情需要处理”,因此又叫做中断请求(IRQ-Interrupt Request)
- 中断请求的目的是希望CPU暂时停止执行当前正在执行的程序,转去执行中断请求所对应的中断处理例程(中断处理程序在哪由IDT表决定)
- 80x86有两条中断请求线:
- 不可屏蔽中断线,称为NMI(NonMaskable Interrupt)
- 可屏蔽中断线,称为INTR(Interrupt Require)
不可屏蔽中断
(IDT表)中断号 | NMI | 说明 |
---|---|---|
0x2 | 不可屏蔽中断 | 80x86中固定为0x2 |
说明:
- 当不可屏蔽中断产生时,CPU在执行完当前指令后会立即进入2号中断,执行相应中断处理程序
- 不可屏蔽中断不受EFLAG寄存器中IF位的影响,一旦发生,CPU必须处理
可屏蔽中断
在硬件级,可屏蔽中断是由一块专门的芯片来管理的,通常称为中断控制器。它负责分配中断资源和管理各个中断源发出的中断请求。为了便于标识各个中断请求,中断控制器通常用IRQ(Interrupt Request)后面加上数字来表示不同的中断。
例如:在Windows中,时钟中断的IRQ编号为0,也就是:IRQ0
(IDT表)中断号 | IRQ | 说明 |
---|---|---|
0x30 | IRQ0 | 时钟中断 |
0x31~0x3F | IRQ1~IRQ15 | 其它硬件设备的中断 |
说明:
- 如果自己的程序执行时不希望CPU去处理这些中断,可以用CLI指令清空EFLAG寄存器中的IF位。与CLI指令相反,STI指令可以用来设置EFLAG寄存器中的IF位
- 硬件中断与IDT表中的对应关系并且固定不变的,参见APIC(高级可编程中断控制器)
异常
聊完了中断,来看看异常。异常通常是CPU在执行指令时检测到的某些错误,比如除0、访问无效页面等。
与中断的区别
- 中断来自于外部设备,是中断源(例如键盘)发起的,CPU是被动的。
- 异常来自于CPU本身,是CPU主动产生的。
- INT N虽然被称为“软件中断”,但其本质是异常。因此不受EFLAG的IF位影响。
异常处理
无论是由硬件设备触发的中断请求还是由CPU产生的异常,处理程序都在IDT表。
上图为IDT表中常见的中断向量号的相关描述,具体细节可以参考Intel白皮书第三卷(Exception And Interrupt Reference)这章
缺页异常(无时无刻不在发生)
缺页异常产生:
- 当PDE/PTE的P=0时
- 当PDE/PTE的属性为只读,但程序试图写入时
一旦发生缺页异常,CPU会执行IDT表中的0xE号中断处理程序,由操作系统接管。
这里简单概括上述两种发生缺页异常的情况:
- 在操作系统中,物理页往往是紧缺的,若当前PTE指向的物理页的内容一段时间没有被访问,则会将这个物理页上的内容存到一个文件里,同时将这个物理页挂给有需要的PTE用,并将原PTE的P位置0。当程序再次访问这段内容时,发现P位为0,则会触发缺页异常,但是此时PTE下标为10,11的位置均为0,其余位置都是有值的,这种情况说明当前PTE指向的内容存到了文件中,并根据下标1~4指定的偏移,在文件中找到内容。这时再重新给这些内容挂上新的物理页,将P位改为1,这时访问便可正常执行。当然,缺页异常对于用户来说是透明的,用户只会觉得自己正常访问了某个内容,但实际上进行了很多操作,通过缺页异常,操作系统可以节省大量物理页。
- 当PDE/PTE属性为只读时,CPU不会进行处理,而是跳到E号中断交给操作系统来处理,操作系统发现程序正在尝试写一个只读的物理页,会返回一个C0000005错误。
异常小节
当异常发生时,CPU会判断异常的种类,根据中断向量号,跳转到相应的异常处理程序,接着由操作系统接管并处理。
总结
这篇简要介绍了中断与异常,在后续讲到中断章节时,会更加详细的分析过程原理。