当前位置: 首页 > 知识库问答 >
问题:

ldr的意外行为[pc,#值]

宰父飞翼
2023-03-14

我使用GNU gcc(4.8.1429)为ARM(ATsam4LC4B:cortexM4 core,256K flash)构建了一个简单的应用程序:

  1. 在0x3F000(链接器选项-Ttext=0x3F000)加载并初始化,
  2. 在0处复制自身(镜像)
  3. 使用assembly跳转到镜像重置处理程序()(接近0)
  4. 镜像应用程序开始按预期运行

当达到mirror main()调用的闪存位置(闪存位置0x532)时,问题会出现:

位于那里的指令ldr[pc,#32]用0x3F565(从而调用原始main())加载r3,而不是预期的0x565(以便按预期调用镜像main())。

即使所有包含0x3F的寄存器在ldr指令之前都归零,也会发生这种情况。

调试器报告PC寄存器按预期为0x534,并且符合执行步进的闪存区域。

谁能给我解释一下发生了什么事吗?

提前谢谢你。

该程序是用[-mthumb-nostdlib-nostartfiles-ffreestanding-msingle pic base-mno pic data is text relative-mlong calls-mpoke function name]标志编译的,并与[-Wl,--gc sections-mcpu=cortex-m4-Ttext=0x3f000-nostlib-notartfiles-ffreestanding-Wl,--dead strip-Wl,-,-static-Wl,--entry=Reset_Handler-Wl,--cref-mthumb]标志相链接。链接器脚本定义rom start=0。

生产区域内的感兴趣区域。lss文件包含(省略的行标记为…):

...
void Reset_Handler(void)
{
...
    /* Initialize the relocate segment */
...
    /* Clear the zero segment */
...
    /* Set the vector table base address */

    /* Initialize the C library */
//  __libc_init_array();

    /* Branch to main function */
    main();
   3f532:   4b08        ldr r3, [pc, #32]   ; (3f554 <Reset_Handler+0x5c>)
   3f534:   4798        blx r3
   3f536:   e7fe        b.n 3f536 <Reset_Handler+0x3e>
   3f538:   20000000    .word   0x20000000
   3f53c:   0003f59c    .word   0x0003f59c
   3f540:   20000004    .word   0x20000004
   3f544:   20000004    .word   0x20000004
   3f548:   20000008    .word   0x20000008
   3f54c:   e000ed00    .word   0xe000ed00
   3f550:   0003f000    .word   0x0003f000
   3f554:   0003f565    .word   0x0003f565
   3f558:   6e69616d    .word   0x6e69616d
   3f55c:   00          .byte   0x00
   3f55d:   00          .byte   0x00
   3f55e:   bf00        nop
   3f560:   ff000008    .word   0xff000008

0003f564 <main>:

int main (void)
    {
   3f564:   b510        push    {r4, lr}
...
        asm("bx %0"::"r"(*(unsigned*)0x3F004 - 0x3F000));
   3f580:   4b05        ldr r3, [pc, #20]   ; (3f598 <main+0x34>)
   3f582:   681b        ldr r3, [r3, #0]
   3f584:   f5a3 337c   sub.w   r3, r3, #258048 ; 0x3f000
   3f588:   4718        bx  r3
        }
    return 0;
    }
   3f58a:   2000        movs    r0, #0
   3f58c:   bd10        pop {r4, pc}
   3f58e:   bf00        nop
   3f590:   e0001000    .word   0xe0001000
   3f594:   0003f329    .word   0x0003f329
   3f598:   0003f004    .word   0x0003f004
...

共有1个答案

丁翊歌
2023-03-14

@这并没有回答我的问题。假设pc 32地址应该直接加载到r3,而不是这个地址的内容,我感到困惑。

 类似资料:
  • 问题内容: 前一阵子,在使用Class.getMethod和自动装箱时,我遇到了类似的问题,因此在自己的查找算法中实现它很有意义。但是,真正让我感到困惑的是,以下两种方法也不起作用: String.class实现了Serializable接口,我确实希望它包含在lookup方法中。 我也必须在自己的查找算法中考虑这一点吗? 编辑 :我确实读过Javadoc, 所以让我强调一下问题的第二部分 :如果

  • 我是Python的新手,我对Python处理空对象的方式有点困惑。 考虑这段代码; 我得到了这段代码的以下输出。 我假设由{}初始化的对象是有效对象。为什么Python不那样对待它?为什么要得到diff If条件的diff输出? 在C++中,当我说 如果obj不是NULL,它将进入IF块(不管它是垃圾值还是其他) 但当我翻译成Python时也是一样的。 为什么?我读到Python将{}计算为fal

  • 请注意,NULL字节始终存在,您可以使用检查它。 我知道我可以使用获得类似的结果。我不是在问其他选择,我只是想了解格式字符(如doc所说的“NUL填充字符串”)背后的逻辑。 “NULL”值在哪里涉及到所有这些?

  • 我有以下输入字符串: 这里有各种各样的错误:标题前面有“。”应该是ID后面的分隔符。作者姓名的最后两个字符出现在日期字段中,实际日期丢失。 我怎样才能纠正这些问题?

  • 问题内容: 我有以下代码: 我希望它返回“ 05/20/2012”,但它返回“ 04/20/2012” 这对我来说毫无意义-有人可以帮助我了解发生了什么以及如何获得正确的响应吗? 感谢您的关注! 问题答案: 从零开始。如和 尝试

  • 问题内容: 我正在尝试在我的工作原型中实现EHCache,在该原型中我有一个 javax.persistence.Entity,它 表示数据库中的表(MySQL,mysql-connector-java-5.1.20.jar),该XML作为XML提供给消费者。 我面临的问题是, 即使EHCache将查询结果存储在memory上 ,Hibernate似乎仍从数据库中检索数据。 我正在使用EHCach