Tôi đã thực hiện một số thử nghiệm với gcc 4.5.2 (được xây dựng với LTO). Nếu tôi biên dịch mã này:
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;
}
sử dụng arm-none-eabi-gcc -Os -mcpu=cortex-m3 -mthumb -c dmb.c
, sau đó từ arm-none-eabi-objdump -d dmb.o
tôi có được điều này:
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
Rõ ràng là __DBM()
chỉ chèn hướng dẫn dmb
và phải mất DMB2()
để thực sự buộc các trình biên dịch xóa các giá trị được lưu trong bộ đăng ký.
Tôi đoán tôi đã tìm thấy lỗi CMSIS.
Câu hỏi hay. Lưu ý rằng Linux sử dụng 'bộ nhớ' clobber: http://lxr.free-electrons.com/source/arch/arm/include/asm/system.h?v=2.6.39#L135 – ninjalj
@ninjalj: Cảm ơn vì liên kết. (không xuất hiện trên googling nhanh chóng) – jpc