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