管道执行期间CPU如何知道它正在执行的指令有一些异常以及需要调用哪个处理程序。谁用这个处理程序地址更新pc?
答案 0 :(得分:0)
如何检测和处理异常的内部实现细节当然是针对每个不同的微体系结构的。
一个非常普遍的事情是精确的异常处理(在执行之前执行所有操作,在异常之后不执行任何操作)需要按顺序退出指令,即使是在外部也是如此有序CPU。如果你让一条指令提交并在之后的指令之前保留乱序核心,那么如果后来的指令出现异常,你就无法回滚它。
在顺序CPU中很容易发生这种情况,但这就是无序CPU需要大ROB的原因,大于乱序调度程序仍然需要等待它们的指令输入。
维基百科的经典RISC管道文章在Exceptions部分中有一些有趣的内容,它们通用,足以应用于典型的有序管道,而不是特定的实现。
异常与分支和跳转不同,因为那些其他控制流更改在解码阶段得到解决。在写回阶段解决了异常。 当检测到异常时,以下说明(管道中的早期)被标记为无效,并且当它们流向管道末尾时,其结果将被丢弃。程序计数器设置为特殊异常处理程序的地址,并使用异常位置和原因写入特殊寄存器。
正如玛格丽特所说,为每个不同的异常分配了一个数字,操作系统将处理程序地址放入表中。
例如,在x86上,0x06
是无效操作码的例外号码。检测到时,CPU会从IVT(实模式)或IDT(受保护或64位模式)加载条目。
在实际跳转之前,它会在内核堆栈上推送当前的IP / EIP / RIP和其他异常返回内容。之后,CPU内部的PC到处理程序地址。
表的基地址存储在CPU内部(使用LIDT
更新),但开机默认位置为0000:0000H
(物理内存的开始)。
无论如何,表查找和实际跳转到异常处理程序与管道检测异常的方式几乎是分开的。
在无序CPU中,如果在推测性地执行的某些事件中检测到异常(例如,在条件分支之后的代码),则直到它被实际执行才会被执行。已知是非投机性的。即直到分支实际执行并发现分支预测的方向。
如果事实证明CPU正在推测错误的路径,那么异常就会被压扁。