如何在arm asm上写PC相对地址? [英] Howto write PC relative adressing on arm asm?

查看:26
本文介绍了如何在arm asm上写PC相对地址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 GNU AS 作为汇编程序,我正在尝试编写一个位置无关的二进制文件,但在编写外部符号的 PC 相对地址时遇到了一些问题.通常加载相对地址

I'm using GNU AS as assembler and I'm trying to write a position independent binary and I have some problems writing the PC relative address of an external symbols. Normaly a relative address is loaded with

adr r0, symbol

但这仅适用于在程序集文件的同一部分中定义的符号.加载符号的另一种方法是

but that only works for symbols defined in the same section in the assembly file. The other method to load a symbol is

ldr r0, =symbol

它将符号的绝对地址存储在一个常量中,并从那里加载 pc 相对地址.所以你得到这样的代码:

which stores the absolute address of the symbol in a constant and loads it pc relative from there. So you get code like this:

  48:   e59f0008        ldr     r0, [pc, #8]    ; 58 <text+0xc>
  ...
  58:   00000008        .word   0x00200018
                        58: R_ARM_ABS32 symbol

但我需要的是 R_ARM_REL32 链接器参考.

But what I need is a R_ARM_REL32 linker reference.

我想出的是这个代码:

tmp1:    ldr    r0, [pc, #tmp2 - tmp1 - 8]
         ldr    r0, [pc, r0]
tmp2:    .word  symbol - tmp1

这会产生:

0000003c <tmp1>:
  3c:   e59f0000        ldr     r0, [pc]        ; 44 <tmp2>
  40:   e79f0000        ldr     r0, [pc, r0]

00000044 <tmp2>:
  44:   00000008        .word   0x00000008
                        44: R_ARM_REL32 symbol

我几乎可以把它放到一个宏中,这样它就可以重用于我需要的任何符号.除了我不知道如何告诉汇编器 tmp2 需要转到常量块而不是在代码中间结束.

I can nearly put that into a macro so it is reusesable for whatever symbol I need. Except I don't know how to tell the assembler that tmp2 needs to go to the constants block instead of ending up right there in the middle of the code.

但是在 GNU AS 中不是已经有一些现有的语法或宏吗?

But isn't there already some existing syntax or macro for that in GNU AS?

推荐答案

ARMv8

请注意,在 ARMv8 中,PC 不能再像 ARMv7 那样被视为常规寄存器.

Note that in ARMv8, the PC cannot be treated as a regular register anymore as was the case for ARMv7.

然而,ldr 有一种特殊的 PC 相关编码,称为LDR(文字)",其语法为:

There is however a special PC-relative encoding for ldr called "LDR (literal)" with syntax:

    ldr x0, pc_relative_ldr
    b 1f
pc_relative_ldr:
    .quad 0x123456789ABCDEF0
1:

GitHub 上游.

尝试使用旧的LDR(寄存器)"语法,如下所示:

Trying to do an old "LDR (register)" syntax as in:

ldr x0, [pc]

失败:

64-bit integer or SP register expected at operand 2 -- `ldr x0,[pc]'

出于某种原因,str没有这种与PC相关的编码.我认为你只需要使用 adr + "STR (register)" 如:

For some reason, there is not such PC-relative encoding for str. I think you just have to use adr + "STR (register)" as in:

    adr x1, pc_relative_str
    ldr x0, pc_relative_ldr
    str x0, [x1]
    ldr x0, pc_relative_str
.data
pc_relative_str:
    .quad 0x0000000000000000

GitHub 上游.

其中 adr 将与 PC 相关的地址加载到寄存器中.

where adr loads a PC-relative address into a register.

如果您需要更长的跳转,您可能也对 ADRP 感兴趣,请参阅:ARM汇编中ADRP和ADRL指令的语义是什么?

You might also be interested in ADRP if you need longer jumps, see: What are the semantics of ADRP and ADRL instructions in ARM assembly?

这篇关于如何在arm asm上写PC相对地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