异常控制流
异常控制流:
从个处理器加电开始,知道断电为止,程序计数器假设一个序列的值 a0 ,a1 ,a2 …..an-1 其中每个ak是某个相应地指令I k的地址,每次从ak到ak+1的过度称为控制转移.这样的控制转移叫做处理器的控制流(control flow).
最简单的一种控制流是一种平滑的序列,其中Ik和Ik+1在存储器中都是相邻的. 这种平滑的突变,也就是Ik+1与IK不相邻,是由诸如跳转,调用和返回这样一些程序指令造成的.
异常控制流(exceptional control flow)ECF:
理解ECF 很重要:
ECF是重要的操作系统概念.ECF 是操作系统用来实现I/O,进程和虚拟存储器的基本机制. 在你真真理解这些概念之前,你必须理解ECF
理解ECF有助于你理解应用程序是如何与操作系统交互的.应用程序通过使用一个叫做陷阱(trap)或者系统调用(system call)的ECF ,向操作系统请求服务.比如,向磁盘写数据,从网络读取数据,创建一个新的进程,以及终止当前进程都是通过应用程序提交系统调用来实现的.
理解ECF将帮助你编写有趣的新的应用程序/ 操作系统为用用程序提供了强大的ECF机制.用来创建新进程,等待进程终止,通知其它进程中的异常事件,以及检测和响应这些事件.如果你了解这些ECF机制,那么你就能够用他们来编写诸如 unix shell 和web 服务器之类的有趣程序了.
理解ECF 将帮助你理解软件异常如何工作.像C++ 和java 这样的语言通过try catch 以及throw 语句来提供软件异常机制.软件异常允许程序进行非本地跳转,(也就是,违反通常的调用/返回栈的跳转),来响应错误情况
异常(exception) 就是控制流中的突变,用来响应处理器状态中的某些变化
In the figure, the processor is executing some current instruction when a significant change in the processor’s state occurs. The state is encoded in various bits and signals inside the processor. The change in state is known as an event. The event might be directly related to the execution of the current instruction. For example, a virtual memory page fault occurs, an arithmetic overflow occurs, or an instruction attempts a divide by zero. On the other hand, the event might be unrelated to the execution of the current instruction. For example, a system timer goes off or an I/O request completes.
In any case, when the processor detects that the event has occurred, it makes an indirect procedure call (the exception), through a jump table called an exception table, to an operating system subroutine (the exception handler) that is specifically designed to process this particular kind of event.
When the exception handler finishes processing, one of three things happens, depending on the type of event that caused the exception:
The handler returns control to the current instruction , the instruction that was executing when the event occurred.The handler returns control to the instruction that would have executed next had the exception not occurred.
- The handler aborts the interrupted program.
在此图中,当处理器状态中一个重要的边变化发生时,处理器正在执行某个当前指令. 在处理器中,状态被编码成不同的位和信号.状态的变化称为事件(even ) 事件有可能和当前指令的执行直接相关.比如, 发生虚拟存储器缺页, 算数溢出,或一条指令试图除以零 .另一方面,事件可能和当前指令的执行无关,比如 ,一个系统定时器产生信号或者一个I/O请求完成.
在任何情况中,当处理器检测到有时间发生时,就会通知一张叫做异常表(exception table) 的跳转表, 进行一个间接过程调用(异常) ,到一个专门设计的用来处理这类时间的操作系统子程序----异常处理程序(exception handler)
当异常处理程序完成处理后, 根据引起异常的时间的类型,会发生一下三种情况中的一种:
1处理程序将控制返回给当前指令(当事件发生时指令正在执行).
2处理程序将控制返回给下一条指令(如果没有异常将会执行的下一条指令).
3处理程序终止被中断的程序.
Each type of possible exception in a system is assigned a unique non-negative integer exception number. Some of these numbers are assigned by the designers of the processor. Other numbers are assigned by the designers of the operating system kernel (the memory-resident part of the operating system). Examples of the former include divide by zero, page faults, memory access violations, breakpoints, and arithmetic overflows. Examples of the latter include system calls and signals from external I/O devices.At system boot time (when the computer is reset or powered on) the operating system allocates and initializes a jump table called an exception table, so that entry contains the address of the handler for exception Figure 8.2 shows the format of an exception table.
系统中可能的每种类型的都分配了一个唯一的非负数正数的异常号(exception number) .这些号码中的某一些是由处理器的设计者分配的,其它号码是由操作系统内核(操作系统常驻存储器的部分)的设计者分配的.前者的示例包括虚拟存储器缺页, 算数溢出,或一条指令试图除以零.后者的实列包括系统调用和来自外部I/O
在系统启动时,操作系统分配和初始化一张称为异常处理表的跳转表,使得标目包含异常K的处理程序的地址.如图展示了一张异常表的格式:
异常号是到异常表中的索引,异常表的起始位置的地址放在一个叫做异常表基寄存器( exception table base register 的特殊CPU 寄存器里)
异常类似于过程调用,但是有一些重要的不同之处:
1过程调用时在跳转到处理程序之前,处理器将返回地址压入到栈中,然而,根据异常处理的类型,返回地址要么是当前指令,要么是下一条指令
2处理器也把一些额外的处理器状态压到栈里,在处理程序返回时,重新开始被中断的程序会需要这些状态.
3如果控制从一个用户程序转移到内核,所有这些目(item) 都被压入内核,而不是压入到用户栈中;
4异常处理运行在内核模式下,这意味着他对所有的系统资源都有完全的访问权.
异常的类别:
异常可以分为四类: 中断(interrupt) ,陷阱(trap) ,故障(fault) ,和终止(abort)
用户程序经常要向内核请求服务,比如读一个文件,创建一个进程或者终止当前进程,加载一个新的程序.为了对这些内核服务的受控制访问,处理器提供了一条特殊的syscall n 指令.当用户程序想请求服务n时,可执行这条指令.执行这条指令会导致一个到异常处理程序的陷阱,这个处理程序对参数解码,并调用适当的内核程序.
从一个程序员的角度看,系统调用和普通的函数调用是一样的,然而,他们的实现是非常不同的.普通的函数运行在用户模式(user model) 中,用户模式限制了函数可以执行的指令类型,而且它只能访问与调用函数形同的栈.系统调用运行在内核模式(kernel model) 中,内核模式允许系统调用执行指令,并访问定义在内核中的栈.
故障
故障有错误情况引起,他可能被故障处理程序修正.故障的一个经典数列就是缺页异常,当指令引用一个虚拟地址,而该地址相对应的物理地址不存在存储器中,因此必须从磁盘中取出时,就会发生故障.一个页面就是一个虚拟存储器的一个连续的快,(典型的四KB).缺页处理程序从磁盘加载适当的页面,然后将控制返回引起故障的指令.当指令再次执行时,相应地物理页面已经驻留在存储器中了,指令就可以没有故障的运行了.
终止
终止是一些不可恢复的致命错误早成的结果,,比如DRAM,SRAM的位被损坏是发生的奇偶错误.终止处理程序不将控制返回还给应用程序.