用于Cortex-M3的CMSIS库中的数据存储器屏障(DMB)

jpc*_*jpc 5 gcc cortex-m3 inline-assembly

在gcc的CMSIS定义中,您可以找到如下内容:

static __INLINE void __DMB(void) { __ASM volatile ("dmb"); }
Run Code Online (Sandbox Code Playgroud)

我的问题是:如果内存障碍没有在clobber列表中声明"内存",它有什么用?

它是core_cm3.h中的错误还是有一个原因导致gcc在没有任何其他帮助的情况下应该正常运行?

jpc*_*jpc 5

我用gcc 4.5.2(使用LTO构建)进行了一些测试.如果我编译这段代码:

static inline void __DMB(void) { asm volatile ("dmb"); }
static inline void __DMB2(void) { asm volatile ("dmb" ::: "memory"); }

char x;

char test1 (void)
{
  x = 15;
  return x;
}

char test2 (void)
{
  x = 15;
  __DMB();
  return x;
}

char test3 (void)
{
  x = 15;
  __DMB2();
  return x;
}
Run Code Online (Sandbox Code Playgroud)

使用arm-none-eabi-gcc -Os -mcpu=cortex-m3 -mthumb -c dmb.c,然后从arm-none-eabi-objdump -d dmb.o我得到这个:

00000000 <test1>:
   0:   4b01        ldr r3, [pc, #4]    ; (8 <test1+0x8>)
   2:   200f        movs    r0, #15
   4:   7018        strb    r0, [r3, #0]
   6:   4770        bx  lr
   8:   00000000    .word   0x00000000

0000000c <test2>:
   c:   4b02        ldr r3, [pc, #8]    ; (18 <test2+0xc>)
   e:   200f        movs    r0, #15
  10:   7018        strb    r0, [r3, #0]
  12:   f3bf 8f5f   dmb sy
  16:   4770        bx  lr
  18:   00000000    .word   0x00000000

0000001c <test3>:
  1c:   4b03        ldr r3, [pc, #12]   ; (2c <test3+0x10>)
  1e:   220f        movs    r2, #15
  20:   701a        strb    r2, [r3, #0]
  22:   f3bf 8f5f   dmb sy
  26:   7818        ldrb    r0, [r3, #0]
  28:   4770        bx  lr
  2a:   bf00        nop
  2c:   00000000    .word   0x00000000
Run Code Online (Sandbox Code Playgroud)

很明显,__DBM()只插入dmb指令并DMB2()实际强制编译器刷新寄存器中缓存的值.

我想我发现了一个CMSIS错误.