中断分类
按照中断的来源分类,来自CPU外部的中断称为外部中断,来自CPU内部的称为内部中断;细分的话,外部中断根据严重程度,分为可屏蔽中断和不可屏蔽中断;内部中断按照是否正常分为软中断和异常。
外部中断
外部中断来自CPU的外部的某个硬件,因此又被称为硬件中断,比如网卡收到了一个数据包,它就会通知CPU,CPU得到通知便将数据拷贝到内核缓冲区。
为了接受外部中断,CPU有两个引脚作为接受接口,INTR和NMI线。
可屏蔽中断
有些中断是不会引起系统宕机,还是网卡的例子,网络数据包通过网线达到网卡,存到网卡自己的缓冲区,这个缓冲区是会被写满的,写满以后,后来的数据就会被丢掉。写满以后,CPU收到中断一般会马上拷贝网卡数据到内核缓冲区,但是这样的数据其实是可以丢的,不会引发崩溃,属于可屏蔽中断。
这类中断通过INTR线传到CPU引脚。
不可屏蔽中断
内存读写错误这类的属于不可屏蔽,出了问题只能找硬件工程师了 : )
内部中断
内部中断可以分为软中断和异常。
软中断
软中断就是由软件主动引发的中断,可以认为是主动引发的,从而实现在CPU的支持下实现某种功能。比如:
- int 0xxx 表示进行系统调用
- int3 我们用gdb 或bochs 调试程序时,实际上就是调试器fork 了一个子进程,
子进程用于运行被调试的程序。调试器中经常要设置断点,其原理就是父进程修改了子进程的指令,触发3号中断,执行3号中断上的中断处理程序。
异常
发生除0,缺页等错误的时候,正常的流程被打断。
- 可被修复的异常 比如操作系统的缺页异常
- 终止程序的异常
中断描述符
一个中断源就会产生一个中断向量,每个中断向量都对应中断描述符表中的一个门描述符,任何中断
源都通过中断向量对应到中断描述符表中的门描述符,通过该门描述符就找到了对应的中断处理程序。
在CPU 内部有个中断描述符表寄存器( Interrupt Descriptor Table Register, IDTR ),该寄存器分为两
部分:第O~ 15 位是表界限,第16~47 位是IDT 的基地址。
中断时候的栈变化
当前进程被中断打断后,为了从中断返回后能继续运行该进程,处理器自
动把CS 和EIP 的当前值保存到中断处理程序使用的栈中。
不同特权级别下处理器使用不同的栈,至于中断处
理程序使用的是哪个栈,要视它当时所在的特权级别,因为中断是可以在任何特权级别下发生的。
除了要保存CS 、EIP 外,还需要保存标志寄存器EFLAGS ,如果涉及到特权级变化,还要压入SS 和ESP 寄存器。