Loading [MathJax]/jax/input/TeX/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >重学计算机组成原理(十二) - 异常和中断

重学计算机组成原理(十二) - 异常和中断

原创
作者头像
JavaEdge
修改于 2019-10-22 02:36:19
修改于 2019-10-22 02:36:19
97900
代码可运行
举报
文章被收录于专栏:JavaEdgeJavaEdge
运行总次数:0
代码可运行

1 概览

完好的程序都满足以下特征

  • 自动运行 我们的程序和指令都是一条条顺序执行,不需要通过键盘或者网络给这个程序任何输入
  • 正常运行 没有遇到计算溢出之类的程序错误。

不过,现实的软件世界可没有这么简单

  • 程序不仅是简单的执行指令,更多的还需要和外部的输入输出打交道
  • 程序在执行过程中,还会遇到各种异常情况,比如除以0、 溢出,甚至我们自己也可以让程序抛出异常。

遇到这些情况,计算机是怎么运转的呢,也就是说,计算机究竟是如何处理异常的

2 异常:硬件、系统和应用的组合拳

2.1 软件 还是 硬件 异常?

一提到异常 (Exception),可能你的第一反应就是Java中的Exception。 不过我们今天讲的,并不是这些软件开发过程中遇到的“软件异常” 而是和硬件、系统相关 的“硬件异常”。

当然,“软件异常”和“硬件异常”并不是业界使用的专有名词,只是我为了方便给你说明,和Java中软件抛出的Exception进行的人为区分,你明白这个意思就好。

尽管,这里我把这些硬件和系统相关的异常,叫作“硬件异常”。但是,实际上,这些异常,既有来自硬件的,也有来自软件层面的。

比如,我们在

  • 硬件层面 当加法器进行两个数相加的时候,会遇到算术溢出 或者,你在玩游戏的时候,按下键盘发送了一个信号给到CPU,CPU要去执行一个现有流程之外的指令,这也是 一个“异常”

同样,来自

  • 软件层面 比如我们的程序进行系统调用,发起一个读文件的请求。这样应用程序向系统调用发起请求的情况,一样是通过“异常”来实现的。

2.2 异常的一生

异常, 其实是一个硬件和软件组合到一起的处理过程。

  • 异常的前半生 异常的发生和捕捉,在硬件层面完成
  • 异常的后半生 异常的处理,其实是由软件来完成的!

2.3 异常代码

计算机会为每一种可能会发生的异常,分配一个异常代码(Exception Number) 异常代码也叫作中断向量(Interrupt Vector)。

异常发生的时候,通常是CPU检测到了一个特殊的信号。 比如

  • 你按下键盘上的按键,输入设备就会给CPU发一个信号
  • 正在执行的指令发生了加法溢出,同样,我们可以有一个进位溢出的信号

这些信号呢,在组成原理,一般叫发生了一个事件(Event) CPU在检测到事件的时候,其实也就拿到了对应的异常代码。 这些异常代码里

  • I/O发出的信号的异常代码,是由操作系统来分配的,也就是由软件来设定的
  • 像加法溢出这样的异常代码,则是由CPU预先分配好的,也就是由硬件来分配的. 这又是另一个软件和硬件共同组合来处理异常的过程

拿到异常代码之后,CPU就会触发异常处理的流程 计算机在内存里,会保留一个异常表 (Exception Table)。 也叫中断向量表(Interrupt Vector Table),好和上面的中断向量对应起来。

这个异常表有点儿像我们在之前的GOT表,存放的是不同的异常代码对应的异常处理程序(Exception Handler)所在的地址

2.4 异常处理程序流程

我们的CPU在拿到了异常码后

  • 首先, 把当前的程序执行的现场,保存到程序栈
  • 然后, 根据异常码查询,找到对应的异常处理程序
  • 最后, 把后续指令执行的指挥权,交给这个异常处理程序

这样“检测异常 => 拿到异常码 => 再根据异常码进行查表处理”的模式,在日常开发的过程中是很常 见的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
flowchat
st=>start: 开始
e=>end: 结束
op1=>operation: 检测异常
op2=>operation: 拿到异常码
op3=>operation: 再根据异常码进行查表处理

st->op1->op2->op3
op3->e

比如说

Web或者App开发

通常都是前后端分离的

  • 前端应用,会向后端发起HTTP请求
  • 当后端遇到了异常,通常会给到前端一个对应的错误代码
  • 前端的应用根据这个错误代码,
    • 在应用层面去进行错误处理
    • 在不能处理的时候,它会根据错误代码向用户显示错误信息。
Java里面

