当前位置:  技术问答>linux和unix

ARM LDR与ADRL区别

    来源: 互联网  发布时间:2017-05-25

    本文导语:  汇编源文件如下: .global _start _start: ldr r0, =0x53000000 mov r1, #0x0 str r1, [r0] adrl r0, mem_config mov r1, #0x48000000 add r3, r1, #52 copy1: ldr r2, [r0], #4 str r2, [r1], #4 cmp r1, r3 bne copy1 mov r0, #0x0 mov r1, #0x30000000...

汇编源文件如下:
.global _start
_start:
ldr r0, =0x53000000
mov r1, #0x0
str r1, [r0]

adrl r0, mem_config
mov r1, #0x48000000
add r3, r1, #52
copy1:
ldr r2, [r0], #4
str r2, [r1], #4
cmp r1, r3
bne copy1

mov r0, #0x0
mov r1, #0x30000000
add r3, r1, #4*1024
copy2:
ldr r2, [r0], #4
str r2, [r1], #4
cmp r1, r3
bne copy2

ldr pc, =sdram
sdram:
ldr sp, =0x34000000
bl main
loop:
b loop

.align 4
mem_config:
.long 0x22011110
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00018005
.long 0x00018005
.long 0x008c07a3
.long 0x000000b1
.long 0x00000030
.long 0x00000030
链接条件如下:
arm-linux-ld -Ttext 0x30000000 boot.o main.o -o led_elf
程序是基于S3c2440的,首先关闭看门狗,然后初始化内存控制器,再将片内RAM的4KB内容复制到SDRAM中,
最后让程序跳到SDRAM中运行,在main函数中点亮LED。
为什么我将adrl r0, mem_config这条指令换成ldr r0, =mem_config,程序就不能正常运行呢?
还有,不是说b 跳转指令与位置无关吗?
为什么bne copy1这条指令反汇编后变为30000028: 1afffffb  bne 3000001c 呢?
这明显是与链接地址0x30000000有关,如果与位置无关,应该是基于的PC的偏移才对啊。
这两个问题困扰我很久了,求大侠相助!!!
下面是代码使用adrl r0, mem_config这条指令的反汇编:
30000000 :
30000000: e3a00453  mov r0, #1392508928 ; 0x53000000
30000004: e3a01000  mov r1, #0 ; 0x0
30000008: e5801000  str r1, [r0]
3000000c: e28f004c  add r0, pc, #76 ; 0x4c
30000010: e1a00000  nop (mov r0,r0)
30000014: e3a01312  mov r1, #1207959552 ; 0x48000000
30000018: e2813034  add r3, r1, #52 ; 0x34

3000001c :
3000001c: e4902004  ldr r2, [r0], #4
30000020: e4812004  str r2, [r1], #4
30000024: e1510003  cmp r1, r3
30000028: 1afffffb  bne 3000001c 
3000002c: e3a00000  mov r0, #0 ; 0x0
30000030: e3a01203  mov r1, #805306368 ; 0x30000000
30000034: e2813a01  add r3, r1, #4096 ; 0x1000

