控制流(control flow)、
从给处理器加电开始,直到断电为止,程序计数器假设一个值的序列 a0,a1,...,an−1 其中,每个 ak 是某个相应的指令 Ik 的地址。每次从 ak 到 ak+1 的过度称为控制转移(control transfer)。这样的控制转移序列叫做处理器的控制流(flow of control 或 control flow)。最简单的控制流是一个“平滑”序列,这里平滑的意思是ak 和ak+1在内存中是相邻的两条指令,如果平滑的控制流发生了突变,也就是ak和ak+1不相邻,这种情况通常是由跳转,函数调用和返回这类指令造成的,这类指令导致的突变属于必要的机制。
异常控制流、
现代系统通过使控制流发生突变来对某些情况做出反应。一般而言,我们把这些突变称为异常控制流(Exceptional Control Flow,ECF)。异常控制流发生在计算机系统的各个层次。比如,在硬件层,硬件检测到的事件会触发控制突然转移到异常处理程序。在操作系统层,内核通过上下文将控制从一个用户进程转移到另一个用户进程。在应用层,一个进程可以发送信号到另一个进程,而接收者会将控制突然转移到它的一个信号处理程序。一个程序可以通过回避通常的栈规则,并执行到其他函数中任意位置的的非本地跳转来对错误做出反应。
理解异常控制流、
- 1)可以帮助程序员理解重要的系统概念,异常控制流是操作系统用来实现I/O,进程以及虚拟内存的基本机制。
- 2)可以帮助理解应用程序是如何与系统交互的。
- 3)理解异常控制流可以帮助我们编写一些有趣的程序
- 4)理解异常控制流可以帮助我们理解并发,异常控制流是计算机系统实现并发的基本机制
- 5)可以帮助我们理解软件异常是如何工作的,在C++中提供了 try--catch--throw 语句来捕获软件异常
异常、
当处理器正在指向应用程序中的某一条指令时,此时系统发生了一个事件,这个事件可能和当前指令的执行直接相关,也可能无关,例如当前指令执行的是除以0的操作,那么此时异常的发生就与当前指令有关;如果事件是一个I/O的请求操作,那就与当前指令无关。在任何情况下,在处理器检测到有事件发生时,接下来处理器从执行应用程序切换到异常处理程序,当异常处理程序完成后,根据引起异常的事件类型选择是否返回。

异常处理、
系统为可能发生的每种类型的异常都分配了一个唯一的非负整数的异常编号(exception number)。一部分是由处理器的设计者分配,其他号码时由操作系统内核的设计者分配的。前者包括:除零、缺页等。后者包括:系统调用和来自外部的I/O设备的信号。
在系统启动时,操作系统分配和初始化一张称为异常表的跳转表,使得条目k包含异常k的处理程序的地址,异常号就是跳转表的索引号,异常表的起始地址保存在CPU的一个特殊的寄存器中,通过起始地址和索引能够确定对应的异常处理程序。如下图:

在运行时(当系统在执行某个程序时),处理器检测到发生一个事件,并且确定了相应的异常号k,随后通过异常表的条目k转到相应的异常处理程序。异常处理类似于一个间接的函数调用,不过二者之间还有一些重要的不同之处。
当发生函数调用时,在跳转到目的函数之前,处理器会将返回地址压入栈中,然而根据异常的类型,返回地址要么是当前的指令,要么是下一条指令。处理器在处理异常时,会把处理器额外的一些状态压倒栈中,当重新开始执行被中断的程序时,需要这些状态。异常处理程序是运行在内核态的,所以它们对所有的系统资源都有访问权限。
一旦硬件出发了异常,剩下的工作就是由异常处理程序在软件中完成。
当异常处理程序完成处理后,根据引起异常的事件的类型,会发生以下三种情况中的一种:
- 处理程序将控制返回给当前指令 Icurr ,即当事件发生时正在执行的指令。
- 处理程序将控制返回给 Inext ,即如果没有发生异常将会执行的下一条指令。
- 处理程序终止被中断的程序。
异常的类别、
异常可以分为四类:中断(interrupt)、陷阱(trap)、故障(fault)和终止(abort)。下图对这些类别的属性做了小结:

异步的含义是由处理器外部的I/O设备产生的,同步是CPU执行当前指令产生的结果。所以这里的同步和异步的主要区别是异常产生的原因来自CPU外部还是内部。
在x86-64系统中,一共定义了256种异常类型,其中0-31号异常是由intel的架构师定义的,因此对于任意的x86-64系统都是一样的。编号32-255对应的异常是由操作系统定义。
Comments NOTHING