可以设定ExceptionHandler,来处理线程执行中的异常情况

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class LastChanceHandler implements Thread.UncaughtExceptionHandler {

    @Override
    public void uncaughtException(Thread t, Throwable e) {
        // do something here - log to file and upload to    
        // server/close resources/delete files...
    }
}

Thread.setDefaultUncaughtExceptionHandler(new LastChanceHandler());
使用一个线程池去运行调度任务的时候

可以指定一个异常处理程序。 对于各个线程在执行任务出现的异常情况,我们是通过异常处理程序进行处理,而不是在实际的任务代码里处理。 这样,我们就把业务处理代码就和异常处理代码的流程分开了。

3 异常的分类

异常可以由硬件触发,也可以由软件触发

3.1 中断(Interrupt)

顾名思义,就是程序在执行到一半的时候,被打断了。这个打断执行的信号,来自于CPU外部的I/O设备。 你在键盘上按下一个按键,就会对应触发一个 相应的信号到达CPU里面。CPU里面某个开关的值发生了变化,也就触发了一个中断类型的异常。

3.2 陷阱(Trap)

程序员“故意“主动触发的异常。就好像你在程序里面打了一个断点,这个断点就是设下的一个"陷阱"。 当程序的指令执行到这个位置的时候,就掉到了这个陷阱当中。然后,对应的异常处理程序就会来处理这个"陷阱"当中的猎物。

最常见的一类陷阱,应用程序调用系统调用的时候,也就是从用户态切换到内核态的时候。

可以用Linux下的time指令,去查看一个程序运行实际花费的时间,里面有在用户态花费的时间(user time),也有在内核态发生的时间 (system time)。

应用程序通过系统调用去读取文件、创建进程,其实也是通过触发一次陷阱来进行的。这是因为用户态的应用程序没有权限来做这些事情,需要把对应的流程转交给有权限的异常处理程序来进行。

3.3 故障(Fault)

陷阱是我们开发程序的时候刻意触发的异常,而故障通常不是。 比如,我们在程序执行的过程中,进行加法计算发生了溢出,其实就是故障类型的异常。 这个异常不是我们在开发的时候计划内的,也一样需要有对应的异常处理程序去处理。

故障和陷阱、中断的重要区别

故障在异常程序处理完成之后,仍然回来处理当前的指 令,而不是去执行程序中的下一条指令。 因为当前的指令因为故障的原因并没有成功执行完成。

3.4 中止(Abort)

与其说这是一种异常类型,不如说这是故障的一种特殊情况。 当CPU遇到了故障,但是恢复不过来的时候,程序就不得不中止了。

3.5小结

中断异常的信号来自系统外部,而不是在程序自己执行的过程中,所以我们称之为“异步”类型的异常。

而陷阱、故障以及中止类型的异常,是在程序执行的过程中发生的,所 以我们称之为“同步“类型的异常。

在处理异常的过程当中,无论是异步的中断,还是同步的陷阱和故障,我们都是采用同一套处理流程,也就是上面所说的,“保存现场、异常代码查询、异常处理程序调用“。 而中止类型的异常,其实是在故障类型异常的一种特殊情况。当故障发生,但是我们发现没有异常处理程序能够处理这种异常的情况下,程序就不得不进入中止状态,也就是最终会退出当前的程序执行。

4 异常的处理:上下文切换

在实际的异常处理程序执行之前,CPU需要去做一次“保存现场”的操作。这个保存现场的操作, 和函数调用的过程非常相似。

切换到异常处理程序,就好像是去调用一个异常处理函数。指令的控制权被切换到了另外一个"函数",所以我们自然要把当前正在执行的指令去压栈。 这样才能在异常处理程序执行完后,重新回到当前的指令继续往下执行。

不过,切换到异常处理程序,比起函数调用,还是要更复杂一些。原因有下面几点

  • 异常情况往往发生在程序正常执行的预期之外,比如中断、故障发生的时候。所以,除了本来程序压栈要做的事情之外,还需要把CPU内当前运行程序用到的所有寄存器, 都放到栈里面。最典型的就是条件码寄存器里面的内容
  • 像陷阱这样的异常,涉及程序指令在用户态和内核态之间的切换。对应压栈的时候,对应的数据是压到内核栈里,而不是程序栈里。
  • 像故障这样的异常,在异常处理程序执行完成之后。从栈里返回出来,继续执行的不是顺序的下一条指令,而是故障发生的当前指令。因为当前指令因为故障没有正常执行成功,必须重新去执行一次。

所以,对于异常这样的处理流程,不像是顺序执行的指令间的函数调用关系。而是更像两个不同的独立进程之间在CPU层面的切换,所以这个过程我们称之为上下文切换(Context Switch)。

5 总结

