ARM架构下十六进制数符号扩展方法及分支地址计算问题
ARM32架构分支指令偏移符号扩展规则解答
符号扩展的核心规则永远是:先明确待扩展值的原始有效位宽,取该位宽下的最高位(符号位)的值,将其复制填充到扩展后的所有高位,和十六进制书写时的最高位数字没有直接关系,这是你之前猜测的错误核心点。
ARM32 B/BL类指令地址计算固定流程
ARM32采用三级流水线,PC值默认指向当前指令后第2条指令,B/BNE这类相对跳转指令的编码中仅携带24位有符号立即数偏移,计算目标地址步骤如下:
- 第一步:计算当前PC值 = 跳转指令自身地址 + 0x8,你给出的示例中指令地址为
0x28,因此PC值为0x28 + 0x8 = 0x30,这一步计算正确。 - 第二步:取出指令编码中的24位立即数
imm24,左移2位得到26位偏移:因为ARM指令是4字节对齐,偏移的最低2位固定为0,无需存储,左移2位即可得到字节偏移的低26位。你示例中的指令编码为1AFFFFFA,对应的imm24为0xFFFFFA,左移2位后得到26位值0x3FFFFE8,这一步数值计算正确。 - 第三步:将26位偏移符号扩展为32位有符号整数:26位值
0x3FFFFE8的最高位(第25位)为1,因此需要将扩展的高6位(32位的第26位到第31位)全部填充1,最终得到的32位偏移为0xFFFFFFE8,这就是你查到的网上结果,是正确的,不是你猜测的03FFFFE8或者F3FFFFE8。 - 第四步:目标地址 = PC + 32位偏移,示例中最终目标地址为
0x30 + 0xFFFFFFE8 = 0x18。
你提到的0x03FFF4扩展结果验证
如果0x03FFF4是24位的imm24,它的24位最高位(第23位)为0,因此符号扩展到32位时,高8位全部填充0,最终结果就是0x0003FFF4,这个结果也是正确的。
典型误区说明
你之前猜测的「取十六进制最高位数字的最高有效位作为符号位」是错误的,相同的十六进制值如果原始有效位宽不同,符号扩展结果会完全不同:
比如0xF3如果是8位值,最高位为1,扩展到16位结果为0xFFF3;如果0xF3是16位值,最高位为0,扩展到32位结果为0x000000F3。
内容的提问来源于stack exchange,提问作者JustLearning321
相关产品推荐
相关产品推荐

