异常可分为四类,中断,陷阱,故障和终止

中断:
中断是异步发生的,是来自处理器外部的io设备的信号的结果,硬件中断不是由任何一条专门的指令造成的,从这个意义上来说它是异步的,硬件终端的异常处理程序,常常称为中断处理程序。
io设备,例如网络适配器,磁盘控制器和定时器芯片通过向处理器芯片上的一个引脚发信号,并将异常号放在系统总线上来触发中断。这个异常号标识了引起中断的设备。
当处理程序返回时,他就将控制返回给下一条指令,(即如果没有发生中断,在控制流中会在当前指令之后的那条指令),结果是程序继续执行,就好像没有发生过中断一样。

陷阱和系统调用
陷阱是有意的异常,是执行一条指令的结果。
就像中断处理程序一样,陷阱处理程序将控制返回到下一条指令,陷阱最重要的用途是在用户和程序和内核之间提供一个像过程一样的接口,叫做系统调用。
用户程序经常需要向内核请求服务,比如读一个文件,创建一个新的进程,加载一个新的程序或者终止当前的进程,为了允许对这些内核服务的受控的访问,系统会提供一些特殊的指令。当执行这些指令的时候,就会产生一个异常处理程序的陷阱。这个处理程序,解析参数,并调用适当的内核程序。如下图所示。

从程序员角度看,系统调用和普通的函数调用是一样的,然而它们的实现有非常大的不同。
普通的函数运行在用户模式下,用户模式限制了函数可执行的指令的类型,而且他们只能访问与调用函数相同的栈。系统调用运行在内核模式中,任何模式允许系统调用执行特权指令并访问定义在内核中的栈
故障
故障由错误引起,它可能够被故障处理程序修。,如果处理程序能够修正这个错误情况,它就将控制返回到引起故障的指令,从而重新执行它,否则处理程序返回到内核中的abort例程,abort例程会终止引起故障的应用程序。

一个经典的故障实例是缺页异常。当指令引用一个虚拟地址,而与该地址相应的物理页面不存在内存中,因此必须从磁盘中取出,就会发生故障。
一个页面就是虚拟内存的一个连续的块,典型的4kb。缺页处理程序从磁盘加载适当的页面,然后将控制返回给引起故障的指令,当指令再次执行时,相应的物理页面已经驻留在内存中了,指令就可以没有故障的运行完成了。
终止
终止是不可恢复的致命错误造成的结果。
通常是一些硬件错误,比如DRAM或者SRAM被破坏时发生的奇偶错误。终止处理程序从不将控制返回给应用程序。处理程序将控制返回给一个abort历程,会终止这个应用程序。

网友评论