Other Parts Discussed in Thread: MSP430F249
器件型号: MSP430-GCC-OPENSOURCE
主题中讨论的其他器件: MSP430F249
我迭代一个函数指针表、该表使用链接器脚本放置在闪存内。 GCC 使 R12 中的循环/迭代指针保留在间接调用中。 我知道 R12 是调用者保存的寄存器、因此被调用函数如果可以随时缓冲寄存器、调用者应该在整个调用中保留它。
下面是我的应用示例:
typedef void(*sys_init_t)(void);
static void init_fn_0(void) {
/* trivial, does not disturb r12 */
}
static void init_fn_1(void) {
volatile int a = 1, b = 2, c = 3, d = 4, e = 5;
(void)a; (void)b; (void)c; (void)d; (void)e;
/* enough live locals at -Os to force r12 use as scratch */
}
__attribute__((section(".sys_init"), used))
static const sys_init_t init0 = init_fn_0;
__attribute__((section(".sys_init"), used))
static const sys_init_t init1 = init_fn_1;
extern const sys_init_t __sys_init_start;
extern const sys_init_t __sys_init_end;
void sys_init(void) {
for(const sys_init_t* fn = &__sys_init_start; fn < &__sys_init_end; fn++) {
(*fn)();
}
}
int main() {
sys_init();
return 0;
}
除了 Sections 部分之外、我还使用了 MSP430F249 的原始链接器脚本:
.sys_init:
{
_sys_init_start =.;
Keep (*(.sys_init));
_sys_init_end =.;
}> ROM
我将按如下方式构建应用:
msp430-elf-gcc -mcpu=MSP430 -mmcu=msp430f249 -g0 -OS -D__MSP430F249__=1 -c main.c -o main.o
MSP430-elf-gcc -mcpu=MSP430 -mmcu=msp430f249 -g0 -OS -D__MSP430F249__=1 -T linker.ld main.o -o example.out
00001148 :
1148: 3c 40 00 11 mov #4352、 R12 ;#0x1100
0000114c <.L4>:
114c: 3c 90 04 11 CMP #4356、 R12 ;#0x1104
第 1150 章:我的心 JNC +4 美元 ;ABS 0x1154
1152: 30 41. 返回
00001154 <.L5>:
1154: 3D 4c MOV @R12+, R13 ;
1156: 8D 12 呼叫 R13 ;
1158: F9 3f JMP –12 美元 ;abs 0x114c
可以看到、在 call r13 跳回 0x114c 后、再次对 R12 进行评估、即使被调用的函数可能对寄存器进行了空间控制。 在这种情况下、代码将崩溃。
msp430-elf-gcc -version:
MSP430-elf-gcc (Mitto Systems Limited - MSP430-gcc 9.3.1.11) 9.3.1