【发布时间】:2014-06-22 14:11:25
【问题描述】:
我正在修改 ARM Cortex-M3 微控制器的启动文件。到目前为止一切正常,但我有一个关于是否需要使用汇编代码来执行 BSS 块的零填充的问题。
默认情况下,启动文件中的复位中断如下所示:
// Zero fill the bss segment.
__asm( " ldr r0, =_bss\n"
" ldr r1, =_ebss\n"
" mov r2, #0\n"
" .thumb_func\n"
" zero_loop:\n"
" cmp r0, r1\n"
" it lt\n"
" strlt r2, [r0], #4\n"
" blt zero_loop"
);
使用该代码,一切都按预期工作。但是,如果我将以前的代码更改为以下代码,它将停止工作:
// Zero fill the bss segment.
for(pui32Dest = &_bss; pui32Dest < &_ebss; )
{
*pui32Dest++ = 0;
}
原则上,两个代码都应该做同样的事情(用零填充 BSS),但第二个代码由于某种我无法理解的原因不起作用。我相信 .thumb_func 指令必须在这里发挥作用,但我对 ARM 汇编器不是很熟悉。有什么想法或方向可以帮助我理解吗?谢谢!
编辑:顺便说一下,初始化数据段的代码(例如从 Flash 复制到 RAM)如下,并且工作正常。
// Copy the data segment initializers from flash to SRAM.
pui32Src = &_etext;
for(pui32Dest = &_data; pui32Dest < &_edata; )
{
*pui32Dest++ = *pui32Src++;
}
编辑:为这两个函数添加了反汇编代码。
第一个组件看起来像:
2003bc: 4806 ldr r0, [pc, #24] ; (2003d8 <zero_loop+0x14>)
2003be: 4907 ldr r1, [pc, #28] ; (2003dc <zero_loop+0x18>)
2003c0: f04f 0200 mov.w r2, #0
002003c4 <zero_loop>:
2003c4: 4288 cmp r0, r1
2003c6: bfb8 it lt
2003c8: f840 2b04 strlt.w r2, [r0], #4
2003cc: dbfa blt.n 2003c4 <zero_loop>
第二个组件看起来像:
2003bc: f645 5318 movw r3, #23832 ; 0x5d18
2003c0: f2c2 0300 movt r3, #8192 ; 0x2000
2003c4: 9300 str r3, [sp, #0]
2003c6: e004 b.n 2003d2 <ResetISR+0x6e>
2003c8: 9b00 ldr r3, [sp, #0]
2003ca: 1d1a adds r2, r3, #4
2003cc: 9200 str r2, [sp, #0]
2003ce: 2200 movs r2, #0
2003d0: 601a str r2, [r3, #0]
2003d2: 9a00 ldr r2, [sp, #0]
2003d4: f644 033c movw r3, #18492 ; 0x483c
2003d8: f2c2 0300 movt r3, #8192 ; 0x2000
2003dc: 429a cmp r2, r3
2003de: d3f3 bcc.n 2003c8 <ResetISR+0x64>
【问题讨论】:
-
它在什么意义上“停止工作”?
-
挂起,执行没有到达主函数。对我来说,这可能与 ARM 与 Thumb 模式有关,也可能是循环错误(例如,它没有结束)。
-
一般情况下,在完成C bootstrap,鸡和蛋之前,你不想做C,这样的问题是可以预料的。设置堆栈,清除 .bss 并将 .data 复制到 asm 中(最好是非内联),至少在触摸第一个 C 之前...
-
codered/lpcXpresso/precision32 的启动代码使用 c/c++,看起来和你正在做的非常相似。没有理由不能或不应该在 c 中。
标签: c assembly arm startup cortex-m3