处理器在执行当前任务时出现突然事件导致执行控制从当前任务转移到冲断处理程序。处理器相应中断或异常处理程序采取的行动称为中断/异常处理。
中断源:
1. 外部中断:经过CPU INTR引脚或NMI引脚接收。当INTR接收外部中断,cpu从系统总线上读取外部中断控制器提供的中断向量号。NMI 接收非屏蔽中断,使用固定中断向量号 2 。INTR接收的中断时可屏蔽的,通过设置EFLAGS的IF位来控制是否屏蔽,
2. 软件中断:INT 指令产生中断,0-255 都可以作为INT指令中断号。IF 标志不能屏蔽软中断。
异常源:
1. 处理器检测到程序错误,比如 被0除。
2. 指令INTO、INT 3、BOUND可以产生软异常。
3. INT 指令也可以模拟异常,但不会产生错误码,所以对于要处理错误码的异常处理程序会吧EIP弹出,需注意。
异常分类:
1. 故障(Fault):一种可纠正异常,异常处理程序执行完后会再次运行产生异常的指令。
2. 陷阱(Trap):异常处理程序执行完后执行产生异常的下一条指令。如 JMP 时产生Trap,返回指针指向JMP指令的目标地址。
3. 中止(Abort):不支持重新执行程序。通常用来收集异常产生时处理器信息,并关闭系统。
开启、禁止中断:
1. 设置EFLAGS的IF标志为0来禁止INTR引脚的中断,用STI和CLI来设置和清除IF位。
2. POPF、任务切换、IRET都会更行EFLAGS
中断描描述符表(IDT):
IDT用于将中断向量与中断处理程序联系起来,与GDT和LDT类似也是由8字节长描述符组成数组。与GDT不同的是表中第一项可以包含描述符。中断向量号*8 = IDT表索引值。
IDT表可以在线性地址空间的任何地方,处理器使用IDTR存储IDT表线性地址(32位)+限长(16位)。为保证处理器访问效率,IDT基地址应对齐8字节边界。
LIDT指令用于加载IDTR内容,该指令只能运行在当前特权级为0代码中。
SIDT指令用于存储IDTR内容,该指令能运行在任何特权级上。
IDT描述符:
1. 中断门 : type= 01110
2. 陷阱门 : type= 01111
3. 任务门 : type= 00101
中断门和陷阱门的主要区别是中断门处理中断时会清除IF位,从而禁止可屏蔽中断。
异常和中断处理:
与用Call指令调用门类似。
1. 处理过程将在高特权级执行时:
a)从当前任务TSS段中选择中断异常处理过程使用的新栈SS和SP,然后处理器将当前SS和SP入栈到新栈。
b) EFLAGS,CS,EIP 压入新栈。
c) 如有错误码,则把错误码压入新栈
2. 处理过程在相同特权级运行时:
a)EFLAGS, CS, EIP 压入当前栈。
b) 如有错误码,则把错误码压入当前栈。
为从处理过程返回,必须使用IRET指令。该指令会把保存的EFLAGS恢复到EFLAGS中,如果调用过程中有堆栈切换,IRET也会把堆栈切回。
中断保护:
利用软件产生中断时CPL 必须<= 门的DPL,防止用户程序访问高特权级程序。硬件产生的中断则不做此检查。
CALL 指令直接把控制转移到另一个特权级时:
如果是访问非一致代码,比如CPL=DPL,如果是访问一致代码,比如CPL》=DPL
阅读(1103) | 评论(2) | 转发(0) |