我需要一个线程保存idx++和idx-操作。禁用中断,即使用临界区,是一回事,但我想来理解为什么我的操作不是原子的,正如我所期望的那样?下面是使用segger ozone的内联汇编代码的c代码:(还请注意,变量的地址显示32位变量在内存中是32位对齐的,8位和16位变量都是16位对齐的)
volatile static U8 dbgIdx8 = 1000U;
volatile static U16 dbgIdx16 = 1000U;
volatile static U32 dbgIdx32 = 1000U;
dbgIdx8 ++;
080058BE LDR R3, [PC, #48]
080058C0 LDRB R3, [R3]
080058C2 UXTB R3, R3
080058C4 ADDS R3, #1
080058C6 UXTB R2, R3
080058C8 LDR R3, [PC, #36]
080058CA STRB R2, [R3]
dbgIdx16 ++;
080058CC LDR R3, [PC, #36]
080058CE LDRH R3, [R3]
080058D0 UXTH R3, R3
080058D2 ADDS R3, #1
080058D4 UXTH R2, R3
080058D6 LDR R3, [PC, #28]
080058D8 STRH R2, [R3]
dbgIdx32 ++;
080058DA LDR R3, [PC, #28]
080058DC LDR R3, [R3]
080058DE ADDS R3, #1
080058E0 LDR R2, [PC, #20]
080058E2 STR R3, [R2]
不能保证++
和--
是原子的。如果你需要保证原子性,你将不得不寻找其他的方法。
正如@StaceyGirl在评论中指出的那样,你也许可以使用 但是Cortex M3有特殊的指令来锁定对内存位置的访问。LDREX,STREX。https://developer.arm.com/documentation/100235/0004/the-cortex-m33-instruction-set/memory-access-instructions/ldaex-and-stlex 您可以直接在C代码中使用它们,而不用使用intrinsic。