首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ARM Cortex-M3启动文件

ARM Cortex-M3启动文件
EN

Stack Overflow用户
提问于 2014-06-22 14:11:25
回答 1查看 1.8K关注 0票数 1

我正在为ARM Cortex-M3微控制器修改启动文件。到目前为止,一切都很好,但是我有一个问题,那就是是否需要使用汇编程序代码来执行BSS块的零填充。

默认情况下,启动文件中的重置中断如下所示:

代码语言:javascript
复制
// 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"
);

使用该代码,一切都如预期的那样工作。但是,如果我为下面的代码更改了前面的代码,它将停止工作:

代码语言:javascript
复制
// Zero fill the bss segment.
for(pui32Dest = &_bss; pui32Dest < &_ebss; )
{
    *pui32Dest++ = 0;
}

原则上,这两种代码都应该做同样的事情(用零填充BSS ),但是第二种代码由于一些我不理解的原因而不能工作。我相信.thumb_func指令必须在这里发挥作用,但我对ARM汇编程序并不十分熟悉。有什么想法或方向可以帮助我理解吗?谢谢!

编辑:顺便说一下,初始化数据段(例如从Flash复制)的代码如下所示,并且工作正常。

代码语言:javascript
复制
// Copy the data segment initializers from flash to SRAM.
pui32Src = &_etext;
for(pui32Dest = &_data; pui32Dest < &_edata; )
{
    *pui32Dest++ = *pui32Src++;
}

编辑:为这两个函数添加了消隐代码。

大会第一阶段的情况如下:

代码语言:javascript
复制
  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>

第二阶段的大会如下:

代码语言:javascript
复制
  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>
EN

回答 1

Stack Overflow用户

发布于 2014-06-22 16:56:31

如果初始堆栈按建议位于.bss部分,您可以从反汇编中看到C代码失败的原因--它正在从堆栈加载当前指针,将增量指针保存回堆栈,对位置进行归零,然后为下一次迭代重新加载增量指针。如果在使用堆栈时将堆栈的内容调零,就会发生不好的事情。

在这种情况下,打开优化可能会修复它(智能编译器在实际尝试时应该生成与程序集代码几乎相同的内容)。不过,更普遍的情况是,在执行通常在C运行时环境以下的级别时,考虑坚持使用汇编代码可能更安全一些--从C代码中引导C环境,而C代码期望环境已经存在,充其量是有风险的,因为您只能希望代码不会尝试使用尚未设置的任何内容。

快速浏览一下(我不太熟悉Cortex-M开发的具体细节)之后,似乎有一种替代的/额外的解决方案可能正在调整链接器脚本,以便将堆栈移到其他地方。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24352082

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档