异常控制流概述与异常

一、异常控制流的概述

1、控制流是什么

从给处理器加电开始,直到你断电为止,PC假设一个值的序列a0,a1,……,an-1。其中,每个ak是某个相应的指令Ik的地址。每次从ak到ak+1的过渡称为控制转移。这样的控制转移序列就叫做处理器的控制流

由此可以知道,最简单的控制流就是一个“平滑的”序列,每个Ik和Ik+1都是相邻的;对于诸如跳转、过程调用和返回这样的一些熟悉的控制指令会造成这种“平滑流”的突变(也就是Ik与Ik+1不相邻)。

这些突变都是必要的,因为这些机制使得程序能够更加灵活,能够对由程序变量便是德内部程序状态的变化做出反应。

2、异常控制流(ECF)的诞生

不仅仅是程序,对于系统也必须能够对系统状态做出反应,这些系统状态不是被内部程序变量捕获的,而且也不一定要和程序的执行相关。
比如:一个硬件定时器定期产生信号,这个事件必须得到处理;当子进程终止时,创造这些子进程的父进程必须得到通知等

现代处理器是通过控制流突变来对这些情况作出反应。我们把这些突变称为异常控制流(Exceptional Control Flow,ECF)

异常控制流发生在计算机系统的各个层次:
1) 在硬件层,硬件检测到的事件会触发控制突然转移到异常处理程序
2) 在操作系统层,内核通过上下文切换将控制从一个用户进程转移到另一个用户进程
3) 在应用层,一个进程可以发送信号到另一个进程,而接收者会将控制突然转移到它的一个信号处理程序

3、ECF的重要性

1) 帮助你理解重要的系统概念
ECF是操作系统用来实现I/O、进程和虚拟内存的基本机制。

2) 帮助逆理解应用程序时候如何与操作系统交互的
应用程序通过使用一个叫做**“陷阱”或者系统调用**的ECF形式,向操作系统请求服务。

3) 帮助你编写有趣的新应用程序
操作系统为应用程序提供了强大的ECF机制,用来创建新进程、等待进程终止、通知其他进程系统中的异常事件,以及检测和响应这些事件。我们可以学会使用这些机制,来编写诸如Unix shell和Web 服务器之类的有趣程序

4) 帮助你理解并发
ECF是计算机系统中实现并发的基本机制。
在运行中并发的例子有:中断应用程序执行的异常处理程序,在时间上重叠执行的进程和线程等

5) 帮助逆理解软件异常如何工作
C++和Java这类的语言通过try catch以及throw语句来提供软件异常机制。软件异常允许程序进行非本地跳转来响应错误情况。非本地跳转是一种应用层ECF。

4、从硬件到软件,从底层到顶层的学习逻辑

1) 异常——硬件和操作系统交界的部分
2) 系统调用——为应用程序提供到操作系统的入口点的异常
3) 进程和信号——应用和操作系统的交界之处
4) 非本地跳转——应用层

二、异常

1、异常的定义

异常是异常控制流的一种形式,它一部分由硬件实现,一部分由操作系统实现。
异常就是控制流中的突变,用来响应处理器状态中的某些变化。

2、异常的剖析:

在这里插入图片描述
Icurr代表处理器正在执行某个当前指令。**在处理器中,状态被编码为不同的位和信号,状态变化称为事件。**事件可以与当前指令相关(如缺页异常,除以0的异常),也可以与当前指令不相关(如I/O请求)。

3、异常的处理

1)异常表: 在任何情况下,处理器检测到事件发生,会通过异常表(一种跳转表)进行间接过程调用(异常),到专门处理这种异常的操作系统子程序(异常处理程序)。
2)异常号: 系统中每种类型的异常都分配了一个唯一的非负整数的异常号。
3)异常表基址寄存器: 当系统启动时,操作系统分配和初始化异常表,使得表木k包含异常k的处理程序地址;在运行时,处理器发现异常后,执行间接过程调用。异常表的起始地址存放在一个叫异常表基址寄存器的特殊CPU寄存器里。
在这里插入图片描述

