ARM跳转指令B的偏移位置如何计算

首先ARM的官方资料中是这样介绍B跳转指令的,如下:

有几个疑点:

  1. 偏移量是24位有符号立即数,那符号位是哪一位?
  2. 分支指令B限制在当前指令±32M字节地址范围内,这个±32M字节是如何计算出来的?
  3. 跳转指令B是位置无关指令,如何实现的位置无关?

要解决这个问题,需要分析一段汇编程序.

绿色框内的汇编程序是BL跳转指令,其实和B道理想通,只是多了带状态位的跳转,偏移量计算是相同的.

首先这条指令存储在0X30006A18处,我们知道这个地址是当前程序执行的地址,而PC指针地址为0X30006A20,这是因为此ARM处理器是3级流水线,当前执行的指令的下一条指令正在译码,即0X30006A1C地址处的指令正在译码,再下一条指令0X30006A20地址处正在执行取指,也就是pc指针指向的位置.

从绿色框内的指令可知,机器码是0XEBFFFB0B.根据B跳转指令的编码格式的值b31-b28是条件码,b27-b24是命令码,b23-b0是偏移量.则此命令偏移量gap=0XFFFB0B.当前PC=0X30006A20,从绿色框内命令的注释得知,此命令的跳转目的地址是0X3000564C,那如何从偏移地址和当前PC指针得出来跳转目的地址呢?

首先偏移地址是24位有符号数,按32位有符号数的惯例,最高位是符号位,那此偏移量的bit23应该是符号位,0XFFFB0B转换成二进制格式为1111 1111 1111 1011 0000 1011,可知最高位是1,则此数值是二进制补码的格式表示的负数,将一个正数转换为对应的负数的方法是取反加一,那么这个二进制补码的偏移量转换为对应的正数就是逆过程,减1取反.减1后为1111 1111 1111 1011 0000 1010,再取反为0000 0000 0100 1111 0101,此数值转换为16进制为0X4F5,那么偏移量就是-0X4F5.那这个就是实际的偏移地址了吗,非也,看分支指令的最后一句话,arm指令为字对齐,最低两位为0,所以这个偏移量是偏移的命令条数,不是地址,如果要转换成地址需要对此偏移量乘以4,因为没条指令为4字节宽度,最总的偏移量是gap=-0X4F5*4=-0X13D4.

最后我们知道了gap的值,也知道了pc的值,那最终的目标跳转地址adr=pc+gap=0X30006A20+(-0X13D4)=0X3000564C,此时你会惊奇的发现,这个结果与绿色框内的指令注释的地址相同,单步程序后,发现程序精准的跳到了0X3000564C处执行了.

实践证明我们的推测是正确的,如果偏移量是个正数呢,你会推倒吗?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值