中断和异常

1.中断和异常的概念

以上定义摘自Intel官方文档80x86编程手册第三卷第五章Interupt and Exception Handling。从中可以看出中断来自外围设备(peripheral devices,这里指除了CPU)的通知(signals from hardware),而异常则是CPU在执行指令时遇到错误的条件(error condition, 我认为这里的错误的条件实际上就是错误的操作数(error operand)),所以说中断是由外围设备产生的,而异常是由CPU自身产生的(在执行指令时)。

注意:上文中有这样一句话:Software can also generate interrupts by executing the INT n instruction.表明软件也可以生成中断,也就是说我们的编写的程序也可以通过INT n指令来生成中断,事实上 CPU 将一些常用的功能以中断处理器(handler)形式提供给我们,作为我们的程序与 CPU 某些特殊功能的调用接口(在高级语言编程中,我们的程序直接调用API函数,从而使用系统提供给我们的功能,这和中断处理器类似),所以当我们在程序中使用中断时,就可以认为该中断就是一次系统的函数调用(实际上是CPU内部功能的调用)。

 

2.中断和异常的通用处理机制

从以上的描述可以看出processor对于中断和异常的处理过程基本一致,分为以下三个过程

a. processor挂起当前运行的过程或任务

b. processor执行中断或异常的处理器(handler)

c. handler执行完毕之后,processor唤醒要执行的过程或任务

注意截图中红色划线的句子,这句话说明了步骤c应该如何决断:如果唤醒被挂起的过程或任务之后不破坏程序的连续性(程序逻辑的正确性),则processor应该将被挂起的过程或任务唤醒,否则处理器(handler)被执行以后异常就不应该被恢复,而中断就应该将当前运行的程序终止。

3.中断和异常产生的来源

3.1中断的来源:

3.2异常的来源:

4.异常的分类

Exceptions are classified as faults, traps, or aborts depending on the way they are reported and

whether the instruction that caused the exception can be restarted with no loss of program or task

continuity.

 

Faults A fault is an exception that can generally be corrected and that, once corrected,

allows the program to be restarted with no loss of continuity. When a fault is

reported, the processor restores the machine state to the state prior to the beginning

of execution of the faulting instruction. The return address (saved contents

of the CS and EIP registers) for the fault handler points to the faulting instruction,

rather than the instruction following the faulting instruction.

Note: There are a small subset of exceptions that are normally reported as

faults, but under architectural corner cases, they are not restartable and some

processor context will be lost. An example of these cases is the execution of the

POPAD instruction where the stack frame crosses over the the end of the stack

segment. The exception handler will see that the CS:EIP has been restored as

if the POPAD instruction had not executed however internal processor state

(general purpose registers) will have been modified. These corner cases are

considered programming errors and an application causeing this class of

exceptions will likely be terminated by the operating system.

 

Traps A trap is an exception that is reported immediately following the execution of

the trapping instruction. Traps allow execution of a program or task to be

continued without loss of program continuity. The return address for the trap

handler points to the instruction to be executed after the trapping instruction.

 

Aborts An abort is an exception that does not always report the precise location of the

instruction causing the exception and does not allow restart of the program or

task that caused the exception. Aborts are used to report severe errors, such as

hardware errors and inconsistent or illegal values in system tables

我们在操作系统的内存管理中常常看到的术语page fault,应该就是属于这三种异常中的第一种:Fault。从红色的语句中我们可以看出,page fault是可以恢复的,事实上,对于操作系统的内存管理来说page fault必须是可以恢复的,不然,操作系统的虚拟地址空间机制就没有办法实现了。

5.中断和异常的处理之后(执行了handler)的指令执行策略

For fault-class exceptions, the return instruction pointer that the processor saves when it generates

the exception points to the faulting instruction. So, when a program or task is restarted

following the handling of a fault, the faulting instruction is restarted (re-executed). Restarting

the faulting instruction is commonly used to handle exceptions that are generated when access

