ARM汇编伪指令adr\ldr\adrl\nop

本文介绍的伪指令:

  • adr 小范围的地址加载指令

  • ldr 大范围的地址加载指令

  • adrl 中等范围的地址加载指令

  • nop 空操作

伪指令说明

1、伪指令adr

汇编时adr伪指令通常被编译器用ADD或SUB指令实现,若不能以一条指令替换则报错。adr伪指令是基于pc或者寄存器的,基于pc时,该地址需和adr伪指令位于同一代码段。

ADR伪指令格式 :ADR{cond} register, expr 地址表达式expr的取值范围: 当地址值是字节对齐时,其取指范围为: +255 ~255B; 当地址值是字对齐时,其取指范围为: -1020 ~ 1020B;   

2、伪指令ldr

汇编时ldr伪指令会被替换成一条合适的指令,使用mov或mvn指令替代它,否则放入文字池(比较深入没看)

ARM中有一个ldr指令,还有一个ldr伪指令一般都使用ldr伪指令而不用ldr指令,不用考虑立即数是否合法。区别在于立即数前面的符号是#还是=。

ldr指令: ldr r0, #0xff

ldr伪指令: ldr r0, =0xf1 @涉及到合法/非法立即数,涉及到ARM文字池。编译后被mov r0, #0xf1

重点:(为了更容易理解需要一点程序链接的知识)

adr和ldr的差别:ldr加载的地址在链接时确定,而adr加载的地址在运行时确定;所以我们可以通过adr和ldr加载的地址比较来判断当前程序是否在链接时指定的地址运行。通过两种伪指令实现方式大概可以看出两种指令差别。这种差别在以下情况下应用时需要注意

首先说明两个概念:

  •  a、位置无关编码(PIC,position independent code):汇编源文件编码成二进制可执行程序时编码方式与位置(内存地址)无关。
  • b、位置有关编码:汇编源码编码成二进制可执行程序后和内存地址是有关的

链接地址和运行地址:可能相同也可能不同

对于位置有关代码来说:最终执行时的运行地址和编译链接时给定的链接地址必须相同,否则一定出错。说一下原因,程序代码运行时要从rom复制到ram中,这样运行速度更快,但是这就有一个问题,那就是把代码复制到ram的什么地址去运行,位置无关码则都可以,但使用了位置有关码,那么复制的目标地址必须与连接地址相同。

ldr作为伪指令进行跳转时时就是位置有关码。比如这一条ldr pc, =main 我们想通过向PC寄存器写入 main函数地址来跳转执行main函数,这就相当于向PC写了一个常数,这个常数就是连接时main的地址。当在ram运行时位置发生偏移那么这条指令就跳转到错误位置,不会执行到main函数。

想反adr进行跳转时就是位置无关码,因为adr跳转是以地址差值进行跳转的,在ram运行时adr指令当前地址和目标地址可能与连接时不同,但是两个地址之间的差值不会变所以,adr位置无关。

3、伪指令adrl

中等范围的地址读取 ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。

ADRL伪指令格式:ADRL{cond} register, expr 地址表达式expr的取值范围: 当地址值是字节对齐时,其取指范围为: -64K~64K; 当地址值是字对齐时,其取指范围为: -256K~256K;

4、伪指令nop

格式:NOP
功能:延时;
特点:NOP伪指令在编译时将会被替代成ARM中的空操作,比如MOV R0,R0指令等;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值