当前位置: 技术问答>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
.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]
这是一条小范围的地址读取伪指令,它将基于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.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。