中断是什么
中断就是打断处理器当前的执行流程,去执行另外一些和当前工作不相干的指令,执行完之后,还可以返回到原来的程序流程继续执行
为什么会有中断机制
中断这种机制能够让处理器可以在不同任务之间快速切换,实现多任务处理的功能。试想一下没有中断机制,一次只能执行一个任务,那我就不能边听音乐边写博客了,这真的很糟糕
外部硬件中断
外部硬件中断就是从处理器外面来的中断信号
外部硬件中断时通过两个信号线引入处理器内部的,这两个线叫做NMI 和 INTR
为什么需要两个信号线呢?实际上这是用来区分中断信号的紧急性的,有些中断信号无关紧要,处理器可以忽略或延迟处理,有些则是很致命,必须尽快处理
中断类型
-
非屏蔽中断
不会被阻断或屏蔽的称为非屏蔽中断,也就是NMI(Non Maskable Interrupt)
我们可以在上图看到,NMI的中断源(产生中断的设备)通过一个与非门连接到处理器,处理器NMI引脚是高电平有效,中断信号是低电平有效
Intel处理器规定,NMI中断信号由0跳到1后,至少要维持4个以上的时钟周期才算有效的,才能被识别
每种类型的中断都被统一编号,这称为中断类型号、中断向量或者中断号。但非屏蔽中断比较特殊,因为这种中断信号产生意味着事件比较致命,总之就是很难去补救,所以在实模式下,NMI被赋予了中断信号2,不在细分
-
可屏蔽中断
可屏蔽中断的特点是数量多(外设多)、可以被屏蔽
可屏蔽中断是通过INTR引脚引入处理器内部的
中断控制器
处理器一次只能处理一个中断,所以需要有一个中断代理来接受外部设备发出的中断信号,然后对他们进行仲裁,决定哪一个优先交给处理器处理了。这个中断代理就是中断控制器了
用得比较多的中断代理就是8259芯片
Intel处理器允许处理256个中断,所以中断号的范围是 0~255,8259负责提供其中的15个
中断号并不是固定的,允许软件根据自己的需要灵活设置中断号以防止冲突
中断控制器的结构
每片8259芯片只有8个中断输入引脚,可以看到从片的INT输出送到主片的引脚2上,这形成了级联关系,然后主片的INT输出直接送到INTR引脚上,最后交给处理器
8259主片的引脚0(IR0)接的是系统定时器/计数器芯片,从片的引脚0(IR0)接的是实时时钟芯片(RTC),这两个不会变化
中断屏蔽寄存器(IMR, Interrupt Mask Register)
IMR存在于8259芯片内部,是一个8位寄存器,对应着芯片的8个引脚输入,对应位是0表示允许通过8259送往处理器,1表示阻断
8259芯片是可编程的,主片的端口号是0x20和0x21,从片的端口号是0xa0和0xa1,通过这些端口可以设置芯片的工作方式,包括IMR的内容
中断处理的条件
- 8259芯片中的中断屏蔽寄存器
- 引脚的对应位是0表示允许,1表示中断
- 处理器内部标志寄存器中的IF位,这是中断标志位(Interrupt Flag)
- IF为0,所有从处理器INTR引脚来的中断信号都被忽略掉,为1表示处理器可以接受和响应中断
- IF位由 cli(置0) 和 sti(置1)这两条指令改变,无操作数
实模式下的中断向量表
中断处理就是处理器要执行要执行一段与该中断有关的程序(指令)
然后这些程序的入口点集中存放到 0x00000~0x003ff 这1KB的空间中,这就是中断向量表(Interrupt Vector Table, IVT),每个中断在中断向量表中占2个字(偏移地址和段地址)
当处理器收到中断号,处理中断的过程:
-
保护断点的现场:
- 将标志寄存器FLAGS压栈
- 清除IF位和TF位
- 将当前代码段的cs和ip压栈
-
执行中断处理程序:
- 将中断号乘以4得到中断入口点在中断向量表中的偏移地址
- 依次取出中断程序的偏移地址和段地址并传送到ip和cs
此时IF位被清除,所以处理器不在响应硬件中断
-
返回到断点接着执行:
- 所有中断处理程序最后一条指令必须是中断返回指令
iret
,这将从栈中依次弹出(恢复), IP、CS和FLAGS的原始内容
- 所有中断处理程序最后一条指令必须是中断返回指令
NMI发生时,处理器不会从外部获得中断号,会自动生成中断号2,中断处理和可屏蔽中断相同
使用处理器进入低功耗状态
使用指令hlt,该指令让处理器进入停机状态,即停止执行指令,这会降低处理器的功耗
处于停机的处理器可以被外部中断唤醒并继续执行指令,而且会继续执行hlt后面的指令
内部中断
内部中断发生在处理器内部,是由执行的指令引起的。比如非法指令(指令操作码无定义)等等
内部中断不受IF标志位影响,不需要中断识别总线周期,他们的中断类型是固定的,可以立即转入相应的处理过程
中断识别总线周期
在计算机系统中,当外部设备发出中断请求时,处理器通常会经过几个步骤来处理这个请求,包括识别中断源、确认中断请求,并决定是否响应中断
这些步骤通常需要通过总线上的识别信号和控制信号来完成,这被称为“中断识别总线周期”
软中断
软中断是由int指令引起的中断处理,也不需要中断识别总线周期,中断号在指令中给出
int3 ;断点中断指令,设置断点,单字节指令,机器码为CC
int 立即数 ;双字节指令,操作码为CD,第2字节的操作数给出中断号
into ;溢出中断指令,OF位为1(表示溢出)则产生4号中断,单字节指令,机器码为CE
BIOS中断
可以为所有的中断类型自定义中断处理过程,包括内部中断、硬件中断和软中断
编写自己的中断处理程序能有更好的复用性,因为它使用的是int指令,该指令不需要知道目标程序的入口地址,只要中断号就好了。也就是说我们想使用这部分功能只用知道具体的中断号就能够调用了
BIOS中断也是软中断,之所以这么叫是因为这些中断功能在计算机加电之后,BIOS程序执行期间建立起来的,即这些中断功能在加载和执行MBR之前就能使用了
BIOS中断又叫BIOS功能调用,主要是为了方便地使用最基本的硬件访问功能
BIOS如何建立起这套功能调用中断的,它又是怎么知道如何访问硬件的
-
BIOS可能会为一些简单的外设提供初始化代码和功能调用代码,并填写中断向量表
-
由外部设备接口自己建立BIOS中断
- 每个外部设备接口都有自己的ROM,ROM中提供了自己的功能调用例程以及本设备的初始化代码
- 按照规范,前两个单元的内容是0x55和0xAA
- 第三个单元是本ROM中以512字节为单位的代码长度
- 第四个单元开始就是实际的ROM代码
- 内存中有部分空间是留给外围设备的,外围设备的ROM会映射到分配给它的地址范围
- 假设某个设备的ROM可能被映射到内存地址0x00到0xFF。当处理器访问这些地 址时,实际上是在访问设备的ROM
- 在计算机启动期间,BIOS会以2KB为单位搜索内存地址0xC0000~0xE0000
- 按照ROM代码的规范进行查找
- 发先某区域的头两个字节是0x55和0xAA,表示该区域有ROM代码存在
- 对该区域做累加和检查,看结果是否和第三个单元相符(检查长度)
- 相符从第四个单元进入,处理器此时执行的是硬件自带的程序指令,初始化设备的相关寄存器和工作状态
- 填写相关的中断向量表,使它们指向自带的中断处理过程
- 按照ROM代码的规范进行查找
- 每个外部设备接口都有自己的ROM,ROM中提供了自己的功能调用例程以及本设备的初始化代码