2

我正在使用 MBD9F126(ARM Cortex R4)微控制器。在那里我将代码闪存到 ROM 中,然后在 RAM 复制后从 RAM 执行代码。我正在使用 Green hills 编译器。在 RAM 复制之前,我正在执行基本的板初始化代码。

    LDR r12, ADDRESS_START_PREINIT
    BLX r12
    ADDRESS_START_PREINIT:DCD Start_PreInit

Start_PreInit 是板卡初始化函数。如果我在 BLX 之后这样给出,它将分支到 RAM 位置。由于 RAM 复制尚未完成,因此它会进入未知区域。

而不是这个如果我在写

    bl Start_PreInit

它工作正常,将进入代码的 ROM 位置。我不明白为什么编译器会有这样的行为?
还有 ADDRESS_START_PREINIT:DCD Start_PreInit 。它是在链接期间完成的吗?

4

1 回答 1

2

bl Start_PreInit指令有效,因为分支目标在指令操作码中编码为相对于当前PC( r15) 的偏移量。由于r15是指向ROM,所以目标是另一个ROM地址。

blx r12指令跳转到加载到r12寄存器中的绝对地址。

当您将 的内容加载ADDRESS_START_PREINIT到寄存器中时,您得到的是链接器为该地址计算的绝对Start_PreInit地址。显然,链接器已将其修复为 RAM 绝对地址。

您可能能够通过链接器配置或通过在分支之前r12使用 RAM 地址(类似于 )加载它时执行一些转换来解决问题。(r12 - RAM_START) + ROM_START或者,如果目标地址在范围内,则对分支指令使用 pc 相对编码而不是寄存器绝对编码。

于 2012-09-05T06:47:10.467 回答