我说的是核心层面的事情。
据我了解,控制器核心仅执行从内存中获取的指令(获取 - 解码 - 执行)。当中断到达时,核心/ALU 如何决定跳转到 ISR?
因为我们或编译器没有添加任何指令来轮询中断状态——那么它如何知道需要服务中断呢?
我说的是核心层面的事情。
据我了解,控制器核心仅执行从内存中获取的指令(获取 - 解码 - 执行)。当中断到达时,核心/ALU 如何决定跳转到 ISR?
因为我们或编译器没有添加任何指令来轮询中断状态——那么它如何知道需要服务中断呢?
您缺少的是,核心不仅仅执行从内存中获取的操作码。它具有实现中断的特定逻辑。
当中断检测硬件发出表明该中断的信号时,通常一条特殊指令被卡在从未从内存中获取的内核中。在大多数情况下,这是对中断向量地址的 CALL 指令。这使用了现有的指令执行机制,将当前PC保存到调用堆栈中,并将其更改为中断向量地址。它还处理丢弃预取指令等。
特殊的中断接收逻辑还必须以这样一种方式禁用中断,以便相同的中断条件不会导致下一个周期再次调用中断向量地址。不同的处理器有不同的处理方式。最简单的方法是全局禁用中断,要求软件在中断服务程序结束时重新启用它们。其他处理器具有中断优先级。这个级别是颠簸的,因此只有更高优先级的中断条件才能导致新的中断。然后,中断优先级与 CALL 返回地址一起自动保存,并在代码从中断返回时恢复。
在现代微控制器中,通常有一个专用的中断控制器 (IC) 单元负责管理中断。此外,如果某些条件适用(例如,该外设完成了一些工作),每个外围组件都有一个中断输出,该中断输出将从0
到1
(反之亦然)。该输出连接到中断控制器。CPU可以告诉IC要么忽略这个Core
特定的中断(屏蔽它),要么在它发生时通过触发特定信号通知MCU,然后MCU决定如何处理它。常见的方法是让 IC 告诉 MCU 确实发生了哪个中断并跳转到相应的处理代码。
计算机内核中有硬件将一个新值塞入程序计数器,该值对应于已触发的特定中断。为了记住中断例程完成后返回到哪里,程序计数器中的当前值在硬件将中断地址塞入程序计数器之前被压入堆栈。当中断例程完成时,程序计数器的原始值从堆栈中恢复。
在中断时插入程序计数器的值通常由两种方案之一确定。一种方法是将每种中断类型的固定地址塞入程序计数器,然后计算机内核从该固定位置开始执行。固定位置的空间大小通常是有限的,因此通常会在固定地址处编写跳转指令,以转到实际的中断服务位置。另一种方案使用称为中断向量表的东西。这里硬件根据中断类型在向量表中生成一个固定的地址偏移量。然后,硬件提取该表位置的内容,并使用该值作为地址塞入程序计数器。
控制器有一个用于程序计数器的寄存器,用于跟踪存储下一个要执行的指令的地址。(执行跳转时也会写入该寄存器。)
控制器有一个中断向量(或有时不止一个,取决于中断的类型),它是存储 ISR 的地址。这个地址总是一样的——它就像程序开始的复位向量。
(通常,该向量中存储有一条跳转指令,该指令跳转到要执行的实际代码,因为向量处的空间不足以存储整个过程。但是,重要的是 ISR 始终位于同一位置。)
当发生中断时,控制器中有一些专用硬件将中断向量写入程序计数器。然后,当控制器到达下一个指令周期时,它从程序计数器指向的地址(即中断向量)中获取指令。
(在控制器的一个指令周期中,它执行不同的任务:它从程序计数器指向的地址获取下一条指令;它增加程序计数器;它对指令进行解码并执行它。)