我使用的是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。它是在链接期间完成的吗?
答案 0 :(得分:2)
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-relative编码而不是register-absolute编码作为分支指令。