1.芯片执行指令时可能会重新排序,并不一定按照代码的指令顺序执行。如下实例代码中,两个地址0x1000和0x1100,不能确定谁先被先写入1,。
ldr r0, =0x1000
mov r1, #1
str r1, [r0, #0] /* 往内存地址0x1000写入1 */
str r1, [r0, #0x100] /* 往内存地址0x1100写入1 */
2.DMB能确保执行顺序,但是不会阻塞CPU的运行
ldr r0, =0x1000
mov r1, #1
str r1, [r0, #0]
DMB
str r1, [r0, #0x100] /* CPU先会执行上一条str,再执行本条语句 */
3.DSB比DMB更强,它会阻塞CPU的运行,等待上一条内存操作完成后,才会让CPU重新运行
ldr r0, =0x1000
mov r1, #1
str r1, [r0, #0]
DSB /* CPU会被阻塞在这里,等待数据1被成功写入到内存地址0x1000中 */
str r1, [r0, #0x100]
4.ISB和DSB有一个共同点,也会阻塞CPU的运行,不同的点是,它不像DSB等待的是内存更新完,而是等待CPU上下文状态的更新完成(简单理解为,缓存,MPU,等系统寄存器的更新)
cpsid i /* 关闭IRQ中断 */
ISB /* CPU会被阻塞在这里,等待CPU确实已经关闭了中断了后,才让CPU恢复执行 */
str r1, [r0, #0x100] /* 运行这条语句绝对不会再触发IRQ中断了 */