LDR - 文字池 - ARM [英] LDR - Literal pool - 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 address
0x0804c088. 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屋!