7.2 中断

   中断技术使得CPU具有了分身之术。

   中断是计算机的一个重要模块。CPU被设计按照顺序来执行指令,所以,CPU总是自动读取下一条指令来执行。这样就产生一个问题,当CPU在执行内存的一个长时间运算程序时,我想放入一张光盘,获取资料,该怎么办?或者想打印一份文档呢?是不是需要等待运算程序执行完成才可以?又如果想要运行另一个程序呢?是不是也需要先等待?

   然而现实情况并非这样。当我们想读取光盘内容时,随时都可以打开光驱,放入光盘,然后就可以查看光盘里的内容了。当我们想打印文件时,也只需要将打印纸放到打印机上,然后启动打印功能即可。当我们想要运行别的程序时,也不需要等待,随时都可以双击程序图标运行。你是否觉得这一切操作都很自然,也是理所当然的?假设换个场景,这一切都只能顺序进行,也就是上一件事没有完成就不许或者不能进行下一件事,而只能等待。如果是这样的话,你还会觉得计算机方便好用吗?我想如果真是这样,那只可能是人类的思维习惯被颠覆了,变成“机器偶”。实际情况是,别说顺序一个一个执行了,就是某个程序卡一下,我们都会觉得不舒服。不相信的话,你可以测试一下,对于一个缓慢加载的网页,你能等待多长时间。我想,大部分情况是,如果某个程序操作不流畅了,我们的鼠标可能就迫不及待的转移阵地了。

   可见,如果CPU只能顺序执行的话,计算机将存在一个巨大问题,那就是分身乏术。如果真是这样,计算机也许只能放在实验室了,没有任何用户体验可言。要解决这个问题,那就需要一个机制,能让CPU暂停当前的执行,去做另一项任务,完了之后还能退回来,接着上次的点继续执行。这样的话,CPU就可以在不同的时间片执行不同的指令段了,从而并行的执行多项任务。举个例子,还就前面的场景,当我们想要查看光盘内容时,CPU需要暂停当前任务的执行,转而去把光驱打开,等待我们放入光盘。这个间隙,CPU可以回到之前的任务暂停点继续执行。当我们放入光盘后,再通知CPU,读取光盘内容。此时CPU再次暂停之前的任务,回来读取光盘内容......这个“断断续续”的过程就是CPU的实际工作过程。需要强调一点,这里所说的并行,并不是真正意义上的同时进行,而只是因为人类的错觉在宏观上感觉是并行的,但在微观上这一切实际还是串行的。这个跟动画原理是类似的。因为CPU速度很快,远远超出了人的主观感知能力,一秒种的时间可能被分成了几百几千份,每一份时间CPU都可能在做不同的任务,这样,可能每一秒内每个任务都得到了满足人类感官的足够的执行。直观来看,就会形成一种假象,感觉所有的程序都在执行。而从微观上看,CPU每一个微时间内还是只干一件事。说了这么多,那到底有没有这么一种让CPU“断断续续”的机制呢?答案显然是肯定的。这一机制在计算机中称为中断。就如这个词所传达出来的含义,中断当前的执行,去做别的事。

   中断让CPU有了分身之术,正是这一机制,CPU不仅能分身并且并行的执行程序,还能分身并且及时的响应各种外设的请求。最常见的就如U盘的使用,当我们插入盘时,CPU就需要为处理U盘分配时间片,但我们丝毫不会觉得系统被卡住了。

   中断机制的良好运转,需要操作系统的正确配置。对于中断配置的细节这里暂不介绍了。这里最重要的是,需要读者建立一个概念,任务的切换就是中断让CPU暂停当前任务的执行,去执行另一个任务的指令。因为当前任务只是暂停,过后还需要继续执行,所以这其中就涉及到状态保存,返回机制,状态恢复等。对于CPU来讲,状态就是内部寄存器的值,所谓保存状态,就是在中断发生时,将CPU内部寄存器的快照保存到内存的一块固定区域。所谓任务切换,就是用新任务的数据更新内部寄存器,让CPU基于新的PC寄存器指定的地址读取新指令执行,从而切换到新任务执行。当恢复之前暂停的任务时,再用之前保存的快照恢复CPU内部寄存器的值,CPU自然就接着上次任务的断点处继续执行。外部中断触发CPU后的典型工作过程如下图所示(图片来自网络):

 

   参与中断过程的硬件有CPU、内存、中断控制器、中断源相关硬件。CPU有提供不同的中断连线供中断控制器接入,不同的连线,优先级不同。中断也可能复用,即某一个中断线上产生的中断,可能是由不同的中断源产生的,具体是那一个中断源,则需要进一步查看相关寄存器得知,这能够节省硬件连线资源。

   中断源相关硬件产生中断,通过中断控制器传递给CPU,CPU在完成当前指令周期后,发现产生了中断,则将当前CPU内部寄存器数据放入内存。内存位置是由CPU内部的堆栈寄存器指定的。堆栈寄存器指向的内存区域作为操作系统的栈区域,专门用来存放中断和函数调用等切换CPU顺序执行的现场。堆栈有两种增长方式,向上增长或者向下增长,这个跟具体的CPU体系结构有关。向上增长说明堆栈地址是不断增大的,向下增长,则说明堆栈地址是不断减小的。比如现在很多基于ARM处理器平台的Linux操作系统,堆栈是从高地址向低地址“增加”的,也就是向下增长。在这种环境中,CPU在中断发生后,不断的将CPU内部寄存器的数据存入堆栈区,每存入一个,当前堆栈地址减少4个字节(32位平台)或者8个字节(64位平台)。这样,下次再次产生中断时,数据不会相互覆盖。接着,CPU根据中断号,到中断向量表中加载中断处理程序的指令地址,并跳转到中断处理程序执行中断处理。从产生中断到执行中断处理程序,整个过程是硬件自动完成的,不需要程序员或者操作系统参与,但是前提是正确的配置了中断向量表。

   当CPU执行完中断处理程序中的逻辑指令,并执行最后的中断返回指令后(中断处理程序模式固定的最后一条指令),在硬件逻辑的协助下,会自动将当前堆栈的数据导入到CPU的内部寄存器中。这称之为出栈过程。对于上面所述的ARM加Linux场景,此时堆栈地址是向高地址方向移动的。完成出栈后,CPU的PC寄存器中保存的就是进入中断前需要执行的下一条指令。通过这个过程,CPU恢复了之前的现场,接着中断之前的指令继续执行了。这就是整个中断的处理过程。

   通过上面的介绍,我们需要有一个概念,那就是CPU的状态就是其内部寄存器的状态,待中断处理完返回后,从内存中读出之前的寄存器数据,存回CPU中,就实现了断点的恢复。

   以上为CPU层面看到的中断机制。在操作系统层面,则关注的是具体的中断。比如时钟中断,可以为操作系统提供时间相关的服务。各种硬件的中断,是驱动中特别要处理的。当然,操作系统还会借助中断,完善多任务的调度,这些可以借助具体的操作系统,比如Linux,进一步的深入学习。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

龙赤子

你的小小鼓励助我翻山越岭

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

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

打赏作者

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

抵扣说明:

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

余额充值