linker - ARM DCD 从 RAM 工作和执行

标签 linker embedded arm greenhills

我正在使用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/

相关文章:

iOS-Hierarchy-Viewer 构建失败 : linker command failed with exit code 1

c++ - 即使使用 -lstdc++fs 也无法链接 std::filesystem

linux - 如何在 linux 内核模块中添加周期性定时器回调

arm - GNU ARM 汇编器上的意外警告

c - Hello World ,裸机 Beagleboard

C++ 链接错误 LNK2019

macos - xcode4:链接器错误:找不到选项的目录

c - 在 C 中匹配(几个)字符串的最有效方法?

c - 如何在嵌入式系统中为某个任务禁用/延迟看门狗定时器

sql-server - 使用unixODBC和FreeTDS问题用arm linux板连接MSSQL数据库