LDR - 文字池 - ARM [英] LDR - Literal pool - ARM

查看:29
本文介绍了LDR - 文字池 - ARM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何在 ARM 中使用 LDR 指令加载立即数.

I know how to load an immediate value using the LDR instruction in ARM.

例如:

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

LDR R0,=0x0804c088 This instruction loads the value (0x0804c088) to the register r0. When I try to access the address it is stored in using x/x $r0 using gdb. I get the message: Cannot access memory at address0x0804c088. But that is not the address, it is the value stored in that register and the address is a PC relative address which is stored in the literal pool.

我在那里做错了什么?我理解错了吗?

What is the mistake that I doing there? did I understand something wrong there?

另外,我应该如何设置文字池,你能举个例子吗?

Moreover, How should I set the literal pool, can you give me an example please?

@Carl Norum:这是代码.

@Carl Norum: Here is the code.

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

来自 gdb 的 O/p

O/p from gdb

(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

推荐答案

gdb x 命令具有固有的解引用操作.如果要打印 r0 中的值,只需使用 p:

The gdb x command has an inherent dereferencing operation. If you want to print the value in r0, just use p:

p/x $r0

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

The form of LDR you're using isn't a real instruction - it's an assembler macro-instruction that gets converted into a pc-relative ldr instruction and a literal value someplace in memory (probably close to the location you're using it). If you want to find the address of the constant in the literal pool, you need to look at the output binary. Your source assembly code doesn't contain it.

例如,让我们以这个简单的示例程序为例:

For example, let's take this simple example program:

    .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 处.

You can see the literal is right there at offset 4.

您无需执行任何操作即可设置文字池".汇编程序将为您设置任何必要的文字.

You don't need to do anything to "set up the literal pool". Any necessary literals will be set up for you by the assembler.

这篇关于LDR - 文字池 - ARM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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