2

ARM で LDR 命令を使用して即値をロードする方法を知っています。

例えば:

LDR R0,=0x0804c088 この命令は、値 ( 0x0804c088) をレジスタにロードしますr0。アドレスにアクセスしようとすると、 using に格納されていx/x $r0ますgdb。メッセージが表示されます: Cannot access memory at address0x0804c088 。しかし、それはアドレスではなく、そのレジスタに格納されている値であり、アドレスは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
4

2 に答える 2

1

実行時にリテラル プールの実際のアドレスを知りたい場合は、これを試してください。

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

次に、実行時にリテラル プールのアドレスを含む r12 を読み取ることができます。

ltorg は、リテラル プールが配置される場所を強制するディレクティブです。短いコードの場合、それらはコードの最後に自動的に付加されますが、コードが 4KB を超えると、PC 相対オフセットが 4096 を超えるため、アセンブリ時に LDR 疑似命令によってエラーが発生します。許容範囲。

これを回避するには、命令として誤って解釈されない安全な場所に ltorg をコードの中間に置くことができます。(たとえば、絶対分岐の後)

于 2013-07-17T11:34:40.717 に答える