LDR - 文字池 - ARM

时间:2013-07-16 15:02:03

标签: c gcc gdb arm

我知道如何使用ARM中的LDR指令加载立即值。

例如:

LDR R0,=0x0804c088 该指令将值(0x0804c088)加载到寄存器r0。当我尝试访问该地址时,使用x/x $r0使用gdb存储该地址。我收到消息:Cannot access memory at address 0x0804c088 。但这不是地址,而是存储在该寄存器中的值,地址是PC相对地址,存储在文字池中。

我在那里做错了什么?我明白了吗?

此外,我应该如何设置文字池,你能给我一个例子吗?

@Carl Norum:这是代码。

__asm__("LDR R0,=0x0804c088");
__asm__("LDR R1,[PC, #34];");

来自gdb的O / p

(gdb) info registers
r0             0x804c088        134529160
r1             0xf2c00300       4072669952
r2             0x0      0
r3             0x1      1
r4             0x8961   35169
r5             0x0      0
r6             0x0      0
r7             0xbe8f4b74       3197062004
r8             0x0      0
r9             0xef99   61337
r10            0xf00d   61453
r11            0x0      0
r12            0x0      0
sp             0xbe8f4b74       0xbe8f4b74
lr             0x89a7   35239
pc             0x8a62   0x8a62 <test46+34>
cpsr           0x60000030       1610612784
(gdb) x/x $r0
0x804c088:      Cannot access memory at address 0x804c088
(gdb) p/x$r0
$1 = 0x804c088
(gdb) p/x $r1
$2 = 0xf2c00300
(gdb) x/x $r1
0xf2c00300:     Cannot access memory at address 0xf2c00300
(gdb) x/x $r15
0x8a62 <test46+34>:     0x1022f8df

2 个答案:

答案 0 :(得分:1)

gdb x命令具有固有的解除引用操作。如果您想在r0中打印该值,请使用p

p/x $r0

您使用的LDR形式不是真正的指令 - 它是一个汇编程序宏指令,可以转换为与pc相关的ldr指令内存中的某个字面值(可能靠近您正在使用它的位置)。如果要在文字池中查找常量的地址,则需要查看输出二进制文件。您的源汇编代码不包含它。

例如,让我们来看看这个简单的示例程序:

    .globl f
f:
    ldr r0,=0x12345678

然后构建和反汇编它:

$ arm-none-eabi-clang -c example.s 
$ arm-none-eabi-objdump -d example.o 

example.o:     file format elf32-littlearm


Disassembly of section .text:

00000000 <f>:
   0:   e51f0004    ldr r0, [pc, #-4]   ; 4 <f+0x4>
   4:   12345678    .word   0x12345678

您可以在偏移4找到文字。

您不需要做任何事情来设置文字池&#34;。汇编程序将为您设置任何必要的文字。

答案 1 :(得分:1)

如果您想在运行时知道文字池的实际地址,请尝试以下方法:

adr r12, literal_pool_label
.
.
. // your code here
.
.
.
literal_pool_label:
.ltorg

然后你可以在运行时读取包含文字池地址的r12。

ltorg是强制放置文字池的指令。对于短代码,它们会自动附加到代码的末尾,但如果代码大于4KB,则LDR伪指令将在汇编时导致错误,因为pc相对偏移量大于4096,因此允许范围。

为避免这种情况,您可以将ltorg放在代码中间,以免被误解为指令。 (例如在绝对分支之后)