30000038 :
30000038: e4902004  ldr r2, [r0], #4
3000003c: e4812004  str r2, [r1], #4
30000040: e1510003  cmp r1, r3
30000044: 1afffffb  bne 30000038 
30000048: e59ff044  ldr pc, [pc, #68] ; 30000094 

3000004c :
3000004c: e3a0d30d  mov sp, #872415232 ; 0x34000000
30000050: eb000012  bl 300000a0 

30000054 :
30000054: eafffffe  b 30000054 
30000058: e1a00000  nop (mov r0,r0)
3000005c: e1a00000  nop (mov r0,r0)

30000060 :
30000060: 22011110  .word 0x22011110
30000064: 00000700  .word 0x00000700
30000068: 00000700  .word 0x00000700
3000006c: 00000700  .word 0x00000700
30000070: 00000700  .word 0x00000700
30000074: 00000700  .word 0x00000700
30000078: 00000700  .word 0x00000700
3000007c: 00018005  .word 0x00018005
30000080: 00018005  .word 0x00018005
30000084: 008c07a3  .word 0x008c07a3
30000088: 000000b1  .word 0x000000b1
3000008c: 00000030  .word 0x00000030
30000090: 00000030  .word 0x00000030
30000094: 3000004c  .word 0x3000004c
30000098: e1a00000  .word 0xe1a00000
3000009c: e1a00000  .word 0xe1a00000

300000a0 :
300000a0: e52db004  push {fp} ; (str fp, [sp, #-4]!)
300000a4: e28db000  add fp, sp, #0 ; 0x0
300000a8: e3a03456  mov r3, #1442840576 ; 0x56000000
300000ac: e2833010  add r3, r3, #16 ; 0x10
300000b0: e3a02b55  mov r2, #87040 ; 0x15400
300000b4: e5832000  str r2, [r3]
300000b8: e3a03456  mov r3, #1442840576 ; 0x56000000
300000bc: e2833014  add r3, r3, #20 ; 0x14
300000c0: e3a02d05  mov r2, #320 ; 0x140
300000c4: e5832000  str r2, [r3]
300000c8: e3a03000  mov r3, #0 ; 0x0
300000cc: e1a00003  mov r0, r3
300000d0: e28bd000  add sp, fp, #0 ; 0x0
300000d4: e8bd0800  pop {fp}
300000d8: e12fff1e  bx lr

下面是使用ldr r0, =mem_config的反汇编:
30000000 :
30000000: e3a00453  mov r0, #1392508928 ; 0x53000000
30000004: e3a01000  mov r1, #0 ; 0x0
30000008: e5801000  str r1, [r0]
3000000c: e59f0080  ldr r0, [pc, #128] ; 30000094 
30000010: e3a01312  mov r1, #1207959552 ; 0x48000000
30000014: e2813034  add r3, r1, #52 ; 0x34

30000018 :
30000018: e4902004  ldr r2, [r0], #4
3000001c: e4812004  str r2, [r1], #4
30000020: e1510003  cmp r1, r3
30000024: 1afffffb  bne 30000018 
30000028: e3a00000  mov r0, #0 ; 0x0
3000002c: e3a01203  mov r1, #805306368 ; 0x30000000
30000030: e2813a01  add r3, r1, #4096 ; 0x1000

30000034 :
30000034: e4902004  ldr r2, [r0], #4
30000038: e4812004  str r2, [r1], #4
3000003c: e1510003  cmp r1, r3
30000040: 1afffffb  bne 30000034 
30000044: e59ff04c  ldr pc, [pc, #76] ; 30000098 

30000048 :
30000048: e3a0d30d  mov sp, #872415232 ; 0x34000000
3000004c: eb000013  bl 300000a0 

30000050 :
30000050: eafffffe  b 30000050 
30000054: e1a00000  nop (mov r0,r0)
30000058: e1a00000  nop (mov r0,r0)
3000005c: e1a00000  nop (mov r0,r0)

30000060 :
30000060: 22011110  .word 0x22011110
30000064: 00000700  .word 0x00000700
30000068: 00000700  .word 0x00000700
3000006c: 00000700  .word 0x00000700
30000070: 00000700  .word 0x00000700
30000074: 00000700  .word 0x00000700
30000078: 00000700  .word 0x00000700
3000007c: 00018005  .word 0x00018005
30000080: 00018005  .word 0x00018005
30000084: 008c07a3  .word 0x008c07a3
30000088: 000000b1  .word 0x000000b1
3000008c: 00000030  .word 0x00000030
30000090: 00000030  .word 0x00000030
30000094: 30000060  .word 0x30000060
30000098: 30000048  .word 0x30000048
3000009c: e1a00000  .word 0xe1a00000

300000a0 :
300000a0: e52db004  push {fp} ; (str fp, [sp, #-4]!)
300000a4: e28db000  add fp, sp, #0 ; 0x0
300000a8: e3a03456  mov r3, #1442840576 ; 0x56000000
300000ac: e2833010  add r3, r3, #16 ; 0x10
300000b0: e3a02b55  mov r2, #87040 ; 0x15400
300000b4: e5832000  str r2, [r3]
300000b8: e3a03456  mov r3, #1442840576 ; 0x56000000
300000bc: e2833014  add r3, r3, #20 ; 0x14
300000c0: e3a02d05  mov r2, #320 ; 0x140
300000c4: e5832000  str r2, [r3]
300000c8: e3a03000  mov r3, #0 ; 0x0
300000cc: e1a00003  mov r0, r3
300000d0: e28bd000  add sp, fp, #0 ; 0x0
300000d4: e8bd0800  pop {fp}
300000d8: e12fff1e  bx lr

|
ADR:
    这是一条小范围的地址读取伪指令,它将基于PC的相对偏移的地址值读到目标寄存器中。
    使用的格式:ADR register,exper。
    在编译源程序时,汇编器首先计算出当前PC到exper的偏移值#offset_to_exper,然后会用一条ADD或者SUB指令来替换这条伪指令,例如:ADD register,PC,#offset_to_exper。
    注意,标号exper与指令必须在同一代码段。
ADRL:
    这是一条中等范围的地址读取伪指令,它将基于PC的相对偏移的地址值读到目标寄存器中。
    使用的格式:ADRL register,exper。
    在编译源程序时,汇编器会用两条合适的指令来替换这条伪指令。
    例如:
             ADD register,PC,offset1
             ADD register,register,offset2  
    与ADR相比,它能读取更大范围的地址。
    注意,标号exper与指令必须在同一代码段。
LDR:
   第一种情况:
        当LDR用做ARM指令时,它将基于PC的相对偏移地址处存储的值读到目标寄存器中。
        应用格式:LDR register,[expr]
   第二种情况:
         当LDR用做ARM伪指令时,它用于大范围的地址读取。
         其实说它用于大范围的读取,还不如说它用于大范围的地址赋值。我们来看一下这条伪指令的应用格式:LDR register,=expr/label_expr ,显然,我们可以直观的看出,指令的目的就是要将expr或label_expr赋值(=)给register.所以在编译时,当expr或label_expr的值没有超出MOV和MVN的范围时,采用MOV或MVN指令来代替这条伪指令就显得理所当然了。当expr或label_expr的值超出MOV和MVN的范围时,汇编器将expr或label_expr放入文字池中,并使用一条程序相对偏移指令LDR从文字池读出常量。例如:LDR register,[PC,#offset to literal pool]

    
 
 

您可能感兴趣的文章:

 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • arm-elf-gcc 和 arm-linux-gcc有什么区别?arm-elf-gcc里的elf代表什么?
  • 关于买ARM9或ARM11的开发板的问题~~~
  • arm-unknown-linux-gnu-gcc與arm-linux 的compiler有不同嗎
  • make ARCH=arm CROSS_COMPILE=arm-linu-错误
  • 请问哪有 arm-linux-nm, arm-linux-addr2line等等这些工具的使用说明~~~
  • 使用eclipse 加入arm-elf-gcc 或arm-linux-gcc 编译器为什么不好使
  • 现在是ARM9还是ARM11比较流行啊?我想买开发板什么牌子的比较好啊,我是大学生。
  • ARM ping不通虚拟机,虚拟机可以ping通ARM
  • 疑惑softfloat的问题,并求arm-linux-gcc和arm-linux-softfloat-gcc4.1.1
  • 新手请教 移植2.6内核到arm9,芯片:arm926ejs,Flash: NOR
  • 请教:make ARCH=arm CROSS_COMPILE=arm-linu- menuconfig出错
  • arm-linux-gcc 交叉编译poco-1.3.5-all 报错stlport_arm_linux_gcc库找不到
  • 关于arm 2440 选择arm-linux-gcc编译器版本的问题
  • 字节对齐 ARM VS Not ARM,经验人士请指点!!
  • ARM开发怎么实现域名解析呢,ARM板能ping通IP,不能ping通域名?
  • 关于ARM的几个基本概念
  • arm linux 2.6.29 下载初级问题,大家指教
  • 关于ARM内核编译
  • arm-elf-gcc问题
  • ARM linux学习的问题


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3