4、异常与过程调用的区别

1) 过程调用时,在跳转到处理程序前,处理器会将返回地址压入栈中,返回地址一般为下一条指令;发生异常时,异常的返回地址要么是当前指令,要么是下一条指令。
2) 过程调用时,必要时只保存一些寄存器的状态和一些实参的传递;发生异常时还需要把一些额外的处理器状态压入到栈中进行保存。
3) 过程调用时,只在用户程序间进行转移,是对用户栈操作;发生异常时,如果控制是从用户程序转移到内核,所有这些项目都被压到内核栈中,而不是压到用户栈中。
4) 过程调用时,其模式一般为用户模式;而异常处理程序运行在内核模式下,处理完后,如果异常中断的是一个用户程序,就将状态恢复为用户模式。

5、异常的类别

1)中断(异步发生)

中断是来自处理器外部的I/O设备的信号的结果。硬件中断不是由任何一条专门的指令造成的,从这个意义上了来说它是异步的。硬件终端的异常处理程序称为中断处理程序
在这里插入图片描述中断处理程序返回时,处理器将控制返回给下一条指令。

2)陷阱和系统调用(同步发生)

陷阱是有意的异常,是执行一条指令的结果。
系统调用: 在用户程序和内核之间提供了一个像过程一样的接口,是陷阱最重要的用途。

用户程序经常需要向内核请求服务,比如读一个文件(read)、创建一个新的进程(fork)等,为了允许对这些内核服务的受控的访问,处理器提供了一条特殊指令**“syscall n”**,当用户想要请求服务n时,可以执行这条指令。
在这里插入图片描述
陷阱处理程序返回时,处理器将控制返回给下一条指令。

3)故障

故障由错误情况引起,他可能能够被故障处理程序修正。
在这里插入图片描述
a)能够修正——控制返回到引起故障的指令
b)不能修正——返回到内核中的abort例程,终止引起故障的应用程序。

经典的故障实例:缺页异常。

4)终止

终止是不可恢复的致命错误造成的结果,通常是一些硬件错误。
终止处理程序不将控制返回给应用程序,返回给内河中的abort例程,该例程会终止这个程序。

总结如下图:
在这里插入图片描述

三、收获、问题与思考(有些问题待解决)

收获

1、控制流是一种底层思维,控制流的突变以及突变后的处理,处理后的措施(如何返回到正常运行),这是需要自己长期体会的一个模式框架。
2、关于硬件、操作系统、应用程序这计算机三个层次间的交互有了初步了解,其基本都是通过异常控制流来实现的
3、我们常听到这样一句话:计算机世界的绝大部分问题都可以通过分层的方法来解决。
异常也能体现分层思想。他是主要用来完成不同层次的交互,来使得系统能够应对各种变化;同时异常的实现也是用的分层,比如异常表基址寄存器的使用,到访问异常表,再访问异常处理程序,这样的设计是为了性能,寄存器访问最为迅速,每次异常都需要,就直接放到寄存器中,越往后其访问的频率越低。
4、异常的不同类型,其触发方式、返回内容都不尽相同

问题

1、用户模式与内核模式有何具体的区别?
2、硬件、操作系统、应用程序这三个层次具体是如何通过异常交互来完成一个程序的?(从高级语言->汇编语言->机器语言->硬件执行)
3、计算机的层次结构:硬件层+操作系统层+应用程序层。为什么要有这种层次?操作系统的作用是什么?

思考

1、通过这些系统调用,我们可以接触到操作系统即内核部分,那我们可以做一些很有趣的事情(病毒可能就是通过这种方式,从一个程序影响到其他程序,可以把病毒理解为非法的交互)。
2、我们在做开发的时候,对于一些bug,可以站在异常的角度进行思考!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Toser

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值