我正在使用MBD9F126(ARM Cortex R4)微 Controller 。我将代码闪存到 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 。是在链接过程中完成的吗?
最佳答案
bl Start_PreInit
指令之所以有效,是因为分支目标在指令操作码中编码为相对于当前 PC
的偏移量 (r15
) 。由于 r15 指向 ROM,因此目标是另一个 ROM 地址。
blx r12
指令分支到加载到 r12
寄存器中的绝对地址。
当您将 ADDRESS_START_PREINIT
的内容加载到寄存器中时,您得到的是链接器为 Start_PreInit
地址计算的绝对地址。显然链接器已将其固定为 RAM 绝对地址。
您也许可以通过链接器配置或在加载 RAM 地址时对 r12
执行一些转换来解决该问题(例如 (r12 - RAM_START) + ROM_START
) 分支之前。或者,如果目标地址在范围内,则对分支指令使用 PC 相对编码而不是寄存器绝对编码。
关于linker - ARM DCD 从 RAM 工作和执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12275354/