ARM ARM(ARM 架构参考手册)是一个很好的资源,尤其是 ARM 和 thumb 指令编码。对于 thumb2,尽管查找 ARMv7-M TRM(技术参考手册),两者都是免费下载的。
(我知道我从 0x7200 十六进制而不是 7200 十进制开始,没关系,最后一切都解决了)。
子 r3,r3,#0x7200 编码如下(对于 ARM)。
e2433c72 sub r3, r3, #29184 ; 0x7200
E 表示总是执行
2 的高三位表示数据处理立即数,没有其他固定位
两位的低位和 4 的高 3 位是 0010,表示 sub。
4 的低位是 s 位,意思是更新标志(如果设置了该位,将是一条 subs 指令)。接下来的两个半字节 3 和 3 是 r3 的两个实例,接下来的 4 位,c 是循环字段,低 8 位是立即数。
移位器操作数是 immed_8 rotate_right(rotate_immed *2) 所以这将是
0x72 向右旋转(24 位),这与向左旋转 32-24 位相同,因此立即变为 0x7200。
对于 thumb2(这是 sub.w 的来源,编码如下:
f5a3 43e4 sub.w r3, r3, #29184 ; 0x7200
T3 编码
0xF1A00000 有或没有一些位是 SUB.W rd,rd,#const 的基线编码(有 12 位立即数,T4 也有 12 位立即数)。
0x5 中的 0x4 位是 i 位并且被设置所以我们需要知道,s 位没有设置,它是一个 sub 而不是 subs。 0x....4... 中的低三位是 imm3 字段,低 8 位是使用 arm 表示法的 imm8 字段我们的立即数是 1:100:11100100
取前五位,i、imm3 和上 imm8 位 11001
这意味着取位模式 11100100 并将其右移 1001 位
00000000011100100……
0000 0000 0111 0010 0......
而常数是
0x00720000 已关闭 256,必须弄清楚
嗯,我在做 0x7200,你在做十进制 7200,正如你提到的,是 0x1C20
所以看看你的工具告诉你工具告诉你什么
A3 F5 E1 53
我们知道我们需要一个 0xF5A3,所以也许另一部分也被交换了。
0xF5A353E1
我得到的是什么:
f5a3 53e1 sub.w r3, r3, #7200 ; 0x1c20
相同的 t3 编码
0xF5A3 表示 sub.w something,r3,something with the i bit set
0x53E1 表示 sub.w r3,r3,something 和 const 是
1:101:11100001
高 5 位 11011
这意味着将 11100001 右移 0b1011 位,即 11
0000000000011100001000
0000 0000 0001 1100 0010 0000 0000 0000
0x001C2000
如果您足够大,可以认识 Seinfeld,这属于 yada,yada 类别。
armv7-m TRM 的 A5.3.2(修改 thumb 指令中的立即常数)。
01010 它们显示为填充了两位(在这五位中,mnopq 丢弃第二位 n,将 mopq 作为移位量或在本例中为 0b0010)。
他们还有……其他的东西,yada yada,然后
11111 变为 23 位移位/填充
11110是垫22
11101 是焊盘 21,但中间的区域不是线性的,那里有一些魔力
如果我们继续向后工作
11100 是焊盘 20,
11011是垫19,
这就是我们在 immed8 的 1 和低 7 位之前寻找 19 的填充。
0x00001C20
因此,thumb2 12 位常量编码有点难以理解,很多有趣的常量可以优化。设置了 imm3 的高位的这个特殊设置为您留下了 4 位或 16 个模式/值。但是我们可能要填充多达 24 位,但我们无法到达那里。显然,如果 i 位为零,则从顶部向下填充,如果设置了 i 位,则从中间点开始填充。
所以看一下 armv7 trm 中的 SUB 指令。编码 t3 与您尝试执行的操作一致。描述说拇指移位值是i:imm3:imm8,取那些位
到同一手册的 a.5 部分并查看表 a5-1,T3 编码将其称为 const 而不是 imm12,imm12 编码看起来在 a5-1 表之后的伪代码中。
另请注意,您正在查看 thumb2 指令时没有使用 ARM 指令。是的,属于 ARM 系列,但指令集或模式不同。