中断&异常

五迷三道 提交于 2020-01-16 04:00:33
中断分类
 
    
类别
原因
返回行为
例子
广义
中断
异步中断 ( 狭义中断)
中断 
(interrupt)
可屏蔽中断
来自 I/O 设备的信号
总是返回到下一条指令
所有的 IRQ 中断
不可屏蔽中断
电源掉电和物理存储器奇偶校验
 
同步中断 ( 也称异常)
陷阱 (trap)
有意的异常
总是返回到下一条指令
系统调用、信号机制 ( 通过软中断实现 )
故障 (fault)
潜在可恢复的错误
返回到当前指令
缺页异常、除 0 错误、段错误
终止 (abort)
不可恢复的错误
不会返回
硬件错误
 
 
     
注:80386有两根引脚INTR和NMI接受外部中断请求信号,INTR接受可屏蔽中断请求。在80386中,标志寄存器EFLAGS中的IF标志决定是否屏蔽可屏蔽中断请求。
 
 
中断的定义(wikipedia)
 
       中断是指由于接收到来自外围硬件(相对于中央处理器内存)的异步信号或来自软件同步信号,而进行相应的硬件/软件处理。硬件中断导致处理器通过
一个上下文切换(context switch)来保存执行状态(以程序计数器和程序状态字等寄存器信息为主);软件中断则通常作为CPU指令集中的一个指令(汇编中的int
指令),以可编程的方式直接指示这种上下文切换,并将处理导向一段中断处理代码。软中断陷入内核,常被用于实现系统调用(int 80等)。
       如果计算机系统没有中断,则处理器与外部设备通信时,它必须在向该设备发出指令后进行忙等待(Busy waiting),反复轮询该设备是否完成了动作并返回结果。
这就造成了大量处理器周期被浪费。引入中断以后,当处理器发出设备请求后就可以立即返回以处理其他任务,而当设备完成动作后,发送中断信号给处理器,后者
就可以再回过头获取处理结果。
 
注:下面中断都指狭义的中断(硬中断)。
 
几个区别
  • 异常&中断
      异常的处理过程和中断类似,不同的是中断由外部设备产生而异常由CPU内部产生,中断产生的原因和CPU当前执行的指令无关(指令执行完毕,即公操作阶段),
而异常的产生就是由于CPU当前执行的指令出了问题,例如访问内存的指令被MMU检查出权限错误,除法指令的除数为0等都会产生异常。
       异常与中断不同,它在产生时必须考虑与处理器时钟同步。并且中断是由硬件而不是软件引起的。
 
  • 硬中断&软中断
     1.  硬中断是由外部事件引起的因此具有随机性和突发性;软中断是执行中断指令产生的,无面外部施加中断请求信号,因此中断的发生不是随机的而是由程序安排好的。
     2.  硬中断的中断响应周期,CPU需要发中断回合信号(NMI不需要),软中断的中断响应周期,CPU不需发中断回合信号。
     3.  硬中断的中断号是由中断控制器提供的(NMI硬中断中断号系统指定为02H);软中断的中断号由指令直接给出,无需使用中断控制器。
     4.  硬中断是可屏蔽的(NMI硬中断不可屏蔽),软中断不可屏蔽。
 
  • 软中断&函数调用
     函数调用是将返回地址和CPU状态寄存器内容压栈,函数执行完毕后出栈返回断点继续执行。  
     软中断调用是将返回地址和CPU状态寄存器内容压栈,修改特权级,根据中断号查找中断向量表,找到ISR中断服务例程地址,跳转执行。  
     综上,函数调用和软中断调用的区别是,软中断多了修改特权级和查找中断向量表的功能,其他部分完全一样。软中断用于系统API调用。
 
  • 函数库调用 VS 系统调用  
 

函数库调用

系统调用

在所有的ANSI C编译器版本中,C库函数是相同的

各个操作系统的系统调用是不同的

它调用函数库中的一段程序(或函数)

它调用系统内核的服务

与用户程序相联系

是操作系统的一个入口点

在用户地址空间执行

在内核地址空间执行

它的运行时间属于“用户时间”

它的运行时间属于“系统”时间

属于过程调用,调用开销较小

需要在用户空间和内核上下文环境间切换,开销较大

在C函数库libc中有大约300个函数

在UNIX中大约有90个系统调用

典型的C函数库调用:system fprintf malloc

典型的系统调用:chdir fork write brk;

 

     具体实现:通过软中断0x80,系统会跳转到一个预设的内核空间地址,它指向了系统调用处理程序(不要和系统调用服务例程相混淆),即在arch/i386/kernel/entry.S