to an operand is blocked. The most common example of a fault is a page-fault exception (#PF)

that occurs when a program or task references an operand in a page that is not in memory. When

a page-fault exception occurs, the exception handler can load the page into memory and resume

execution of the program or task by restarting the faulting instruction. To insure that this instruction

restart is handled transparently to the currently executing program or task, the processor

saves the necessary registers and stack pointers to allow it to restore itself to its state prior to the

execution of the faulting instruction.

 

For trap-class exceptions, the return instruction pointer points to the instruction following the

trapping instruction. If a trap is detected during an instruction which transfers execution, the

return instruction pointer reflects the transfer. For example, if a trap is detected while executing

a JMP instruction, the return instruction pointer points to the destination of the JMP instruction,

not to the next address past the JMP instruction. All trap exceptions allow program or task restart

with no loss of continuity. For example, the overflow exception is a trapping exception. Here,

the return instruction pointer points to the instruction following the INTO instruction that tested

the OF (overflow) flag in the EFLAGS register. The trap handler for this exception resolves the

overflow condition. Upon return from the trap handler, program or task execution continues at

the next instruction following the INTO instruction.

 

The abort-class exceptions do not support reliable restarting of the program or task. Abort

handlers generally are designed to collect diagnostic information about the state of the processor

when the abort exception occurred and then shut down the application and system as gracefully

as possible.

Interrupts rigorously(严格的) support restarting of interrupted programs and tasks without loss of continuity.

The return instruction pointer saved for an interrupt points to the next instruction to be

executed at the instruction boundary where the processor took the interrupt. If the instruction

just executed has a repeat prefix, the interrupt is taken at the end of the current iteration with the

registers set to execute the next iteration.

上文中的红色语句说明了执行处理器(handler)之后,代码该如何执行。其中abort-class exception 的异常不支持restart,所以发生该类异常时program or task一般就会退出或终止。

 

6.异常和中断是可以被processor通过设置EFLAGS标志寄存器来屏蔽的。

MOV SS, AX

MOV ESP, StackTop

例如以上指令在执行期间是不应该被中断的,所以在执行MOV SS, AX时要屏蔽中断和异常。

 

7.中断和异常是有预定义的优先级的,所以当出现并发的中断和异常时,processor通常根据其优先级来执行相应的处理器(handler)

 

8.IDTR寄存器和IDT(中断向量表)

9.汇编语言中的中断调用,以及CPU中与DOS,BIOS,以及外设(如:输入设备:鼠标,键盘,输出设备:显示器,打印机等)的交互(功能调用)都是通过中断机制来实现的。

<think>我们正在讨论中断异常的处理机制及流程。根据引用内容,中断异常是处理器响应外部事件或内部错误的方式。下面我将结合引用内容,详细解释中断异常的处理机制及流程。 ### 1. **中断Interrupt)** 中断是由外部设备或事件引起的异步事件,会打断处理器的当前执行流程。 #### 处理流程: 1. **中断请求(IRQ)**:外部设备(如磁盘、键盘)通过中断控制器向CPU发送中断请求信号[^1]。 2. **中断响应**: - CPU在每条指令执行结束后检查中断请求。 - 若中断请求存在且未被屏蔽,则响应中断: - 保存当前执行上下文(程序计数器PC、状态寄存器等)到堆栈或专用寄存器。 - 关闭中断(防止嵌套中断,除非支持中断优先级)。 3. **中断处理**: - CPU根据中断向量号(由中断控制器提供)从中断描述符表(IDT)中获取中断处理程序的入口地址。 - 跳转至中断处理程序执行: - 保存现场(通用寄存器等)。 - 执行设备服务(如读取键盘输入)。 - 发送EOI(End of Interrupt)信号给中断控制器。 4. **中断返回**: - 恢复现场(寄存器)。 - 执行中断返回指令(如`IRET`),恢复之前保存的上下文并继续执行原程序。 #### 中断类型(引用[2]): - **I/O设备中断**:磁盘、网卡、键盘等。 - **时钟中断**:定时器周期性触发,用于任务调度。 - **非可屏蔽中断(NMI)**:硬件故障等紧急事件。 - **处理器间中断(IPI)**:多核系统中用于核间通信[^2]。 ### 2. **异常Exception)** 异常是处理器执行指令时检测到的同步事件(如除零错误),分为三类(引用[3]): 1. **故障(Fault)**:可修复的错误(如页错误)。处理流程: - CPU保存当前状态,跳转到异常处理程序。 - 处理程序修复问题(如加载缺失的页)后,重新执行触发异常的指令。 2. **陷阱(Trap)**:用于调试(如断点)。处理流程: - 保存状态后执行处理程序。 - 处理完成后继续执行触发指令的下一条指令。 3. **中止(Abort)**:严重错误(如硬件故障)。处理流程: - 系统可能直接终止进程或重启。 #### 异常处理流程: 1. **异常检测**:执行指令时由CPU硬件检测(如除零、非法指令)。 2. **异常响应**: - 立即停止当前指令。 - 保存上下文(PC、状态寄存器等)。 3. **异常处理**: - 根据异常类型(向量号)查询IDT,跳转到对应的异常处理程序。 - 执行错误处理(如终止进程或修复错误)。 4. **异常返回**: - 故障类异常:返回触发指令重新执行。 - 陷阱类异常:返回触发指令的下一条指令。 ### 3. **中断异常的对比** | **特性** | **中断** | **异常** | |----------------|-----------------------------|-----------------------------| | 触发源 | 外部设备 | CPU执行指令时检测到错误 | | 同步性 | 异步(随机发生) | 同步(由特定指令触发) | | 是否可屏蔽 | 部分可屏蔽(NMI除外) | 不可屏蔽 | | 处理目标 | 响应设备请求 | 处理错误或调试 | | 返回行为 | 返回原指令的下一条 | 故障:返回原指令;陷阱:返回下一条 | ### 4. **中断/异常处理的关键机制** - **中断描述符表(IDT)**:存储中断/异常处理程序的入口地址(引用[4])。 - **中断控制器**:管理多个中断源(如APIC、PIC)。 - **上下文保存**:通过硬件自动完成(如`pushad`指令)。 - **嵌套处理**:高优先级中断可打断低优先级处理程序(需硬件支持)。 ### 5. **处理流程代码示例(简化)** 引用[4]展示了一个中断分发器的伪代码: ```c void _global_interrupt_handler(intptr_t sp, int mcause) { intr_handler_item_t it = s_intr_handlers[mcause]; // 根据中断原因查询处理函数 if (it.handler) { (*it.handler)(it.arg); // 调用注册的中断处理函数 } } ``` > **说明**:`mcause`寄存器存储中断/异常原因码,通过查表调用对应的处理函数[^4]。 ### 6. **实际案例:Linux内核处理流程** 1. **中断入口**(汇编):保存现场,调用`do_IRQ()`。 2. **中断处理**(C语言): - 调用设备驱动注册的中断服务例程(ISR)。 - 处理中断共享优先级。 3. **中断退出**:恢复现场,执行调度(若需要)。 --- §§相关问题§§ 1. 在多核系统中,如何通过处理器间中断(IPI)实现缓存一致性? 2. 页错误(Page Fault)异常的处理流程是怎样的? 3. 非可屏蔽中断(NMI)通常用于处理哪些紧急情况? 4. 中断描述符表(IDT)在操作系统中是如何初始化的? 5. 硬件中断软件中断(如`INT 0x80`系统调用)的处理机制有何异同?</think>### 中断异常处理机制及流程详解 #### 1. **基本概念与分类** - **中断Interrupt)**:由**外部硬件事件**触发的异步信号(如键盘输入、时钟信号)[^3] - 可屏蔽中断INTR):可通过中断屏蔽寄存器忽略 - 非可屏蔽中断(NMI):必须立即处理的严重事件(如硬件故障)[^2] - **异常Exception)**:由**CPU执行指令**触发的同步事件[^3] - 故障(Fault):可修复错误(如页错误) - 陷阱(Trap):调试中断(如断点) - 中止(Abort):不可恢复错误(如硬件故障) #### 2. **中断处理流程** ```mermaid sequenceDiagram participant H as 硬件设备 participant C as CPU participant I as 中断控制器 participant M as 内存(IDT) participant H as 处理程序 H->>I: 1. 发送中断请求(IRQ) I->>C: 2. 转发中断信号 C->>C: 3. 保存现场(EFLAGS, CS, EIP) C->>M: 4. 查询IDT获取处理程序地址 C->>H: 5. 跳转执行中断处理程序 H->>I: 6. 发送EOI(中断结束命令) H->>C: 7. 恢复现场(IRET指令) ``` 具体步骤: 1. **中断请求**:设备通过IRQ线发送请求到中断控制器(如APIC)[^1] 2. **中断响应**: - CPU完成当前指令后检查中断请求 - 保存状态寄存器(EFLAGS)返回地址(CS:EIP)到内核栈 3. **中断分发**: - 通过中断向量号查询中断描述符表(IDT)[^4] - 获取中断处理程序入口地址(如`_global_interrupt_handler`) 4. **处理程序执行**: - 保存通用寄存器状态 - 执行设备服务(如读取键盘缓冲区) - 发送EOI信号通知中断控制器[^2] 5. **中断返回**: - 恢复寄存器状态 - 执行`IRET`指令返回原程序 #### 3. **异常处理流程** ```mermaid graph TD A[指令执行] --> B{检测异常} B -->|无异常| C[继续执行] B -->|有异常| D[保存现场] D --> E[查询IDT] E --> F{异常类型} F -->|故障 Fault| G[修复后重试指令] F -->|陷阱 Trap| H[继续下条指令] F -->|中止 Abort| I[终止进程] ``` 关键差异点: - **同步触发**:异常在特定指令执行时立即发生(如除零错误) - **无EOI信号**:异常处理无需通知外部控制器 - **返回行为**: - 故障:返回触发指令重新执行(如页错误修复后) - 陷阱:返回下一条指令(如断点调试) #### 4. **多核处理机制** - **处理器间中断(IPI)**: - 核心A通过ICR(中断命令寄存器)向核心B发送中断[^2] - 用途: - 任务调度(唤醒空闲核心) - TLB一致性维护(TLB shootdown) - 系统关闭信号广播 - **中断性**:将特定设备中断绑定到指定CPU核心 #### 5. **关键数据结构** - **中断描述符表(IDT)**: ```c struct idt_entry { uint16_t offset_low; // 处理程序地址低16位 uint16_t selector; // 代码段选择子 uint8_t ist; // 中断栈表 uint8_t attributes; // 门类型(P=1表示有效) uint16_t offset_mid; // 处理程序地址中16位 uint32_t offset_high; // 处理程序地址高32位 uint32_t reserved; } __attribute__((packed)); ``` - **中断处理注册**(引用[4]示例): ```c void _global_interrupt_handler(intptr_t sp, int mcause) { intr_handler_item_t it = s_intr_handlers[mcause]; if (it.handler) { (*it.handler)(it.arg); // 执行注册的处理函数 } } ``` #### 6. **优先级与嵌套** - **中断优先级**: 1. 机器检查 > NMI > 硬件中断 > 陷阱 > 故障 - **嵌套处理**: - 高优先级中断可打断低优先级处理程序 - 内核栈保存多层执行上下文(最多5-8层) #### 7. **典型场景示例** 1. **时钟中断**: - IRQ0触发 → 更新系统时间 → 执行任务调度 2. **页错误异常**: - 访问无效地址 → 触发#PF异常 → 内核分配物理页 → 重试指令 3. **系统调用**: - 执行`INT 0x80` → 陷入内核 → 根据EAX值分发系统调用 > **性能指标**: > 中断延迟 $t_{latency} = t_{detect} + t_{save} + t_{dispatch}$ > 现代系统典型值:$\leq 10\mu s$ (实时系统要求 $\leq 1\mu s$) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值