计算机里的“异常”处理流程。这里的异常可以分成中断、陷阱、故障、中止 这样四种情况。这四种异常,分别对应着I/O设备的输入、程序主动触发的状态切换、异常情况下的程序出错以及出错之后无可挽回的退出程序。 当CPU遭遇了异常的时候,计算机就需要有相应的应对措施。CPU会通过“查表法”来解决这个问 题。在硬件层面和操作系统层面,各自定义了所有CPU可能会遇到的异常代码,并且通过这个异 常代码,在异常表里面查询相应的异常处理程序。在捕捉异常的时候,我们的硬件CPU在进行相 应的操作,而在处理异常层面,则是由作为软件的异常处理程序进行相应的操作。 而在实际处理异常之前,计算机需要先去做一个“保留现场”的操作。有了这个操作,我们才能在异常处理完成之后,重新回到之前执行的指令序列里面来。这个保留现场的操作,和我们之前讲 解指令的函数调用很像。但是,因为“异常”和函数调用有一个很大的不同,那就是它的发生时间。函数调用的压栈操作我们在写程序的时候完全能够知道,而“异常”发生的时间却很不确定。 所以,“异常”发生的时候,我们称之为发生了一次“上下文切换”(Context Switch)。这个时 候,除了普通需要压栈的数据外,计算机还需要把所有寄存器信息都存储到栈里面去。

推荐阅读

关于异常和中断,《深入理解计算机系统》的第8章“异常控制流”部分,有非常深入和充分的讲解,推荐你认真阅读一下。

思考

很多教科书和网上的文章,会把中断分成软中断和硬中断。你能用自己的话说一说,什么是软中 断,什么是硬中断吗?它们和我们今天说的中断、陷阱、故障以及中止又有什么关系呢? 欢迎留言和我分享你的疑惑和见解。你也可以把今天的内容,分享给你的朋友,和他一起学习和 进步。

参考