文件中使用汇编语言编写的system_call函数。
 
     所有的系统调用都会统一跳转到这个地址进而执行system_call函数,system_call函数又该如何派发它们到各自的服务例程呢?
 
     软中断指令int 0x80执行时,系统调用号会被放入eax寄存器,同时,sys_call_table每一项占用4个字节。这样,如图5.5所示,system_call函数可以读取eax寄存器获得
当前系统调用的系统调用号,将其乘以4生成偏移地址,然后以sys_call_table为基址,基址加上偏移地址所指向的内容即是应该执行的系统调用服务例程的地址。
     有了软中断,就可以实现应用程序的动态加载。就像WINDOWS/Linux那样,应用程序和系统程序分别开发,不在一起编译连接,应用程序通过软中断调用系统提供的
功能。
 

 

     
什么是中断上半部和下半部?
 
       中断处理一般分为两个部分,上半部指的是中断处理程序,下半部则指的是一些虽然与中断有相关性但是可以延后执行的任务。上半部接收到一个中断就立即执行,但
只做有严格时限的工作,这些工作都是在所有中断被禁止的情况下完成的。能够被允许稍后完成的工作被推迟到下半部去。通常情况下,下半部会在中断处理程序返回时立即
执行。
 
     对于一个工作是放在上半部还是放在下半部去执行,可以参考下面四条:
     a)如果一个任务对时间非常敏感,将其放在中断处理程序中执行。
     b)如果一个任务和硬件相关,将其放在中断处理程序中执行。
     c)如果一个任务要保证不被其他中断(特别是相同的中断)打断,将其放在中断处理程序中执行。
     d)其他所有任务,考虑放在下半部去执行。
 
 
软中断
     软中断是利用硬件中断的概念,用软件方式进行模拟,实现宏观上的异步执行效果。很多情况下,软中断
和"信号"有些类似,同时,软中断又是和硬中断相对应的,"硬中断是外部设备对CPU的中断","软中断通常
是硬中断服务程序对内核的中断","信号则是由内核(或其他进程)对某个进程的中断"(《Linux内核源代码
情景分析》第三章)。软中断的一种典型应用就是所谓的"下半部"(bottom half),它的得名来自于将硬件中
断处理分离成"上半部"和"下半部"两个阶段的机制:上半部在屏蔽中断的上下文中运行,用于完成关键性的处
理动作;而下半部则相对来说并不是非常紧急的,通常还是比较耗时的,因此由系统自行安排运行时机,不
在中断服务上下文中执行。bottom half的应用也是激励内核发展出目前的软中断机制的原因。
 
 

中断向量表

     共有从0到255共256个中断类型码,每个中断类型码对应的中断向量所在地址为该类型码乘以4。如果中断类型码为33,则对应中断向量所在地址为00084H。这样,
果已知一个中断类型码,则需要通过两次地址转换(中断类型码到中断向量表地址;中断向量表地址到中断处理程序地址)才能到达中断处理程序。
 
     在全部256个中断中,前32个(0—31)为硬件系统所预留。后224个可由用户设定。
     
     在INTEL后续的32位CPU中,使用中断描述符表来代替中断向量表。中断描述符表的起始地址由中断描述符表寄存器(IDTR)来定位,因此不再限于底部1K位置。
 
 
中断处理程序
 
    在响应一个特定中断的时候,内核会执行一个函数,该函数叫中断处理程序(interrupt handler)或中断服务例程(interrupt service routine,ISR)。产生中断
的每个设备都有一个相应的中断处理程序。一个设备的中断处理程序是它设备驱动程序的一部分。
 
 
中断是进程切换的必要不充分条件
 
     假如在时刻T1与时刻T2之间发生了进程切换,则在时刻T1与时刻T2之间一定执行了处理机调度程序,而处理机调度程序是操作系统低层中的一个模块,运行于管态,说明在T1与T2时刻之间处理机状态曾由目态转换到管态。由于中断是系统由目态转换为管态的必要条件,所以在时刻T1与时刻T2之间一定发生过中断,也就是说,中断是进程切换的必要条件,然而中断不是进程切换的充分条件。
     例如: 一个进程执行一个系统调用命令将一个消息发给另外一个进程,该命令的执行将通过中断进入操作系统,操作系统处理完消息的发送工作后可能返回原调用进程,此时中断未导致进程切换;也可能选择一个新的进程,此时中断导致了进程切换。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!