首页 文章

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

提问于
浏览
3

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

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

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

IP pushed onto the stack

在这里, After interrupt request 实际上意味着 After interrupt request has been served . 该图表显示的是,在中断请求发出之前,指令被缓存, with IP pointing to the address of the next byte of instruction in the CS memory segment . 为了服务中断请求,寄存器的内容(包括IP和标志)被压入堆栈段 . 在提供请求之后,先前的内容被加载回来 - with IP still pointing to the location of the 7th byte (指令),队列(缓存)为空 . 这是我的疑问 . IP递减指向i1吗?其次,我们需要手动处理IP(比如,在中断时将其推入堆栈)还是中断服务程序为我们处理这个问题?请,任何帮助表示赞赏,谢谢!


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

2 回答

  • 3

    您不太清楚“指令队列”的含义 .

    一个意思可能是"prefetched instructions" . 在实践中,处理器在指令流中从最后完成的指令的点开始推测性地预读,在分支之后或不基于各种类型的分支预测算法 . 由于这些是读操作,如果处理器决定放弃当前指令"stream"(例如,中断例程),则它只是忽略其预读 .

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

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

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

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

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

    一个非常快速的中断例程可能只保存足够的寄存器来完成其关键工作,然后在返回到中断之前恢复这些寄存器 .

  • 1
    • 当发生中断或陷阱时,CPU通过停止与高速缓存同步,直到所有挂起的高速缓存操作完成或被抢占为止 .

    • 如果缓存加载已在进行中,则完成,但队列中等待的其他操作将被抢占 .

    • 队列存储为缓存内部状态的一部分,因此在恢复上下文时,抢占的操作将重新排队 .

相关问题