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

Gcc ldr的意外行为[pc,#值],gcc,assembly,arm,Gcc,Assembly,Arm,我使用GNU gcc(4.8.1429)为ARM(ATsam4LC4B:cortexM4内核,256K闪存)构建了一个简单的应用程序,该应用程序: 加载0x3F000(链接器选项-Ttext=0x3F000)并初始化 在0处复制自身(镜像) 使用程序集跳转到镜像重置_处理程序()(接近0) 镜像应用程序开始按预期运行 当达到mirror main()调用的闪存位置(闪存位置0x532)时,问题会出现: 位于那里的指令ldr[pc,#32]加载带有0x3F565的r3(从而调用原始main()),

我使用GNU gcc(4.8.1429)为ARM(ATsam4LC4B:cortexM4内核,256K闪存)构建了一个简单的应用程序,该应用程序:

  • 加载0x3F000(链接器选项-Ttext=0x3F000)并初始化
  • 在0处复制自身(镜像)
  • 使用程序集跳转到镜像重置_处理程序()(接近0)
  • 镜像应用程序开始按预期运行
  • 当达到mirror main()调用的闪存位置(闪存位置0x532)时,问题会出现:

    位于那里的指令ldr[pc,#32]加载带有0x3F565的r3(从而调用原始main()),而不是预期的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-nostartfiles-ffreserving-Wl,-dead strip-Wl,-static-Wl,--entry=Reset_Handler-Wl,--cref-mthumb]标志。链接器脚本定义rom start=0

    生成的.lss文件中的感兴趣区域包含(省略的行标记为…):

    。。。
    无效重置\u处理程序(无效)
    {
    ...
    /*初始化重定位段*/
    ...
    /*清除零段*/
    ...
    /*设置向量表的基址*/
    /*初始化C库*/
    //__libc_init_数组();
    /*分支到主功能*/
    main();
    3f532:4b08 ldr r3[pc,#32];(3f554)
    3f534:4798 blx r3
    3f536:e7fe b.n 3f536
    3f538:20000000.字0x20000000
    3f53c:0003f59c.字0x0003f59c
    3f540:2000004.字0x2000004
    3f544:2000004.字0x2000004
    3f548:2000008.字0x2000008
    3f54c:e000ed00。字0xe000ed00
    3f550:0003f000。字0x0003f000
    3f554:0003f565.字0x0003f565
    3f558:6e69616d。字0x6e69616d
    3f55c:00。字节0x00
    3f55d:00。字节0x00
    3f55e:bf00 nop
    3f560:ff000008.字0xff000008
    0003f564:
    内部主(空)
    {
    3f564:b510推送{r4,lr}
    ...
    asm(“bx%0”::“r”(*(无符号*)0x3F004-0x3F000));
    3f580:4b05 ldr r3[pc,#20];(3f598)
    3f582:681b ldr r3[r3,#0]
    3f584:f5a3 337c sub.w r3,r3,#258048;0x3f000
    3f588:4718 bx r3
    }
    返回0;
    }
    3f58a:2000 MOV r0,#0
    3f58c:bd10 pop{r4,pc}
    3f58e:bf00 nop
    3f590:e0001000.字0xe0001000
    3f594:0003f329.字0x0003f329
    3f598:0003f004.字0x0003f004
    ...
    
    @这并不能回答我的问题。
    假设pc+32地址应该直接加载到r3,而不是这个地址的内容,我感到困惑。

    那么,地址0x3f554/0x554实际存储了什么值?这就是您加载到r3的内容,但您没有显示它。如果它是在链接时计算的符号地址,那么显然您必须将其作为o部分进行修复f.0x0003f565存储在地址0x3f554/0x554。谢谢。可能会有类似问题。
    ...
    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
    ...