仔细观察

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

在使用Keil(版本为uVision V5.38.0.0)编译工程的时候碰到了一个报错:

Error: L6286E: Relocation #REL:0 in cm0dasm.o(.text) with respect to __main. Value(0xfffffffa) out of range (0 - 0xff) for (R_ARM_THM_PC8)

启动汇编代码如下所示

Reset_Handler PROC
    GLOBAL Reset_Handler
    ENTRY
    IMPORT __main
    LDR R0,__main
    BX R0
    ENDP

在网上搜了一些解答,像是CSDN有人说将编译优化等价修改为-O1,这肯定是在胡说八道。实际上ARM社区已经对此问题作出了解答

此问题产生的原因是汇编指令尝试访问超出指令范围的符号,至于修改的方式,其实比较简单,只需要将第五行做如下改动

    LDR R0,=__main

之前调试的时候我就发现,这里写的汇编代码的LDR其实不是汇编指令,而是伪代码。它的使用方式有两种

LDR {{<cond>}} {.W} {<Rt>}, ={<expr>}
LDR {{<cond>}} {.W} {<Rt>}, ={<label_expr>}

其中<expr>是数值表达式,<label_expr>PC或者外部地址加减一个数值。这一点从汇编器的结果就可以发现,例如上面程序汇编的结果为

0x00000094 4800 LDR r0,[pc,#0] ; @0x00000098

所以说一开始的写法其实是错误的,要跳转到符号地址应该用LDR伪指令说明里提供的方法。
除此之外补充一点,因为LDR其实是伪指令,所以汇编出的结果不一定是LDR指令,也可能是MOV指令。

posted on 2024-04-16 14:42  注意看  阅读(60)  评论(0编辑  收藏  举报