[英]ARM Cortex-M3 startup file
我正在修改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汇编器不是很熟悉。 有什么想法或方向可以帮助我理解吗? 谢谢!
编辑 :顺便说一句,用于初始化数据段(例如,从闪存复制到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>
如果初始堆栈如建议的那样位于.bss
节中,您可以从反汇编中看到C代码失败的原因-它正在从堆栈中加载当前指针,将递增的指针保存回堆栈,将位置清零,然后重新加载下一次迭代的增量指针。 如果在使用堆栈时将堆栈的内容清零,则会发生不良情况。
在这种情况下,启用优化可能会解决该问题(智能编译器如果实际尝试生成的代码,则应生成与汇编代码几乎相同的代码)。 不过,更一般而言,在执行此类操作(通常在低于C运行时环境的水平下执行)时考虑使用汇编代码可能更安全-从C代码引导C环境,因为C代码期望该环境已经存在会带来风险最好,因为您只能希望代码不要尝试使用尚未设置的任何内容。
快速浏览后(我不太熟悉Cortex-M开发的细节),看来替代/其他解决方案可能是调整链接程序脚本以将堆栈移动到其他位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.