繁体   English   中英

ARM Cortex-M3启动文件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM