ARM机器码中操作SP的SUB/ADD类立即数指令的编码规则问询
ARM32状态下SUB/ADD指令的立即数偏移编码逻辑
核心说明
- 你给出的
SUB/ADD SP, SP, #imm类指令,属于ARM32 ARM状态(非Thumb)的立即数型数据处理(DP)指令 - 立即数并非直接在机器码中存储,也不能通过简单与低16位掩码运算得到,而是采用「8位常数 + 4位旋转控制」的压缩编码规则
- 需先从32位机器码中提取bit11~bit0的12位立即数压缩字段,再按固定规则还原为实际偏移量
32位机器码固定位段划分
所有立即数型DP指令的32位机器码,从最高位bit31到最低位bit0的拆分规则为:
bit31~bit28:条件码(你看到的指令开头E对应AL,即无条件执行)bit27~bit25:固定为000,用于标识数据处理类指令bit24~bit21:操作码(SUB对应0101,ADD对应0100)bit20:S位(标识是否修改程序状态寄存器,你给出的示例中该位均为0)bit19~bit16:源寄存器Rn(SP对应R13,编码为1101即十六进制D)bit15~bit12:目标寄存器Rd(SUB SP,SP,#xx的Rd也是SP,编码同样为D)bit11~bit0:立即数压缩编码字段(核心计算依据)
立即数压缩编码的还原规则
bit11~bit0的12位字段会被拆分为两部分:
bit11~bit8:4位旋转控制值(记为rotate_imm,取值范围0~15)bit7~bit0:8位无符号常数(记为immed8,取值范围0~255)
实际有效立即数的计算公式:
有效imm = immed8 循环右移(ROR)2 * rotate_imm位
(32位环境下,循环右移n位等价于循环左移32-n位,可简化计算)
结合示例的逐行验证
示例1:e24dd024对应sub sp, sp, #36
- 提取bit11~bit0的12位字段:机器码
0xE24DD024的低12位为0x024 - 拆分12位字段:
rotate_imm = 0x024的高4位 = 0x0(对应bit11~bit8为0000)immed8 = 0x024的低8位 = 0x24
- 还原有效偏移:
0x24 ROR (2*0) = 0x24 = 36
直接纠正你的疑问:不能通过
e24dd024 & 0x0000ffff计算立即数,该运算得到的结果为0xd024,其中0xd是目标寄存器Rd(SP)的编码,不属于立即数字段。
示例2:e24ddd0a对应sub sp, sp, #640
- 提取bit11~bit0的12位字段:机器码
0xE24DDD0A的低12位为0xD0A - 拆分12位字段:
rotate_imm = 0xD0A的高4位 = 0xD = 13(对应bit11~bit8为1101)immed8 = 0xD0A的低8位 = 0x0A = 10
- 还原有效偏移:
- 移位量 =
2 * 13 = 26 - 将
0x0A扩展为32位0x0000000A,循环右移26位等价于循环左移32-26=6位,最终得到0x00000280 = 640
- 移位量 =
其余示例快速验证
- 机器码
e24dd034:低12位0x034,rotate_imm=0,immed8=0x34→ 有效偏移0x34=52 - 机器码
e28d5014:低12位0x014,rotate_imm=0,immed8=0x14→ 有效偏移0x14=20 - 机器码
e28d60a8:低12位0x0a8,rotate_imm=0,immed8=0xa8→ 有效偏移0xa8=168 - 机器码
e28d5e13:低12位0xe13,rotate_imm=0xe=14,immed8=0x13→ 移位量28,循环右移28位等价于左移4位,得到0x130=304
内容的提问来源于stack exchange,提问作者Ngoc Hoang Nguyen
相关产品推荐
相关产品推荐

