-2

我正在尝试将寄存器指向的数据加载ARM(R0)另一个寄存器(R1)

所以,我正在使用LDR R1,[R0]. 但是R0LDR R0,=0x0804c000

我得到一个分段错误。

注册信息

(gdb) info registers
r0             0x804c000        134529024
r1             0x1      1
r2             0x804c044        134529092
r3             0x1      1
r4             0x804c088        134529160
r5             0x0      0
r6             0x804c0cc        134529228
r7             0xbe9746c4       3197585092
r8             0x804c110        134529296
r9             0x8fb9   36793
r10            0x804c154        134529364
r11            0x0      0
r12            0x0      0
sp             0xbe9746c4       0xbe9746c4
lr             0x8939   35129
pc             0x89f0   0x89f0 <test46+48>
cpsr           0x60000030       1610612784

Disassembler:

(gdb) disassemble
Dump of assembler code for function test46:
   0x000089c0 <+0>:     push    {r7}
   0x000089c2 <+2>:     add     r7, sp, #0
   0x000089c4 <+4>:     ldr     r0, [pc, #60]   ; (0x8a04)
   0x000089c6 <+6>:     ldr     r2, [pc, #64]   ; (0x8a08)
   0x000089c8 <+8>:     ldr     r4, [pc, #64]   ; (0x8a0c)
   0x000089ca <+10>:    ldr     r6, [pc, #68]   ; (0x8a10)
   0x000089cc <+12>:    ldr.w   r8, [pc, #68]   ; 0x8a14
   0x000089d0 <+16>:    ldr.w   r10, [pc, #68]  ; 0x8a18
   0x000089d4 <+20>:    nop
   0x000089d6 <+22>:    nop
   0x000089d8 <+24>:    nop
   0x000089da <+26>:    nop
   0x000089dc <+28>:    nop
   0x000089de <+30>:    nop
   0x000089e0 <+32>:    nop
   0x000089e2 <+34>:    nop
   0x000089e4 <+36>:    nop
   0x000089e6 <+38>:    nop
   0x000089e8 <+40>:    nop
   0x000089ea <+42>:    nop
   0x000089ec <+44>:    nop
   0x000089ee <+46>:    nop
=> 0x000089f0 <+48>:    ldr     r1, [r0, #0]
   0x000089f2 <+50>:    ldr     r3, [r2, #0]
   0x000089f4 <+52>:    ldr     r5, [r4, #0]
   0x000089f6 <+54>:    ldr     r7, [r6, #0]
   0x000089f8 <+56>:    ldr.w   r9, [r8]
   0x000089fc <+60>:    ldr.w   r11, [r10]
   0x00008a00 <+64>:    b.n     0x89f0 <test46+48>
End of assembler dump.

LDR指令不能这样使用吗?我可以使用以下命令将数据从 R0 移动到 R1 而不会出现任何问题MOV R1, R0

这是我的compilation flags:

gcc -std=c99 -mthumb -march=armv7 -mthumb-interwork -static -ffunction-sections
4

2 回答 2

3

从您在另一个回复中的评论来看,我认为您对缓存如何工作的看法是错误的。我不相信支持缓存的内存可以直接访问,并且查看数据表,我会说我是正确的。用于缓存的 RAM 通常非常快,如果您可以避免尝试访问主存储器时涉及的典型地址周期,则它的效果最好。此外,内核不允许直接访问 L1 的内容,因为它可能会给系统带来很多麻烦,即使您只能读取它而不写入它——想想另一个可以检查 L1 的用户空间进程。内容并可能从中提取密码或其他敏感数据。通常,您通过系统协处理器执行影响缓存的操作,您需要在Cortex-A15 的 ARM 架构手册

即使您可以直接访问它,您也忘记了其中涉及 MMU 和 Linux。Linux 设置的虚拟内存空间看起来与处理器的物理空间大不相同。在这种情况下,0x0804c000未映射,因此您会遇到分段错误。

我怀疑这个问题只是一个编码错误。FWIW,您提供的代码段看起来是正确的,只是您正在访问无效的内存位置。

于 2013-07-04T10:17:36.470 回答
1

该指令 ,从LDR R1, [R0]获取一个地址R0,并将一个 32 位整数从该地址加载到R1

如果地址中的地址R0不是有效地址,则会出现分段错误。您应该在该指令上设置一个断点并查看当时的内容R0

(gdb) break *0x000089f0
(gdb) run
<program hits breakpoint>
(gdb) info registers
<read value from R0>

然后,您可以尝试使用调试器从该地址加载,看看它是否在那里工作:

(gdb) x/x $r0

如果调试器可以读取地址,那么问题就不是你想象的那样;形成另一个假设并对其进行检验。

于 2013-07-04T09:15:01.783 回答