我目前正在阅读ARM网站上的ARM Cortex M0 +用户指南,如下所示
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0662b/CHDBIBGJ.html
在“用户手册”中,提到了以下段落:
可中断重启指令
可中断可重启指令是LDM,STM,PUSH,POP,并且在32周期乘法器实现中是MULS。当在执行这些指令之一期间发生中断时,处理器放弃执行该指令。在处理完中断后,处理器从头开始重新执行指令。
我无法理解可重启指令的工作原理?有人可以用一个例子向我解释可中断可重启指令的不同阶段(获取,解码和执行)吗?当中断到来时,指令管道会发生什么?
答案 0 :(得分:1)
对于LDM,执行阶段实际上是多个周期(每个寄存器至少一个周期)。
这是简单的获取/解码/执行模型开始崩溃的地方-执行实际上是一个非平凡的状态机,可以经常表示一个周期,但是有少数“特殊”状态操作。
使用Cortex M,即使在基本级别上,当发生异常时,除了将获取指向异常处理程序并等待执行脱离当前指令后等待执行释放之外,还有很多工作要做
在硬件级别理解不间断和可重新启动指令的关键部分是它们由体系结构寄存器控制,并且没有很多中间状态。处于中间状态的位置将其存储在EPSR.ICI中。还有一些中间寄存器存储区用于诸如乘法中间结果之类的事情,因此可以恢复体系结构寄存器而不会损坏。
关于为什么的架构致力于支持可重新启动或可持续的指令(如注释中所述),这专门用于改善中断等待时间(这是Cortex-M的关键之一)特征)。对于单个加载或存储,程序员通常具有足够的控制权,可以在中断延迟至关重要的情况下避免风险太大的数据接口停顿,并且对12个周期的延迟不应有太大影响。对于多个加载/存储,延迟可能会很大(从程序的角度来看,当异常悬而未决时,像堆栈压入之类的操作就毫无价值,因为处理程序本身会满足即时的上下文保存要求)。由于这些处理器通常仅具有一个数据存储器接口,因此微代码异常堆栈无法与完成加载/存储倍数的其余拍子并行进行。
需要权衡多循环指令,这些指令被简单地放弃,指令被暂停以在以后继续,并且指令必须完成。由于总线接口,一旦开始传输,它就必须完成。连续的指令不是原子的,并且可重新启动的指令可能导致重复访问同一地址(因此,在写入外围设备fifo等时必须避免这些操作)。通过保持良好的中断性能,对于目标应用程序而言,所有这些额外的复杂性仍然是合理的,并且通常不需要程序员担心精确的细节。另一种选择是在各个地方使用单独的LDM,这从代码密度的角度来看效率低下(并且可能取决于uArch /系统的性能)。