注册 登录
自由的生活_软路由 返回首页

心想事成的个人空间 https://bbs.routerclub.com/?681 [收藏] [复制] [分享] [RSS]

日志

ARM中基于PC的寻址

已有 1320 次阅读2013-4-6 13:03

最近看ARM的反汇编,计算地址时搞得有点头晕,总结了两天,把总结的结果记录下来。还是那句话,网上的资料很零碎,多不可信。


在ARM的代码中,经常会用到相对偏移,换句话说就是基于PC的寻址,以PC为基准,加上偏移后找到相对地址。听起来似乎是个很简单的事情,但由于ARM指令的多样性,从ARM的指令机器码推算出偏移地址并不是一件简单的事情。


今天用一个例子讨论三种基于PC的寻址方式,相关的规则等等。看一段Thumb指令:



先看0x8964处的指令:BL sub_8B84,对应的机器码是:F90EF000. 

第一个问题来了,Thumb指令不是16bit吗?为何这个指令是32bit?原因是ARMv7中引入了新的指令模式Thumb-2,Thumb-2允许16bit和32bit的指令混合使用,添加了一些新指令,即兼顾了ARM体积小速度快的优点,又兼顾了Thumb低功耗的有点。在Thumb-2的模式下如果指令bit[15:11]=11101/11110/11111, 那么这条指令就是32bit,否则就是16bit. 这个case中bit[15:8] = 0xF0, bit[15:11] = 11110, 属于32bit指令。


那么如何通过0xF90EF000实现从0x8964到0x8B84的偏移的?先要查阅Thumb-2中32bit BL指令的格式。经查询,这条指令符合如下格式:

套这个格式的时候,左边的16bit对应指令的低16位,右边的对应高16位。这条指令的参数:S=0,imm10=0,J1=1,J2=1,imm11=0x10E

根据公式算出 imm32 = 0x10E<<1 = 0x21C,因为S=0所以这是一个正数,向后跳转。为何要左移一位?因为Thumb-2指令的长度是2字节或者4字节,那么指令的开始地址最后一位一定是0,所以在指令中把要存储的地址右移一位,节省空间。如果是表示ARM指令的地址,那么就要左移两位,原理是一样的。

回过头来再看PC的值和要跳转的地址:0x8B84-0x8964=0x220,什么?居然不是0x21C?原因是在执行这条指令的时候PC的值并不是0x8964. 由于ARM处理器采用的是流水线技术,使用指令预取,在执行一条指令的时候PC的值是下下条指令的地址。那么下下条指令地址要加多少呢?在ARM模式下是4*2=8,在Thumb模式下是2*2=4. 那么在Thumb-2模式下是多少?也是2*2=4,虽然Thumb-2有些指令是4字节,但依然按照2*2=4来算。

所以0x21C+4=0x220,一切都能说的通了。


再看另外一条指令, 0x895E: BEQ loc_8A40, 机器码:0xD06F, 这是一个16bit的Thumb-2指令。CPU怎么知道这是个16bit的指令的?前面已经说过了,如果这是个32bit的指令,那么bit[15:11]=11010,显然不符合标准。因而这是个16bit指令。有了前面的基础,这个就好推算多了。先查ARM指令表,符合这个格式:

cond=0, imm8=0x6F

imm32 = 0x6F<<1 = 0xDE == 0x8A40-(0x895E+4)

解释圆满


最后看0x895A处的指令:LDR R3,=0x2711,机器码:0x4B3D, 这也是一个16bit的Thumb-2指令。显而易见的是0x2711超过了16bit指令所能忍受的立即数大小,因而0x2711不能直接放在指令里,而是要放在其他地方,用指令里存储的偏移地址来索引。还是一样先查ARM指令表,找到符合的格式:


Rt=3, imm8=0x3D

imm32=0x3D<<2=0xF4

按此推论存放0x2711的地址:0x895A+4+0xF4=0x8A52

查看一下具体地址:

居然是0x8A50,差了两个字节,怎么回事?

再仔细查看ARM指令说明,找到这么一行:

原来这个指令在寻址的时候要求字对齐(4字节),因而会强制把bit[1]设为0,不巧的是我们这个PC原来的值bit[1]刚好是1,所以PC的值被减去了2,又一次真相大白了。


总的来说ARM指令的寻址多种多样,对于每一种寻址方式都需要仔细查阅官方指令表,认真推算才能不出错。


路过

雷人

握手

鲜花

鸡蛋

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

QQ|Archiver|手机版|小黑屋|软路由 ( 渝ICP备15001194号-1|渝公网安备 50011602500124号 )

GMT+8, 2024-5-10 05:22 , Processed in 0.074431 second(s), 5 queries , Gzip On, Redis On.

Powered by Discuz! X3.5 Licensed

© 2001-2023 Discuz! Team.

返回顶部