8086中的中断,指令指针和指令队列

时间:2014-05-23 21:13:53

标签: assembly interrupt x86-16 interrupt-handling microprocessors

假设向8086发出外部中断请求。处理器将在完成当前正在执行的指令(如果有)后处理中断。在处理中断之前,通过将数据推入堆栈段,也将保存程序的状态(PSW标志,寄存器等)。

现在,大多数教程/文档都描述了指令指针也被压入堆栈段,这是可以的,因为它指向代码段中的下一个指令字节(就在发出中断请求之前)。

但是指令队列会发生什么?在处理中断请求时,它是否也被压入堆栈段?还是它的内容被清零?在这种情况下,不应该递减指令指针,以便可以指向代码段中的先前指令(在中断服务之后)?

IP pushed onto the stack

此处, 中断请求后 实际上意味着 中断请求后 。该图显示的是,在中断请求到来之前,指令被高速缓存,,IP指向CS存储器段中下一个指令字节的地址。为了提供中断请求,寄存器(包括IP和标志)的内容被压入堆栈段。在提供请求之后,先前的内容被加载回来 - ,IP仍然指向第7个字节的位置(指令),队列(缓存)为空。这是我的疑问。 IP是否递减以指向i1 ?其次,我们需要手动处理IP(比如,在中断时将其推入堆栈)还是中断服务程序为我们处理这个问题?拜托,感谢任何帮助,谢谢!


注意:Instruction Queue - 8086架构有一个6字节的预取指令流水线。当执行单元执行当前指令时,总线接口单元预先从存储器中读取最多六个字节的操作码。

2 个答案:

答案 0 :(得分:3)

您对“指令队列”的含义并不十分清楚。

一个含义可能是“预取指令”。在实践中,处理器在指令流中从最后的完成的指令的点开始推测性地预读,在分支之后或者不是基于各种类型的分支预测算法。由于这些是读取,如果处理器决定放弃当前指令“stream”用于另一个(例如,中断例程),它只是忽略了它的预读。

另一个意思可能是“部分执行的指令(在飞行中/在'管道中')”,这经常发生在超标量CPU上。在异步中断的情况下,处理器必须完成那些影响系统可见状态的处理器(例如,已经提交了对寄存器或存储器的写入),并且可能会或可能不会完成其他指令,具体取决于特定处理器的设计者。在同步陷阱的情况下,处理器必须完成影响状态的指令,但只是放弃其余的(OP的短语是“队列中的零”,它具有正确的概念,但错误的措辞)。

[根据OP的要求添加我做出的评论]: 你说8086有一个6字节的预取“指令管道”(坏词IMHO)。可能有一个属性,但这是实现的细节,并没有充分的理由相信这是所有8086的属性。对于现代CPU,实现指令预取的方式仅取决于设计者的聪明才智。关于所有你可以合理预测的是,会有一些预取方案,除了对性能的影响和有关自修改代码的有趣规则之外,你很难在应用程序中检测它的存在。

[回答OP的第二个问题]: 其次,我们是否需要手动处理IP(例如,在中断时将其推入堆栈)或者中断服务程序是否为我们处理这个问题?

对于任何类型的陷阱或中断,存储架构定义的状态(“寄存器”,PC等)就足够了。对于许多处理器,硬件存储架构状态的关键子集就足够了,让中断例程存储(并最终恢复)其余的处理器。因此,存储整个状态的责任在硬件和软件之间分配(以节省硬件中的实现工作量)。

对于x86系列,通常指令指针(IP)和标志寄存器由硬件推送到当前堆栈,控制转移到中断,中断例程具有通常存储其余寄存器的指令操作系统定义的数据结构,通常称为“上下文块”。中断例程完成其工作,并通过重新加载寄存器将控制返回给应用程序,然后使用特殊的IRET指令重新加载IP和标志,或者将控制转移到选择运行其他活动的OS调度程序,最终使用保存的上下文块内容重新启动应用程序。

真正的快速中断例程可能会保存足够的寄存器来完成其关键工作,然后在返回到中断之前恢复这些寄存器。

答案 1 :(得分:1)

  • 当发生中断或陷阱时,CPU会通过停止与缓存同步,直到所有挂起的缓存操作完成或抢占为止。
  • 如果缓存加载已在进行中,则完成,但其他加载 在队列中等待的操作被抢占。
  • 队列存储为缓存内部状态的一部分,因此在恢复上下文时,抢占的操作将重新排队。