https://www.cnblogs.com/luoahong/p/11425628.html#top 深入理解计算机系统(第三版)

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
重学计算机组成原理(十二) - 异常和中断
一提到异常 (Exception),可能你的第一反应就是Java中的Exception。 不过我们今天讲的,并不是这些软件开发过程中遇到的“软件异常” 而是和硬件、系统相关 的“硬件异常”。
JavaEdge
2020/05/27
1.5K0
重学计算机组成原理(十二) - 异常和中断
计算机组成原理笔记(三)
超线程的CPU,其实是把一个物理层面CPU核心,“伪装”成两个逻辑层面的CPU核心。这个CPU,会在硬件层面增加很多电路,使得我们可以在一个CPU核心内部,维护两个不同线程的指令的状态信息。
luozhiyun
2020/03/19
6070
中断和异常
异常通常分为2类:一类是编程错误,另外一类就是需要内核处理的异常情况。编程错误,比如程序异常终止,处理这种异常,内核只需要给当前进程发送一个信号即可。而需要内核处理的异常,比如页错误、通过汇编语言指令比如int或sysenter等请求内核服务等,需要内核作出相应的处理。
Tupelo
2022/08/15
1.5K0
10_异常与中断
本章处理器架构的内容主要来自于ARM® Cortex™-A Series Programmer’s Guide version4.0。
韦东山
2022/05/05
1.5K0
10_异常与中断
中断机制和中断描述符表、中断和异常的处理
该文介绍了中断和异常的基本概念、分类,以及Linux 中中断和异常的处理方式,包括硬件中断、软件中断和异常的分类和处理。
s1mba
2017/12/28
3.9K0
中断机制和中断描述符表、中断和异常的处理
【操作系统】操作系统运行环境——中断与异常
在上一篇内容中我们介绍了处理器的运行模式。在计算机系统中,CPU通常会执行两种不同性质的程序:
蒙奇D索隆
2024/12/20
1960
【操作系统】操作系统运行环境——中断与异常
Linux中断一网打尽(1) —— 中断及其初始化
既然叫中断, 那我们首先就会想到这个中断是中断谁?想一想计算机最核心的部分是什么?没错, CPU, 计算机上绝大部分的计算都在CPU中完成,因此这个中断也就是中断CPU当前的运行,让CPU转而先处理这个引起中断的事件,通常来说这个中断的事件比较紧急,处理完毕后再继续执行之前被中断的task。比如,我们敲击键盘,CPU就必须立即响应这个操作,不然我们打字就全变成了慢动作~。说白了中断其实就是一种主动通知机制,如果中断源不主动通知,那想知道其发生了什么事情,只能一次次地轮询了,白白耗费CPU。
扫帚的影子
2020/02/25
1.7K0
Linux中断一网打尽(1) —— 中断及其初始化
计算机组成原理 I/O方式
1) 程序查询方式。由 CPU通过程序不断查询 /O 设备是否已做好准备,从而控制0 设备与主机交换信息
onenewcode
2024/01/26
4001
保护模式下的中断和异常(上) -- 硬件原理篇
在我们这个系列的第一篇文章中,我们就已经使用过了 BIOS 10H 中断,用来在屏幕上打印一行字符: 计算机是如何启动的?如何制作自己的操作系统
用户3147702
2022/06/27
1.2K0
保护模式下的中断和异常(上) -- 硬件原理篇
Linux内核20-Linux内核的异常处理过程
当异常发生时,Linux内核给造成异常的进程发送一个信号,告知其发生了异常。比如,如果一个进程尝试除零操作,CPU会产生除法错误异常,相应的异常处理程序发送SIGFPE信号给当前进程,然后由其采取必要的步骤,恢复还是中止(如果该信号没有对应的处理程序,则中止)。
Tupelo
2022/08/15
1.7K0
计算机组成原理知识点
计算机体系结构(Computer Architecture)主要研究硬件和软件功能的划分,确定硬件和软件的界面,哪部分功能由硬件系统来完成,哪部分功能由软件系统来完成。
全栈程序员站长
2022/09/05
1K0
MIPS架构深入理解6-异常和中断
MIPS架构中,中断、异常、系统调用以及其它可以中断程序正常执行流的事件统称为异常(exception),统一由异常处理机制进行处理。
Tupelo
2022/08/15
3.1K0
MIPS架构深入理解6-异常和中断
漫谈计算机组成原理(十一)中断系统
这篇文章是整个《漫谈计算机组成原理》系列文章的最后一篇——中断系统。实际上,在《I/O系统》那一篇文章中,我们已经介绍过了中断系统,我想你大概也知道了中断的流程及中断的两种方式,如果你还不知道,就去翻翻前一篇文章《漫谈计算机组成原理(七)I/O系统》吧! 在这篇文章中,我们将细化的讲述中断系统的相关内容,带你全面的了解中断系统的组成、中断系统的工作流程及中断系统的意义。那就开始吧!
roobtyan
2019/02/21
1.2K0
深入理解计算机系统(第三版)/ CSAPP 杂谈,第8章:异常控制流
异常控制流(Exceptional Control Flow,ECF)是操作系统为应用提供的一种访问处理器资源之外的能力,对应于嵌入式和CPU等硬件的中断概念。 系统调用,进程管理,并发,IO 访问都属于异常控制流。 异常(exception)是控制流的突变,用来处理处理器状态中的某些变化。异常通过事件(event)触发,有专门的异常表(exception table)用于事件的跳转。 每种类型的异常都有唯一的异常号(exception number),有可能是处理器设计时分配的零除,缺页
sickworm
2019/02/27
1.1K0
中断和异常概念详解
CPU执行程序时,由于发生了某种随机的事件(外部或内部),引起CPU暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程称为中断。
一个会写诗的程序员
2022/01/27
1.7K0
中断和异常概念详解
干货!计算机组成原理简介
未名编程
2024/10/12
2300
Linux内核17-硬件如何处理中断和异常
在上一篇文章中,我们已经了解了中断和异常的一些概念,对于中断和异常也有了大概的理解。那么,系统中硬件到底是如何处理中断和异常的呢?本文我们就以常见的X86架构为例,看看中断和异常的硬件工作原理。
Tupelo
2022/08/15
2.1K0
Linux内核17-硬件如何处理中断和异常
5-中断和异常
发生中断就意味着需要操作系统介入,开展管理工作。由于操作系统的管理工作(如进程切换,分配I/O设备等)需要使用特权指令,所以需要CPU由用户态切换到核心态。中断可以使CPU从用户态切换到核心态,是操作系统获得计算机的控制权。有了中断,才能实现多道程序并发执行
Ywrby
2022/10/27
4900
5-中断和异常
计算机组成-概述
冯诺依曼结构:运算器、控制器、存储器、输入设备和输出设备五大部件组成。现代计算机一般把控制器和运算器集成在一个芯片上,合称为中央处理器。 现代计算机一般以存储器为中心,使I/O操作尽可能绕过CPU,直接在I/O设备与存储器间完成,从而提高系统的整体运行效率。
千灵域
2022/06/17
2.4K0
计算机组成-概述
一文讲透计算机的“中断”
中断,英文名为Interrupt,计算机的世界里处处都有中断,任何工作都离不开中断,可以说整个计算机系统就是由中断来驱动的。那么什么是中断?简单来说就是CPU停下当前的工作任务,去处理其他事情,处理完后回来继续执行刚才的任务,这一过程便是中断。
小灰
2021/03/26
1.3K0
一文讲透计算机的“中断”
相关推荐
重学计算机组成原理(十二) - 异常和中断
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验