1. 间断和反常的概念差异
Intel的官方文档里将间断和反常了解为两种间断当时程序履行的不同机制。这是间断和反常的共同点。不同点在于:
间断(interrupt)是异步的事情,典型的比方由I/O设备触发;反常(exception)是同步的事情,典型的比方处理器履行某条指令时发现出错了等等。
间断又可以分为可屏蔽间断和非可屏蔽间断,反常又分为毛病、圈套和反常间断3种,它们的详细差异许多书本和官方文档都解说的比较清楚这儿不再赘述。
关于它们的差异有两点是需求留意的:
1)往常所说的屏蔽间断是不包含反常的,即反常不会由于CPU的IF位被清(关间断,指令:cli)而受影响,比方缺页反常,即便关了间断也会触发CPU的处理。
2)一般说的int 80h这种体系调用运用的间断方法实际上硬件上是了解为反常处理的,因而也不会被屏蔽掉,这也很好了解,int 80h这种间断方法是程序里自动触发的,关于CPU来说归于同步事情,因而也就归于反常的领域。
2. 间断(反常)处理进程
需求清晰的一点是CPU关于间断和反常的详细处理机制本质上是完全一致的,即:
当CPU收到间断或许反常的信号时,它会暂停履行当时的程序或使命,经过必定的机制跳转到担任处理这个信号的相关处理程序中,在完结对这个信号的处理后再跳回到方才被打断的程序或使命中。这儿只描绘维护形式下的处理进程,搞清楚了维护形式下的处理进程(更杂乱),实形式下的处理机制也就简单了解了。
详细的处理进程如下:
0)间断呼应的事前预备:
体系要想可以应对各种不同的间断信号,总的来看便是需求知道每种信号应该由哪个间断服务程序担任以及这些间断服务程序详细是怎么作业的。体系只要事前对这两件事都知道得很清楚,才干正确地呼应各种间断信号和反常。
[a]体系将一切的间断信号一致进行了编号(总共256个:0~255),这个号称为间断向量,详细哪个间断向量表明哪种间断有的是规定好的,也有的是在给定范围内自行设定的。
间断向量和间断服务程序的对应联系主要是由IDT(间断向量表)担任。操作体系在IDT中设置好各种间断向量对应的间断描绘符(总共有三类间断门描绘符:使命门、间断门和圈套门),留下CPU查询运用。而IDT自身的方位是由idtr保存的,当然这个地址也是由OS填充的。
[b]间断服务程序详细担任处理间断(反常)的代码是由软件,也便是操作体系完结的,这部分代码归于操作体系内核代码。也便是说从CPU检测间断信号到加载间断服务程序以及从间断服务程序中康复履行被暂停的程序,这个流程基本上是硬件承认下来的,而详细的间断向量和服务程序的对应联系设置和间断服务程序的内容是由操作体系承认的。
1)CPU查看是否有间断/反常信号
CPU在履行完当时程序的每一条指令后,都会去承认在履行方才的指令进程中间断控制器(如:8259A)是否发送间断请求过来,假如有那么CPU就会在相应的时钟脉冲到来时从总线上读取间断请求对应的间断向量[2]。
关于反常和体系调用那样的软间断,由于间断向量是直接给出的,所以和经过IRQ(间断请求)线发送的硬件间断请求不同,不会再专门去取其对应的间断向量。
2)依据间断向量到IDT表中获得处理这个向量的间断程序的段选择符
CPU依据得到的间断向量到IDT表里找到该向量对应的间断描绘符,间断描绘符里保存着间断服务程序的段选择符。
3)依据获得的段选择符到GDT中找相应的段描绘符
CPU运用IDT查到的间断服务程序的段选择符从GDT中获得相应的段描绘符,段描绘符里保存了间断服务程序的段基址和特点信息,此刻CPU就得到了间断服务程序的开端地址。
这儿,CPU会依据当时cs寄存器里的CPL和GDT的段描绘符的DPL,以确保间断服务程序是高于当时程序的,假如这次间断是编程反常(如:int 80h体系调用),那么还要查看CPL和IDT表中间断描绘符的DPL,以确保当时程序有权限运用间断服务程序,这可以避免用户应用程序拜访特别的圈套门和间断门[3]。
4)CPU依据特权级的判别设定行将运转的间断服务程序要运用的栈的地址
CPU会依据CPL和间断服务程序段描绘符的DPL信息承认是否发生了特权级的转化,比方当时程序正运转在用户态,而间断程序是运转在内核态的,则意味着发生了特权级的转化,这时CPU会从当时程序的TSS信息(该信息在内存中的首地址存在TR寄存器中)里获得该程序的内核栈地址,即包含ss和esp的值,并立行将体系当时运用的栈切换成新的栈。这个栈便是行将运转的间断服务程序要运用的栈。紧接着就将当时程序运用的ss,esp压到新栈中保存起来。
6)维护当时程序的现场
CPU开端运用栈维护被暂停履行的程序的现场:顺次压入当时程序运用的eflags,cs,eip,errorCode(假如是有错误码的反常)信息。
官方文档[1]给出的栈改变的示意图如下:
7)跳转到间断服务程序的第一条指令开端履行
CPU运用间断服务程序的段描绘符将其第一条指令的地址加载到cs和eip寄存器中,开端履行间断服务程序。这意味着从前的程序被暂停履行,间断服务程序正式开端作业。
8)间断服务程序处理完毕,康复履行从前间断的程序
在每个间断服务程序的最终,必须有间断完结回来从前程序的指令,这便是iret(或iretd)。程序履行这条回来指令时,会从栈里弹出从前保存的被暂停程序的现场信息,即eflags,cs,eip重新开端履行。