【发布时间】:2014-06-30 22:38:21
【问题描述】:
我想知道 STMDB SP!, {R0-R8} 是否是 ARM(v7) 中的原子操作,因为它在我看来相当复杂。例如,CPU 是否有可能在“中间”某处中断,并且已经将 R5-R8 存储在堆栈中,并且 SP 现在是 SP_old - 16,并且在处理中断后处理器继续使用 R0-R4?谢谢。
【问题讨论】:
我想知道 STMDB SP!, {R0-R8} 是否是 ARM(v7) 中的原子操作,因为它在我看来相当复杂。例如,CPU 是否有可能在“中间”某处中断,并且已经将 R5-R8 存储在堆栈中,并且 SP 现在是 SP_old - 16,并且在处理中断后处理器继续使用 R0-R4?谢谢。
【问题讨论】:
为了澄清这里稍微混乱的答案组合,首先; v7-A1:
在标准配置中唯一可以中断多路访问指令的例外是同步数据中止,因此它们在中断方面实际上是原子的(尽管 不是内存访问)。
这是不正确的,但是,如果低延迟中断配置受支持并已启用。在这里,IRQ、FIQ 和异步中止也可以中断指令。在此引用 v7-A ARM ARM:
ARM 不赞成任何软件依赖的行为,即在访问普通内存的单个加载或存储指令生成的一系列内存事务中不会发生中断或异步中止。
注意
显示这种依赖的一个特殊情况是从内存中加载堆栈指针的加载倍数。在 LDM 期间发生中断的实现中,这可能会破坏堆栈指针。
以这种方式中断的指令将被放弃,如果返回,则从头开始执行(因此对于存储低地址可能会看到两次写入)。
其次是 v7-M2,带有古怪的异常模型:
这里每天都是低延迟的。在多个访问指令期间总是可以采取异常,但架构允许(在某些情况下)根据问题中的建议从中断点继续执行。放弃并重新启动行为也被允许作为替代,并且是不可继续指令/异常组合的唯一选择。
[1] ARMv7-A ARM (DDI0406C.b) 的 A3.5.3 和 B1.8.12 节
[2]ARMv7-M ARM (DDI0403D) 的 B1.5.10 部分
【讨论】:
就中断处理而言,它是原子的。
如果我没记错的话,中断指令会导致它在中断处理完成后被中止并重新执行,以保证中断延迟。
【讨论】:
如果配置,它可以被中断然后重新启动(不继续)。如果内存不可访问,也可以中止。
相对于其他设备而言,它不是原子的。
【讨论】:
STM 是一条指令,因此它与其他指令一样具有原子性。您告诉 cpu 从 SP-4 指向的内存开始保存 N 个寄存器,然后在一条指令中将 SP 更新为 SP-N*4。因此,它有责任在不同的模式切换(也称为中断)之间保持一致的状态。
【讨论】: