短文标题: 中断向量表:CPU的"紧急联系人"名单

【传播知识 手有余香🌹】转发此文到朋友圈 赠送 于振南老师 知识视频合集哦!
你有没有想过一个问题:当中断发生时,CPU怎么知道该跳转到哪个函数?比如USART1中断来了,CPU怎么知道要去USART1_IRQHandler?答案是:查表 。这个表叫中断向量表 。它是一张函数指针数组,存在Flash的开头。每个中断源对应表里的一个条目,存着中断处理函数的地址。中断来了,CPU查表,跳转。
那个"函数指针"的数组, 中断向量表,本质上是一个函数指针数组。

typedef void (*pHandler)(void);
pHandler vector_table[] = {
(pHandler)0x20001000, // 栈顶地址
Reset_Handler, // 复位
NMI_Handler, // 不可屏蔽中断
HardFault_Handler, // 硬错误
// ...
USART1_IRQHandler, // USART1中断
// ...
};
每个条目是一个函数指针。中断号,就是数组索引。
那个"固定"的位置, 中断向量表固定在Flash的0x08000000 地址(STM32)。上电后,CPU先读第一个字(栈顶地址),再读第二个字(Reset_Handler地址)。然后跳转到Reset_Handler。其他中断也一样------查表,跳转。

那个"弱定义"的默认, 启动文件里,中断处理函数是弱定义(weak)。
__weak void USART1_IRQHandler(void)
{
while(1); // 默认:死循环
}
如果你没写这个函数,链接器就用默认的。如果你写了,链接器用你的。这是"默认实现,可覆盖"的设计模式。那个"重定向"的魔法, 中断向量表可以重定位 (移到RAM)。SCB寄存器里有VTOR(向量表偏移寄存器)。写VTOR,把向量表移到RAM。然后,你可以在运行时动态修改中断处理函数。这是高级玩法。
**那个"调试"的技巧,**调试时,看中断向量表:
- 查看0x08000000地址的数据
- 第一个字是栈顶地址
- 第二个字是Reset_Handler地址
- 对照数据手册,就知道中断函数在哪
能看懂向量表,是调试高手。那个"保留"的条目, 向量表前16个条目是内核异常 (Reset、NMI、HardFault等)。后面的条目是外设中断 (USART、TIM、EXTI等)。不同型号的STM32,外设中断数量不同。向量表大小,取决于芯片型号。这个故事给我们的启示, 为什么CPU能快速找到中断处理函数?因为有向量表 。中断号 → 表索引 → 函数地址 → 跳转。**查表,比if-else快得多。**这是"用空间换时间"的经典案例。
写在最后, 下次你写中断处理函数,别只管功能。想想那张叫"中断向量表"的名单。它告诉CPU:这个中断来了,去这个函数。没有它,中断不知道往哪跑。

(本文灵感源于于振南《新概念ARM32单片机》教程中对中断向量表的深刻讲解,感谢作者将中断系统的底层机制讲得如此通透。)
如果您觉得这个故事对您有启发,欢迎点赞、转发,让更多工程师看到这个藏在向量表背后的"查表"哲学。关注我,一起探索嵌入式世界里那些"查比判快"的硬核真相。
