在 Cortex-M7 中,我有一个用
-Os
编译的函数,位于特定地址中,我通过函数指针调用它,如下所示(+1
用于拇指模式):
//Some code above...
memset(.....)
uint32_t (*caller)(uint32_t taskid, ...);
caller = (uint32_t(*)(uint32_t, ...))((uint32_t)0x08020000 + 1U);
for (size_t i = 0; i < 3; ++i) {
caller(i);
}
函数被调用
3
次并返回,但是函数内部的i
参数不是0,1,2
,而是garbage,0,1
。如果我不使用 -Os
编译器选项,情况就不是这样。
检查反汇编,似乎 for 循环已展开,带有
movs r0, #1
和 movs r0, #2
,甚至还重新排序了。
memset(shared_ram, 0x00, sizeof(*shared_ram));
8000968: 2000 movs r0, #0
caller(i);
800096a: 4d1a ldr r5, [pc, #104] ; (80009d4 <main+0xc0>)
memset(shared_ram, 0x00, sizeof(*shared_ram));
800096c: 6018 str r0, [r3, #0]
800096e: 6058 str r0, [r3, #4]
8000970: 6098 str r0, [r3, #8]
caller(i);
8000972: 47a8 blx r5
8000974: 2001 movs r0, #1
8000976: 47a8 blx r5
8000978: 2002 movs r0, #2
800097a: 47a8 blx r5
这是编译器错误吗?
Cortex-M7 缓存未启用(如果这很重要)。
编译标志:
-fdata-sections -ffunction-sections --specs=nano.specs -Wl,--gc-sections -g -mthumb -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -Og -g3 -ggdb -fno-eliminate-unused-debug-symbols -fdata-sections -ffunction-sections -Wall -Wextra -Wpedantic -Wno-unused-parameter -Os -std=gnu11
问题与编译器无关(99.9% 的情况)。我的函数包含相同的分支,因此编译器选择了
default
方式并且不关心变量值。
__attribute__((section(".security_secure_gate")))
uint32_t se_secure_gate(uint32_t id, ...) {
switch (id) {
case 0: {
__NOP();
break;
}
default: {
__NOP();
break;
}
}
return 0;
}