8086中的中断,指令指针和指令队列
假设有一个外部中断请求发送到8086.处理器将在完成当前正在执行的指令(如果有)后处理中断。 在处理中断之前,程序的状态也将通过将数据推入堆栈段来保存(PSW标志,寄存器等)。
现在,大多数教程/文档描述了指令指针也被压入堆栈段,这是可以的,因为它指向代码段中的下一个指令字节(就在中断请求之前)。
但是指令队列发生了什么? 当正在处理中断请求时,它是否也被压入堆栈段? 还是它的内容被清除为零? 在这种情况下,不应该减少指令指针,以便可以指向代码段中之前的指令(在中断服务之后)?
这里, 中断请求实际上意味着在中断请求服务完成之后 。 该图显示的是,在发出中断请求之前,指令被缓存, IP指向CS存储段中下一个字节的地址 。 为了提供中断请求,寄存器的内容(包括IP和标志)被压入堆栈段。 在请求被提供之后,先前的内容被加载回来--IP仍然指向 (指令的) 第7个字节的位置 ,并且队列(缓存)是空的。 这是我的疑问。 IP减少指向i1? 其次,我们是否需要手动处理IP(例如,在中断时将其推入堆栈)还是中断服务例程为我们处理? 请,任何帮助表示赞赏,谢谢!
注意:指令队列 - 8086架构有一个6字节的预取指令流水线。 当执行单元正在执行当前指令时,总线接口单元预先从存储器读取最多六个字节的操作码。
你对“指令队列”的含义不是很清楚。
一个含义可能是“预取指令”。 在实践中,处理器在指令流中从最后完成的指令的点开始推测性地预读,在分支之后或不基于各种类型的分支预测算法。 由于这些是读取操作,如果处理器决定放弃另一个当前指令“流”(例如,中断例程),它就会忽略它的预读。
另一个含义可能是“部分执行的指令(在飞行中/在'管道中')”,这在超标量CPU中经常发生。 在异步中断的情况下,处理器必须完成那些影响系统可见状态的事件(例如,已经向寄存器或存储器提交了写入),并且可能会或可能不会完成其他指令,这取决于特定处理器的设计者。 在同步陷阱的情况下,处理器必须完成影响状态的指令,但只是放弃其余的(OP的短语是“零队列”,它具有正确的概念,但错误的措辞)。
[在OP的请求中添加我发表的评论]:你说8086有一个6字节的预取“指令管道”(坏项恕我直言)。 可能有那个属性,但这是实现的细节,没有理由相信这是所有8086的属性。 对于现代CPU而言,指令预取的实现方式仅取决于设计师的聪明才智。 关于您可以合理预测的所有内容,都会有一些预取方案,除了对性能和有关自修改代码的有趣规则的影响之外,您将很难在应用程序中检测到它的存在。
[回答OP的第二个问题]:其次,我们是否需要手动处理IP(例如,在中断时将其推入堆栈)还是中断服务例程为我们处理?
对于任何类型的陷阱或中断,存储体系结构定义的状态(“寄存器”,PC等)就足够了。 对于许多处理器来说,硬件足以存储架构状态的关键子集,并让中断例程存储(并最终恢复)其余部分。 因此,存储整个状态的责任在硬件和软件之间进行分配(以节省硬件中的实施工作)。
对于x86系列,通常情况下,指令指针(IP)和标志寄存器被硬件压入当前栈,控制转移到中断,中断程序有指令将其余寄存器保存在操作系统中,系统定义的数据结构通常称为“上下文块”。 中断例程执行其任务,并通过重新加载寄存器将控制权返回给应用程序,然后使用特殊的IRET指令重新加载IP和标志,或者将控制权转交给选择运行其他活动的OS调度程序,最终使用保存的上下文块内容重新启动应用程序。
一个真正快速的中断例程可能只保存足够的寄存器来完成其关键工作,然后在返回给中断者之前恢复这些寄存器。
上一篇: Interrupts, Instruction Pointer, and Instruction Queue in 8086