组装中的重新定位



我有一个用汇编编写的裸机ARM的启动代码,我试图了解它是如何工作的。二进制文件写在一些外部闪存中,并在启动时在RAM中复制自身的一部分。尽管我读了这个维基百科条目,但我仍然没有完全理解在这种情况下搬迁的概念。RAM被映射到一个低地址窗口,而闪存被映射到一个高地址窗口。有人能向我解释一下为什么我们在这里测试链接寄存器的值吗?

/* Test if we are running from an address, we are not linked at */
       bl check_position
 check_position:
        mov     r0, lr                  
        ldr     r1, =check_position
        cmp     r0, r1                  /* ; don't relocate during debug */
        beq     relocated_entry 

我的猜测是应用程序从ram运行,当调试应用程序时,作者可能使用某种引导加载程序或jtag将测试应用程序直接加载到ram中,因此没有理由复制和运行(这可能导致崩溃)。

这样做的另一个原因是为了避免无限循环。例如,如果你想从闪存启动(通常必须),但从ram执行,那么最简单的方法就是将整个闪存或整个闪存块复制到ram,然后分支到ram的开始。当你这样做意味着你击中"复制应用程序到ram和分支"循环再次,以避免它的第二次(这可能会使你崩溃),你有某种我从flash运行这个循环或不测试。

谁能向我解释一下为什么我们在这里测试链接寄存器的值?

bl check_position将把PC+4的值放在链路寄存器中,并将控制转移到check_position,也相对于PC。bl at ARM到目前为止,一切都是相对于PC的。

ldr r1,=check_position字面值池获取一个值。Ref1实际代码看起来像,

  ldr r1,[pc, #offset]
...
  offset:
    .long check_position   # absolute address from assemble/link. 

因此R0包含PC相对版本,R1包含绝对汇编版本。在这里,它们是比较的。你也可以使用算术来计算差值,然后在非零的情况下将分支到;或者可能将代码复制到它的绝对目的地。Ref2如果代码链接的地址上运行,则R0R1相同。这是blpseudo code

 mov lr,pc               ; pc is actually two instruction ahead.
 add pc,pc,#branch_offset-8

关键是BL基于PC做所有事情,包括lr的更新。而不是使用这个技巧,我们可以使用mov R0,PC,除了PC在前面8个字节。另一种选择是使用adr R0,check_position,它会让汇编程序为我们做所有的地址计算。

 /* Test if we are running from an address, we are not linked at */
 check_position:
    adr    r0, check_position
    ldr    r1, =check_position
    cmp    r0, r1                  /* ; don't relocate during debug */
    beq    relocated_entry 

ARMv6版本可能是这样的,

 /* Test if we are running from an address, we are not linked at */
 check_position:
    adr    r0, check_position
    movw   r1, #:lower16:check_position
    movt   r1, #:upper16:check_position
    cmp    r0, r1                  /* ; don't relocate during debug */
    beq    relocated_entry 

在这两种情况下,代码都更直接,少了一个单词,并且不会覆盖lr寄存器,因此它可以用于其他目的。

Ref1:参见gnu汇编手册中的Arm操作码和.ltorg
Ref2:这正是Linux head.S为ARM所做的。

编辑:我检查了ARM和PC显然是当前指令+8,这表明为什么代码是这样的。我认为adr版本更直接和可读,但adr伪op不经常使用,所以人们可能不熟悉它。

相关内容

  • 没有找到相关文章

最新更新