关于ldr和adrl使用分析

之前在操作SDRAM的实验中发现了比较奇怪的事,在韦东山老师的代码里有一段代码使用了adrl伪指令,在自己实现SDRAM程序时将adrl改成了ldr伪指令,如下所示的

 mem_ctrl_setup:
      ldr r0, =MEM_CTL_BASE
     add r1, r0, #52       @13*4
     ldr r2, =mem_ctrl_register_setup
     @adrl r2, mem_ctrl_register_setup

在改成ldr伪指令后执行程序总是出错,无法正常执行代码,后来经过查找资料,和查看反汇编代码得到以下结论:
ldr:绝对地址操作 (跳转的地址保存在文字池)
adr:相对地址操作
adrl 指令反汇编代码:
在这里插入图片描述
adrl r2, mem_ctrl_register_setup 经过反汇编得到第一个红框中内容add r2, pc, #58,此时r2 = 0x30000058 + 0x38 = 0x30000090,值58就是当前pc相对于mem_ctrl_register_setup 函数地址的偏移量与位置无关。无论链接地址或者代码的执行地址是多少都不会影响到r2中的最终值,即r2最终都是保存的mem_ctrl_register_setup 地址值。
ldr 指令反汇编代码:
在这里插入图片描述
ldr r2, mem_ctrl_register_setup 经过反汇编得到第一个红框中内容ldr r2, [pc, #120] ,此时pc + #120 = 0x30000058 + 120 = 0x300000d0,从上图中看r2中保存的值为0x30000090。
此时从反汇编代码看使用ldr和adrl指令后r2的值都是0x30000090,但是就是由于相对地址和绝对地址的原因导致最终r2中保存的值是不同的。
具体看,adrl指令由于是进行相对地址操作,所以r2保存的应该是0x00000090,ldr指令是进行绝对地址操作,所以r2保存的就是0x30000090。
解释一下adrl指令执行后为什么r2中保存的是0x00000090呢,是因为程序开始执行时是从0地址处进行的pc值也是从0开始,此时还没有到sdram中运行,将反汇编里没搬运代码前的地址都减0x30000000就是pc的实际值,所以r2中保存的是0x00000090。
解释为什么使用ldr指令后r2的值变得不正确了,从反汇编看在0x300000d0(可以认为是0x000000d0)里存放的是0x30000090,所以ldr执行后r2保存的值就是0x30000090(应该是0x00000090)。但是就目前的状态mem_ctrl_register_setup函数的实际地址是0x00000090。
ldr指令结束后由于r2的内容不正确,那么就导致了后续sdram寄存器配置错误(此时代码还没有拷贝到SDRAM中),继而导致程序后续执行失败。
那么什么时候0x30000000地址就是pc值得起始值呢,就是在所有代码在sdram中正确执行后,pc值就是0x30000000以后的值了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值