1. 中断处理中的"记忆"保存机制
当CPU正在执行主程序时,突然收到一个中断请求,这就好比你在专心写代码时突然被同事打断问问题。这时候你需要先记住自己写到了哪一行(程序计数器PC),当前的变量值是什么(寄存器状态),然后才能去处理同事的问题。处理完后,你又需要准确地回到之前的代码位置,继续之前的思路。
这个"记住现场"的过程,在计算机体系结构中就是通过压栈操作实现的。当发生中断时,硬件会自动将当前程序状态字(PSW)和程序计数器(PC)压入系统栈。有些架构还会自动保存部分关键寄存器,而其他寄存器的保存则需要通过软件实现。
关键点:中断现场保存的完整性直接决定了系统能否正确恢复执行。漏掉任何一个关键状态的保存都可能导致程序跑飞。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 压栈操作:中断现场的精确快照
2.1 硬件自动保存的寄存器
以ARM Cortex-M系列为例,发生中断时硬件会自动将以下寄存器压入当前栈:
code复制xPSR // 程序状态寄存器
PC // 返回地址
LR // 链接寄存器
R12 // 临时寄存器
R3-R0 // 通用寄存器
这个压栈顺序是硬件固定的,在异常入口处自动完成。栈指针SP会根据压栈的数据量自动调整。
2.2 软件需要保存的寄存器
编译器通常会在中断服务程序(ISR)的入口生成保存剩余寄存器的代码。例如在GCC中,你可能会看到这样的汇编:
assembly复制push {r4-r11} // 保存未被硬件自动保存的寄存器
对于FPU寄存器,如果需要使用,也必须手动保存:
c复制void ISR(void) {
__asm volatile ("vpush {s16-s31}"); // 保存FPU寄存器
// 中断处理逻辑
__asm volatile ("vpop {s16-s31}"); // 恢复FPU寄存器
}
2.3 栈帧结构的实际案例
假设在中断发生时,程序正在执行函数A,调用深度为3层。此时栈结构可能如下:
| 地址 | 内容 |
|---|---|
| 0x2000FFFC | 函数A的局部变量 |
| 0x2 |
