编译器:arm-none-eabi-gcc
1. const and rodata section
先看c代码,apb_psc_table[8] 是个常量数组。
static const u8 apb_psc_table[8] = {
0, 0, 0, 0, 1, 2, 3, 4
};
unsigned long clock_get(enum clock clck)
{
u32 sysclk = 0;
u32 shift = 0;
/* Prescaler table lookups for clock computation */
u8 ahb_psc_table[16] = {
0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
};
/*operations*/
};
编译链接后dump出汇编指令和数据:
80005aa: 4a07 ldr r2, [pc, #28] ; (80005c8 <clock_get+0x98>)
80005ac: 5cd3 ldrb r3, [r2, r3]
80005ae: 40d8 lsrs r0, r3
80005b0: e000 b.n 80005b4 <clock_get+0x84>
80005b2: 2000 movs r0, #0
80005b4: b004 add sp, #16
80005b6: bd70 pop {r4, r5, r6, pc}
80005b8: 08014766 stmdaeq r1, {r1, r2, r5, r6, r8, r9, sl, lr}
80005bc: 40023808 andmi r3, r2, r8, lsl #16
80005c0: 40023804 andmi r3, r2, r4, lsl #16
80005c4: 007a1200 rsbseq r1, sl, r0, lsl #4
80005c8: 0801495e stmdaeq r1, {r1, r2, r3, r4, r6, r8, fp, lr}
apb_psc_table[8] 在0x801495e这个地址。而这个地址位于rodata section。
下面改变apb_psc_table[8]的定义,加上volatile。
2.volatile const 和data section
static volatile const u8 apb_psc_table[8] = {
0, 0, 0, 0, 1, 2, 3, 4
};
unsigned long clock_get(enum clock clck)
{
u32 sysclk = 0;
u32 shift = 0;
/* Prescaler table lookups for clock computation */
u8 ahb_psc_table[16] = {
0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9
};
/*operations*/
}
再看汇编:
80005aa: 4a07 ldr r2, [pc, #28] ; (80005c8 <clock_get+0x98>)
80005ac: 5cd3 ldrb r3, [r2, r3]
80005ae: 40d8 lsrs r0, r3
80005b0: e000 b.n 80005b4 <clock_get+0x84>
80005b2: 2000 movs r0, #0
80005b4: b004 add sp, #16
80005b6: bd70 pop {r4, r5, r6, pc}
80005b8: 08014766 stmdaeq r1, {r1, r2, r5, r6, r8, r9, sl, lr}
80005bc: 40023808 andmi r3, r2, r8, lsl #16
80005c0: 40023804 andmi r3, r2, r4, lsl #16
80005c4: 007a1200 rsbseq r1, sl, r0, lsl #4
80005c8: 0801a782 stmdaeq r1, {r1, r7, r8, r9, sl, sp, pc}
apb_psc_table[8]的地址变成了0x0801a782,到了data section里面。
可以看到是volatile关键字改变了常量数组的位置变化。是不是volatile关键字表示易变,编译器就理解为可写的?
volatile可以告诉编译器变量是只读易变的吗?