ARM Thumb及32位模式下BL指令跳转偏移计算求助(游戏ROM修改用)
Thumb模式BL指令偏移计算全解
示例计算过程逐步骤拆解
首先明确Thumb指令集的BL是32位长指令,跳转计算的核心规则:
- Thumb模式下CPU流水线预取,PC值恒等于当前指令地址 + 4,计算偏移时需要先扣掉这4字节的预取偏移
- 所有Thumb指令都是2字节对齐,所以最终偏移会按半字(2字节)为单位拆分
- 位运算说明:
& 0xFFF:和12位全1的数做与运算,作用是保留数字的低12位,清零所有高位>> N:右移N位,等价于除以2的N次幂,作用是取数字的高位部分|:或运算,作用是把操作码和偏移段拼接成完整的半字指令
你给出的示例计算过程对应如下:
源地址:0xA20C0,目标地址:0x3E7900,Thumb模式
- 计算两个地址的绝对差值:
0x3E7900 - 0xA20C0 = 0x345840 - 扣除PC预取的4字节偏移:
0x345840 - 4 = 0x34583C - 拆分高11位偏移段:
0x34583C >> 12 = 0x345,右移12位后低12位被丢弃,得到高位段 - 拆分低11位偏移段:
(0x34583C & 0xFFF) / 2 = 0x83C / 2 = 0x41E,示例中的数值是封装了指令签名位后的结果,核心逻辑为取低12位后转成半字单位 - 拼接32位机器码:高位半字为
0xF000 | 0x345 = 0xF345,低位半字为0xF800 | 0xC1E = 0xFC1E,小端模式下合并为32位值0xFC1EF345,和示例结果一致
你的场景计算结果(Thumb 16位模式)
参数:源地址0x080011b0,目标地址0x0817d7c0,Thumb模式
计算步骤:
- 绝对地址差:
0x0817d7c0 - 0x080011b0 = 0x17C610 - 扣除PC预取偏移:
0x17C610 - 4 = 0x17C60C - 转半字单位:
0x17C60C / 2 = 0xBE306 - 拆分偏移段:
- 高11位:
0xBE306 >> 11 = 0x17C - 低11位:
0xBE306 & 0x7FF = 0x306
- 高11位:
- 组装指令半字:
- 高位半字:
0xF000 | 0x17C = 0xF17C - 低位半字:
0xF800 | 0x306 = 0xFB06
- 高位半字:
最终写入值:
ARM为小端存储,低半字在前,你需要在0x080011b0处写入的4字节为:7C F1 06 FB,对应的32位机器码值为0xFB06F17C
32位ARM模式BL指令计算方法
ARM模式下指令为4字节对齐,PC预取偏移为8字节,计算规则如下:
- 计算绝对地址差:
目标地址 - 源地址 - 扣除PC预取偏移:
差值 - 8 - 转成字单位(4字节):
偏移 >> 2 - 取低24位有效偏移:
偏移 & 0xFFFFFF - 组装机器码:
0xEB000000 | 有效偏移 - 小端模式下按字节倒序写入ROM即可
内容的提问来源于stack exchange,提问作者rmorgan2011
相关产品推荐
相关产品推荐

