中断包括硬件中断和软中断。
硬件中断是由外围硬件设备发出的中断信号引发的,以请求处理器提供服务。当IO接口发出中断请求时,会被像8259A和 I/O APIC这样的中断控制器收集,并发送到处理器。硬件中断完全是随机产生的,与处理器的执行并不同步。当中断发生时,处理器要先执行完当前的指令,然后才对中断进行处理。
软中断是由intn指令引发的中断处理,n是中断号或者叫类型码。
异常( Exception)异常就是内部中断。它们是处理器内部产生的中断,表示在指令执行的过程中遇到了错误的状况。当处理器执行一条非法指令,或者因条件不具备,指令不能正常执行时,将引发这种类型的中断。
以上所列的情况都是异常情况,所以内部中断又叫异常或者异常中断,异常分为三种:
- 程序错误异常,指处理器在执行指令的过程中,检测到了程序中的错误,并由此而引发的异常。
- 软件引发的异常。这类异常通常由into、int3和 bound指令主动发起。这些指令允许在指令流的当前点上检査实施异常处理的条件是否满足
- 机器检查异常。这种异常是处理器型号相关的
根据异常的严重程度,又可以分为故障、陷阱、终止
中断和异常发生时,处理器将挂起当前正在执行的过程或者任务,然后执行中断和异常处理
过程。返回时,处理器恢复程序或者任务的执行,而且被打断的程序或任务的执行不失连续性
除非遇到一个终止类型的异常。对于某些异常,处理器在转入异常处理程序之前,会在当前栈中
压入一个称为错误代码的数值,帮助程序进一步诊断异常产生的位置和原因。
中断描述符、中断门、陷阱门在实模式下,位于内存最低端的1KB内存,是中断向量表(IVT),定义了256种中断的入口地址,包括16位段地址和16位段内偏移量。当中断发生时,处理器要么自发产生一个中断向量,要么从int n指令中得到中断向量,或者从外部的中断控制器接受一个中断向量。然后,它将该向量作为索引访问中断向量表,从中取得中断处理过程的段地址和偏移地址,并转到那里执行。
在保护模式下,处理器对中断的管理是相似的,但并非使用传统的中断向量表来保存中断处理过程的地址,而是中断描述符表( Interrupt Descriptor Table,IDT)。这个表里保存的是和中断处理过程有关的描述符,包括中断门、陷阱门和任务门
和实模式下的中断向量表(IVT)不同,保护模式下的IDT不要求必须位于内存的最低端。事实上,在处理器内部,有一个48位的中断描述符表寄存器( Interrupt Descriptor Table Register,IDTR),保存着中断描述符表在内存中的线性基地址和界限。
处理器复位时,IDTR的基地址部分为0,界限部分的值为0xFFFF。16位的表界限值意味着IDT和GDT、LDT一样,表的大小可以是64KB,但是,事实上,因为处理器只能识别256种中断,故通常只使用2KB,其他空余的槽位应当将描述符的P位清零。最后,与GDT不同的是,IDT中的第一个描述符也是有效的。
当目标代码段描述符的特权级低于当前特权级CPL时,即在数值上,CPL<目标代码段的DPL时,不允许将控制转移到中断或异常处理程序,违反此规则将引发常规保护异常(#GP)。
因为中断和异常的向量中没有RPL字段,故当处理器进入中断或异常处理程序,或者通过任务门发起任务切换时不检查RPL。中断门、陷阱门也有自己的描述符特权级DPL,即门的DPL。但是,通常情况下不针对该DPL进行检查。
除了用软中断int n和单步中断int3,以及into引发的中断和异常。在这种情况下,当前特权级CPL必须高于,或者和门的特权级DPL相同,即,在数值上 CPL<=门描述符的DPL
中断和异常是随机产生的,不可预测。但是,有一点是可以确定的,即,它总是发生在某个任务内,是在某个任务正在执行的时候产生的,即使整个系统内只有一个任务
作为对任务门的保护,和中断门、陷阱门一样,只对通过int3、intn和into指令发起的任务切换实施特权级检查,即,只有在数值上符合以下条件,才允许通过以上指令发起任务切换:CPL<=任务门的DPL
有些异常产生时,处理器会在异常处理程序或中断任务的栈中压入一个错误代码。通常,这意味着异常和特定的段选择子或中断向量有关
EXT位的意思是,异常是由外部事件引发的( External Event)。此位置位时,表示异常是由
NMI、硬件中断等引发的。
IDT位用于指示描述符的位置( Descriptor Location)。为“1”时,表示段选择子的索引部分(错误代码的位15~3)是指向中断描述符表(IDT)的;为“0”时,表示段选择子的索引部分指向GDT或者LDT
TI位仅在DT位是“0”的情况下才有意义。此位是“0”时,表示段选择子的索引部分指向GDT,否则,指向LDT。
段选择子的索引部分用于指示 GDT/LDT内的段描述符,或者IDT内的门描述符,它就是我们平时所用的段选择子的高13位
注意,当通过 iret/inetd指令从中断处理程序返回时,处理器并不会自动弹出错误代码。因此,对于那些有异常代码的异常处理过程来说,必须在执行 iret/inetd指令前,先从栈中移去(或弹出)错误代码。否则,处理器在执行 iret/inetd指令时,加载(弹出)到CS和EP中的返回地址就是错的。



