外部中断方式选择:中断描述符表
外部中断方式选择:中断描述符表陷阱门描述符结构如下:中断门包含中断处理程序所在的段选择子和段内偏移地址,当通过此方式进入中断后,标志寄存器eflags中的IF位自动置0,表示把中断关闭,避免中断嵌套。中断们只存在于中断描述符表IDT。任务门描述符结构如下: 任务门需要和任务状态段(TSS)配合使用,这是Intel处理器在硬件一级提供的任务切换机制。任务门可以存在于全局描述符GDT、局部描述符表LDT以及中断描述符表IDT中。中断门描述符结构如下:
摘要- 中断描述符表
- 中断描述符寄存器
- 中断细节
- 中断错误码
什么是中断描述符表?
中断描述符表是保护模式下用于存储中断处理程序的数据结构。CPU在接收到中断时,会根据中断向量在中断描述符表中检索对应的描述符。
中断描述符表中的描述符有哪些类型?
中断描述表中的主要包含以下类型:
- 任务门描述符
- 中断门描述符
- 陷阱门描述符
- 调用门描述符
任务门描述符结构如下:
任务门需要和任务状态段(TSS)配合使用,这是Intel处理器在硬件一级提供的任务切换机制。任务门可以存在于全局描述符GDT、局部描述符表LDT以及中断描述符表IDT中。
中断门描述符结构如下:
中断门包含中断处理程序所在的段选择子和段内偏移地址,当通过此方式进入中断后,标志寄存器eflags中的IF位自动置0,表示把中断关闭,避免中断嵌套。中断们只存在于中断描述符表IDT。
陷阱门描述符结构如下:
通过陷阱门进入中断,标志寄存器eflags的IF位不会自动置0,陷阱门只允许存在于IDT中。
调用门描述符结构如下:
调用门是用户进程用来进入0特权级的方式,其DPL为3。调用门可以在GDT和IDT中存在的,只能使用call和jmp指令调用。
中断描述符表存储的位置不固定。
中断描述符寄存器如何找到中断描述符表?
CPU内部有个中断描述符寄存器IDTR,该寄存器的结构图如下图:
第0~15位是表界限,即IDT减1,可容纳8192个中段描述符;第16~47位时IDT的基地址。
通过lidt 48位内存数据指令便可将中断描述符表的信息加载到IDTR寄存器中。
中断细节中断处理过程包含哪两部分?
CPU外部:外部设备的中断由中断代理芯片接收,处理后将该中断的中断向量号发送给CPU
CPU内部:CPU执行该中断向量号的中断处理程序
如何在中断描述表中定位中断描述符?
每个中断描述符号占用8字节,所以使用中断向量号与8相乘,相当于得到偏移地址,然后从IDTR寄存器中取出中断描述符表的基址,将两个地址相加,便能定位到中断描述符的地址。
中断门处理器如何进行特权级检查?
对于内部中断来说,要求检查当前特权级CPL和中断门描述符DPL及门描述符对应的的代码段的DPL,在数值上满足以下关系:
目标代码段DPL < 当前特权级CPL < 门描述符DPL
对于外部中断,检查当前特权级CPL和目标代码段的DPL,在数值上满足以下关系:
目标代码段DPL < 当前特权级CPL
如何执行中断处理程序?
将门描述符中的目标代码段描述符选择子加载到代码段寄存器CS中,把门描述中中断处理程序的偏移地址加载到EIP,便开始执行中断程序。
如何确定使用新栈还是旧栈?
程序的运行需要栈,由于不同的特权级需要使用不同的栈,因此当涉及到特权级变化后,便需要开启新栈。
使用新栈时需要压入哪些信息?
- 旧栈环境下SS和ESP的值
- 标志寄存器EFLAGS的值
- 备份CS和EIP的值
- ERROR_CODE中断错误码
特权级不发生变化时,不需要压入旧栈环境下SS和ESP的值。
中断处理程序执行完成以后执行返回指令时,CPU会将上述值从栈中弹出,但是ERROR_CODE需要我们手动弹出。
为什么要保存CS和EIP的值?
当我们中断处理程序在返回时,检查备份的CS选择子,根据其RPL和DPL做特权级检查,如果通过,则需要更新寄存器CS和EIP,这样才可以恢复到中断之前的代码段。
该特权级检查的结果还决定了是否需要恢复SS和ESP的值,如果特权级没有发生变化,不需要恢复,因为中断处理程序和我们的应用程序是同一个栈,否则便需要恢复栈。
中断错误码中断错误码只是用来指明中断发生在哪个段上,结构如下图:
EXT用来指明中断源来自处理器内部还是外部,1代表中断源是不可屏蔽中断或外部设备。
IDT表示选择子是否指向中断描述表,1表示执行IDT,否则指向GDT或LDT。
当IDT为1:TI为0表示从GDT中检索描述符,为1表示从LDT检索描述符。
选择子高13位就是用来索引描述符用的下标。