【问题标题】:ARM, help LDR instructionARM,帮助 LDR 指令
【发布时间】:2017-08-01 16:52:50
【问题描述】:

我正在学习 ARM 测试,我有这个代码

    AREA datos, DATA, READWRITE
long    EQU 7*4   
serie   DCD 1, 2, 4, 6, 8, 7, 9
resul   DCB 0
    AREA prog, CODE, READONLY

    ENTRY
    mov r0, #0
    eor r1, r1, r1  ;result variable

    ldr r2, =serie **This one**
buc ldr r3, [r2, r0]
    add r1, r1, r3
    add r0, r0, #4
    cmp r0, #long
    bne buc

    ldr r2, =resul **This one**
    str r1, [r2]

fin b fin

    END 

而且我正在用Keil调试,我的问题是我对标注的指令不是很了解。

     8:     mov r0, #0 
0x40000000  E3A00000  MOV       R0,#0x00000000
     9:     eor r1, r1, r1  ;result variable 
    10:      
0x40000004  E0211001  EOR       R1,R1,R1
    11:     ldr r2, =serie 
0x40000008  E59F201C  LDR       R2,[PC,#0x001C]
    12: buc     ldr r3, [r2, r0] 
0x4000000C  E7923000  LDR       R3,[R2,R0]
    13:     add r1, r1, r3 
0x40000010  E0811003  ADD       R1,R1,R3
    14:     add r0, r0, #4 
0x40000014  E2800004  ADD       R0,R0,#0x00000004
    15:     cmp r0, #long 
0x40000018  E350001C  CMP       R0,#0x0000001C
    16:     bne buc 
    17:      
0x4000001C  1AFFFFFA  BNE       0x4000000C
    18:     ldr r2, =resul 
0x40000020  E59F2008  LDR       R2,[PC,#0x0008]
    19:     str r1, [r2] 
    20:         
0x40000024  E5821000  STR       R1,[R2]
    21: fin     b fin 

如果我用 Keil 拆开它,我就有这个,那么我知道 LDR R2, =serieLDR R2,[PC, #offset] 相同,但#offset 的值放在文字池中?我不知道为什么值是0x001C

PD:对不起我的英语,我知道它不是很好。

【问题讨论】:

  • 这个问题已经被问过很多次了……
  • 是的,我一直在寻找很多线程,但仍然不明白我如何知道serie 的地址手动操作。不知道如何确定#offset的值,在那种情况下是#0x001C
  • 不能,汇编器/链接器可以。该值被放置在文字池中(您不知道确切的位置),并且该地址的偏移量被编码在指令中。
  • 汇编语言是由汇编器定义的,所以keil arm汇编语言和gnu、arm等不应该完全相同,只有机器码要一致。因此,每个汇编器和汇编器的每个版本如何确定为这些项目分配空间的位置是特定于该汇编器的。一些汇编程序有指令,您可以使用这些指令来鼓励或指导它选择一个区域,有人会假设有些没有。同样,这种伪指令甚至可能不被所有 arm 汇编器支持...
  • 指令是伪代码,简单地说请将此标签的地址加载到此寄存器中并使其正常工作。由于这部分是链接时间过程,并且指令长度是固定的,因此您无法执行所需的任何值的 mov 立即数,因此将其编码为 pc 相对负载,现在汇编器必须找到一个空间,这就是汇编器具体的。

标签: assembly arm keil


【解决方案1】:

这是您程序的对象转储(修改为在 Raspberry Pi 上运行)。

Disassembly of section .text:

00000000 <main>:
   0:       e3a00000        mov     r0, #0
   4:       e0211001        eor     r1, r1, r1
   8:       e59f201c        ldr     r2, [pc, #28]   ; 2c <buc+0x20>

0000000c <buc>:
   c:       e7923000        ldr     r3, [r2, r0]
  10:       e0811003        add     r1, r1, r3
  14:       e2800004        add     r0, r0, #4
  18:       e350001c        cmp     r0, #28
  1c:       1afffffa        bne     c <buc>
  20:       e59f2008        ldr     r2, [pc, #8]    ; 30 <buc+0x24>
  24:       e5821000        str     r1, [r2]
  28:       e12fff1e        bx      lr
  2c:       00000000        andeq   r0, r0, r0
  30:       0000001c        andeq   r0, r0, ip, lsl r0

Disassembly of section .data:

00000000 <serie>:
   0:       00000001        andeq   r0, r0, r1
   4:       00000002        andeq   r0, r0, r2
   8:       00000004        andeq   r0, r0, r4
   c:       00000006        andeq   r0, r0, r6
  10:       00000008        andeq   r0, r0, r8
  14:       00000007        andeq   r0, r0, r7
  18:       00000009        andeq   r0, r0, r9

0000001c <resul>:
  1c:       00000000        andeq   r0, r0, r0

Disassembly of section .ARM.attributes:

00000000 <.ARM.attributes>:
   0:       00001541        andeq   r1, r0, r1, asr #10
   4:       61656100        cmnvs   r5, r0, lsl #2
   8:       01006962        tsteq   r0, r2, ror #18
   c:       0000000b        andeq   r0, r0, fp
  10:       01080206        tsteq   r8, r6, lsl #4
  14:       Address 0x00000014 is out of bounds.

程序有一个 .text 部分,数据(DCD、DCB)有一个 .data 部分。在程序结束时,有两个单词将包含定义为“serie”和“resul”的.data 部分的地址。 ldr r2, [pc, #28] 中这些地址的地址是 pc reg + dec 28 = hex 2c 的值。 ldr r2, [pc, #8] 也是如此,pc reg + dec 8 = hex 30 中的值。

【讨论】:

  • 是的,谢谢你的解释,现在我明白了!
猜你喜欢
  • 2017-04-06
  • 2014-07-29
  • 1970-01-01
  • 1970-01-01
  • 2016-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多