📄 一句话概括
中断是程序流程的特例:正跑着被打断,硬件把现场(PC 等)压进栈,处理完再弹出来接着跑——像接了个电话又回到书桌前。
📝 本节和前面几节的关系
前五节讲的都是【程序自己决定流向】,这一节第一次讲【外部插入的流程】——特殊情况之一:中断。
一、中断是什么
CPU 正一条条执行指令,外部设备突然有急事(键盘按下、网卡收到包),需要立刻处理——这叫中断。 处理流程:暂停当前程序 -> 保存现场(把 PC 和关键寄存器压进栈)-> 跳到中断处理程序干活 -> 干完从栈里恢复现场 -> 从被打断处继续。 生活类比:写作业时电话响了,你先在书角折个记号(保存现场),接完电话接着从记号处写(恢复现场)。
二、栈与现场
现场=被打断那一刻的 PC 和寄存器值——不知道它们,回来时接不上; 栈是内存里一块后进先出的区域,专门存这类【待恢复的信息】。第三章认识过的 SP(栈指针)就是记录栈顶在哪的寄存器。 中断可以嵌套(电话接一半门铃又响),所以栈必须能一层层压、再一层层弹。
三、为什么需要中断
如果靠程序自己【每做一步就问一次键盘】,那查询会把 CPU 占满。中断让 CPU 平时专心干活,有事才被打搅——这是效率设计。 【⚠️ 2026 现状】中断是现代计算机的脉搏:时钟中断、IO 中断、网络中断日夜不停;操作系统调度的底层就靠它。
四、动手 Demo:一次中断的全过程
模拟主程序跑着跑着被中断:保存现场、处理、恢复、继续。
# 中断: 保存现场 -> 处理 -> 恢复现场
pc = 0x0100
stack = []
pc += 2; pc += 2; pc += 2 # 主程序跑到第三条
print("主程序 PC =", hex(pc))
stack.append(pc) # 保存现场
print("中断! 现场入栈, 栈深 =", len(stack))
print("执行中断处理程序... 完毕")
pc = stack.pop() # 恢复现场
print("恢复 PC =", hex(pc), "栈深 =", len(stack))
实跑输出:
--------------------------------------------------------------------
中断处理——被打断还能接回来
--------------------------------------------------------------------
主程序正跑着,外部来了急事,处理器要暂停手头活去应付——这叫中断。
关键机制:**把现场(PC 等寄存器)保存到栈里**,办完事再原样恢复。
模拟一次中断的全过程:
[主程序] PC=0x0100 执行第 1 条指令
[主程序] PC=0x0102 执行第 2 条指令
[主程序] PC=0x0104 执行第 3 条指令
[中断信号到达!] 停下手头的活
[保存现场] PC=0x0106 压入栈 (栈深=1)
[中断处理程序] 干活中... 干完了
[恢复现场] 从栈弹回 PC=0x0106 (栈深=0)
[主程序] 从第 4 条指令继续 PC=0x0106
步骤 硬件动作 结果
--------------------------------------------------
来中断 暂停当前指令流 PC 不再前进
保存现场 PC 等压入栈 栈深 +1
执行处理 跳到中断处理程序 急事办完
恢复现场 从栈弹出 PC 栈深 -1、接着跑
没有【保存现场】这一步,被打断的程序就找不回路了——栈是中断的救命索。
栈后进先出:嵌套中断时,最晚压入的最先恢复——顺序不能乱。 没有保存现场这一步,被打断的程序就【回不去】——这是中断机制最关键的一环。
30 秒实验
- 把折书角接电话的类比讲给别人听——讲通了中断就懂了。
- 想象两层嵌套中断(电话未完门铃又响),在纸上画出栈的压入弹出顺序。
常见误区
- 以为中断是【程序主动查】——中断是硬件强插,不需要程序配合。
- 以为保存现场只存 PC——关键寄存器的值同样要存,回来才能接得上。
自测三问(点开对答案)
1. 中断处理的四个步骤? —— 暂停当前程序、保存现场到栈、执行中断处理程序、恢复现场继续。 2. 为什么必须有保存现场这一步? —— 不保存现场,处理完就找不到被打断的位置,程序接不上。 3. 栈为什么必须能嵌套? —— 中断可以嵌套发生,现场要一层层压入再一层层弹回。- ☐ 下一节(4.7 特殊的程序流程——事件驱动)
相关笔记
- Z80 CPU 的寄存器结构 — 栈指针 SP 与 PC 在哪里等着接中断
- 🖥️ 服务器工作原理 · 索引 — 服务器处理请求同样是中断与事件的世界
- 💻 计算机是怎样跑起来的 · 索引