我使用的是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 . 它是在链接期间完成的吗?
1 回答
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-relative编码而不是register-absolute编码作为分支指令 .