Windows保护模式学习笔记(十一)—— 中断与异常
前言
一、学习自
滴水编程达人
中级班课程,官网:https://bcdaren.com
二、海东老师牛逼!
一、中断
描述:
- 中断通常是由CPU外部的输入输出设备(硬件)所触发的,供外部设备通知CPU“有事情需要处理”,因此又叫中断请求(Interrupt Request)
- 中断请求的目的是希望CPU暂时停止执行当前
正在执行
的程序,转去执行中断请求所对应的中断处理例程(中断处理程序在哪有IDT表决定) - 80x86有两条中断请求线:
- 可屏蔽中断线,称为INTR(Interrupt Require)
- 非屏蔽中断线,称为NMI(NonMaskable Interrupt)
- 假设没有中断这种机制,当一个的程序的代码为死循环时,其他的程序就没有机会执行了。
中断的本质:改变CPU的执行路线
可屏蔽中断
描述:
- 在硬件级,可屏蔽中断是由一块专门的芯片来管理的,通常称为中断控制器
- 它负责分配中断资源和管理各个中断源发出的中断请求
- 为了便于标识各个中断请求,中断管理器通常用IRQ(Interrupt Request)后面加上数字来表示不同的中断
比如:在Windows中,时钟中断的IRQ编号为0,也就是IRQ0
时钟中断
描述:
- 大多数操作系统时钟中断在10-100MS之间,Windows系列为10-20MS
- Windows时钟中断每隔10~20MS会向CPU发送一个请求,当CPU收到请求时,操作系统就会接管CPU,指定CPU去执行一段代码,操作系统在这段代码里便有机会进行线程的切换。这样,即便一个程序进入死循环,操作系统依然有机会进行线程切换
- 当然,操作系统主要并不是通过时钟中断来进行线程切换,而只是有机会进行线程切换,这里只是举个例子。
可屏蔽中断的处理
描述:
- 时钟中断的IRQ编号为0,所在位置为IDT[0x30]
- IRQ1~IRQ15分别对应IDT[0x31]~IDT[0x35]
注意:
- 如果自己的程序执行时不希望CPU去处理这些中断,可以:
- 用
CLI
指令清空EFLAG寄存器中的IF位 - 用
STI
指令设置EFLAG寄存器中的IF位
- 用
- 硬件中断与IDT表中的对应关系并非固定不变的,
参见:APIC(高级可编程中断控制器)
非可屏蔽中断
注意:
- 当非可屏蔽中断产生时,CPU在执行完当前指令后会里面进入中断处理程序
- 非可屏蔽中断不受EFLAG寄存器中
IF
位的影响,一旦发生,CPU必须处理 - 非可屏蔽中断处理程序位于IDT表中的2号位置
二、异常
描述:
异常通常是CPU在执行指令时检测到的某些错误,比如除0、访问无效页面等。
中断与异常的区别:
中断
来自于外部设备,是中断源(比如键盘)发起的,CPU是被动的异常
来自于CPU本身,是CPU主动产生的- INT N虽然被称为“软件中断”,但其本质是异常
- EFLAG的
IF位
对INT N
无效。
异常处理
描述:
无论是由硬件设备触发的中断请求还是由CPU产生的异常,处理程序都在
IDT表
常见的异常处理程序:
页错误
:当我们访问一个线性地址,而这个线性地址指向的物理页是无效的,便会触发CPU异常,该异常位于E号门(IDT[0xE])
段错误
:一旦段的运算发生异常时(如权限检查),便会走D号门(IDT[0xD])
除0错误
:当除数为0时,会触发异常,这时走0号门(IDT[0x0])
双重错误
:假设执行一个异常(如页错误)时又产生了一个错误,那么便会触发双重错误,这时走8号门(IDT[0x8])
缺页异常
缺页异常的产生(例举两种):
- 当PDE/PTE的P=0时会发生缺页异常
- 当PDE/PTE的属性为只读但程序试图写入时会发生缺页异常
一旦发生缺页异常,CPU会执行IDT表中的0xE号中断处理程序,由操作系统来接管
例1:
- 若一个物理页是有效的,那么PDE/PTE的P位一定为1
- 当其他进程的物理页发生紧缺(不够用)时,但当前线性地址是有效的(指向了这个物理页),那么操作系统就会把这个物理页的内容保存到文件里,再将这个物理页挂到别人的PDE/PTE中供其使用,最后将当前进程指向这个物理页的线性地址的PDE/PTE的P位改为0
- 再次访问这个线性地址时,操作系统发现P位为0,便会进入0xE号中断处理程序(IDT[0xE])
- 进入IDT[0xE]后,若操作系统发现
P=0
、转移位=0
、原型位=0
,而其他位都是有值的时候,就说明当前物理页被存储到了页面文件里,页面文件的位置(编号)保存在PFN
中 - 操作系统找到页面文件后,把里面的内容从文件中再次读到物理页,并将P位改回1
说明:
- 整个过程对于用户来说是完全透明的,用户并不知道发生了一个异常,只知道程序能够对地址进行正确的读写,但其实这个过程中可能有大量异常在发生
- 操作系统通过这种异常的方式节省大量物理页,当我们的程序在执行时,这种缺页异常时时刻刻在发生
例2:
- 当一个线性地址的PDE/PTE属性为只读,但试图往里写时
- CPU检测到了这个异常,但CPU没有权利处理,便进入0xE号中断处理程序(IDT[0xE]),由操作系统来接管
- 操作系统检测出用户的操作确实是不合理的,便会返回一个错误(0xC0000005,内存访问失败)
练习1:分析IDT表中0x2号中断的执行流程
略(待补充)
练习2:分析IDT表中0x8号中断的执行流程
略(待补充)