ldr与adr的区别

本文详细探讨了ARM指令集中的ldr和adr指令。通过实例分析,解释了两者如何与程序计数器(PC)关联,以及在运行时如何导致不同的地址计算。ldr指令用于从内存中加载由PC相对地址指定的数据,而adr指令则直接计算标签的地址。在动态地址计算中,ldr可能因运行地址变化而取到错误的地址,而adr则能正确获取标签的静态地址。
摘要由CSDN通过智能技术生成
.global _start

_start:
		ldr r0,=label
		adr r0,label

stop:
		b stop

label:
		.word 0x12345678

在学习adr指令时,对ldr与adr有些难以理解

debug后的对应的代码为

0x00000000  E59F0008  LDR       R0,[PC,#0x0008]        @//对应ldr
0x00000004  E28F0000  ADD       R0,PC,#0x00000000        @//对应adr

乍一看,两条代码都与PC相关,我想不通为什么会因为运行地址不同而导致ldr取不到正确的标签地址。

0x00000010  0000000C  ANDEQ     R0,R0,R12

再仔细看,ldr是取得[PC,#0x0008]处存储的内容,而非是获得标签处的地址

举例说明,

@//写代码时
0x00000000  E59F0008  LDR       R0,[PC,#0x0008]        @//PC为0x00000008
0x00000004
0x00000008
0x0000000c  12345678  EORNES    R5,R4,#0x07800000
0x00000010  0000000C  ANDEQ     R0,R0,R12         @//存储标签所在地址
0x00000014

@//运行时,假设运行地址从3000开始
0x00003000  E59F0008  LDR       R0,[PC,#0x0008]        @//PC为0x00003008
0x00003004
0x00003008
0x0000300c  12345678  EORNES    R5,R4,#0x07800000
0x00003010  0000000C  ANDEQ     R0,R0,R12        @//此处存储的是编译前标签所在地址,
0x00003014                                       @//编译后内容不会更改,
                                                 @//所以ldr仍取到0000000C,
                                                 @//而此时正确的地址为0x0000300c

所以,ldr与adr都与PC相关,但adr是通过与标签的相对地址直接获取标签的地址。

ldr是通过与某一 存储标签地址的地址 的相对地址间接获取到编译前存在此处的标签地址,相当于”刻舟求剑“

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值