如何在ARM ASM上编写PC相对地址? [英] Howto write PC relative adressing on arm asm?
问题描述
我正在使用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:
尝试使用旧的"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
其中adr
将PC相对地址加载到寄存器中.
where adr
loads a PC-relative address into a register.
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屋!