ARM64汇编0A - thumb模式与IT块

本文主要讨论一下 32 位程序下的 thumb 模式相关东西,属于选读内容。

thumb模式

ARM模式的指令集宽度是32位而Thumb是16位宽度(但也可以是32位)。

Thumb也有很多不同的版本。不过不同的名字仅仅是为了区分不同版本的Thumb指令集而已(也就是对于处理器来说,这些指令永远都是Thumb指令)。

**Thumb-1(16位宽指令集):**在ARMv6以及更早期的版本上使用。

**Thumb-2(16位/32位宽指令集):**在Thumb-1基础上扩展的更多的指令集(在ARMv6T2以及ARMv7即很多32位Android手机所支持的架构上使用)

**Thumb-EE:**包括一些改变以及对于动态生成代码的补充(即那些在设备上执行前或者运行时编译的代码)。

thumb模式下有长指令与短指令,长指令是4个字节,短指令是2个字节。

在短指令里面,只能使用 R0-R7 这几个寄存器,如果要使用R8-R12,则会生成长指令。这里可以在指令编码中体现出来,我们看一个 add 指令的例子:

对寄存器的描述只使用了3位。

短指令里面会强行影响标志位,看一个例子:

复制代码
00 24              MOVS R4, #0

这里生成的 MOV 是带 S 的,当我们尝试去掉这个 S 的时候,发现它生成的指令如下:

复制代码
4F F0 00 04        MOV R4, #0

反而变成了长指令。

运算指令优先对第一,第二操作数相同的情况进行短指令编码:

复制代码
7E 44          ADD R2, PC

之前学过ADD指令,它是有3个操作数的,但是这里只有俩个,是因为它是简写,相当于:

复制代码
ADD R2, R2, PC

在 IDA 中,thumb 模式下有些指令带了 W 后缀,其实不用管,带 W 就理解成长指令就行,主要是看指令部分,后缀可忽略,比如下面的指令其实就是 STR 指令:

复制代码
C3 F8 AC 01           STR.W R0, [R3, #(dword_4969C - 0x494E0)]

IT块

为了在Thumb模式下使用条件执行指令,Thumb提出了"IT"分支指令。然而,这条指令在之后的版本又被更改移除了,说是为了让一些事情变得更加简单方便。我觉得不用深究这个问题。了解一下知识,遇到再深入学习。

一些版本的ARM处理器上允许在Thumb模式下通过IT汇编指令进行条件执行。条件执行减少了要被执行的指令数量,以及用来做分支跳转的语句,所以具有更高的代码密度。

IT 是 IF-THEN 的简写。IF-THEN(IT)指令围起一个块,里面最多有 4 条指令,它里面的指令可以条件执行。需要注意的是,在IDA调试的时候,IT指令块并不是一句一句的执行,而是一次性全部执行完,所以我们无法在IT指令块中间下断点。

IT 指令已经带了一个"T",因此还可以最多再带 3 个"T"或者"E"。并且对 T 和 E 的顺序没有要求。**其中 T 对应条件成立时执行的语句,E 对应条件不成立时执行的语句。**在 If-Then 块中的指令必须加上条件后缀,且 T 对应的指令必须使用和 IT 指令中相同的条件,E 对应的指令必须使用和 IT指令中相反的条件。

IT 的使用形式总结如下:

  • IT;围起 1 条指令的 IF-THEN 块

  • IT;围起 2 条指令的 IF-THEN 块

  • IT;围起 3 条指令的 IF-THEN 块

  • IT;围起 4 条指令的 IF-THEN 块

其中,,的取值可以是"T"或者"E"。而则是在下中列出的条件(AL 除外 ):

IT 指令优化 C 代码的例子如下面伪代码所示:

复制代码
if (R0==R1)
{
    R3 = R4 + R5;
    R3 = R3 / 2;
}
else
{
    R3 = R6 + R7;
    R3 = R3 / 2;
}

可以写作:

复制代码
CMP   R0, R1     ; 比较 R0 和 R1
ITTEE EQ         ; 如果 R0 == R1, Then-Then-Else-Else
ADDEQ R3, R4, R5 ; 相等时加法
ASREQ R3, R3, #1 ; 相等时算术右移
ADDNE R3, R6, R7 ; 不等时加法
ASRNE R3, R3, #1 ; 不等时算术右移

IT 块的编码非常的有意思:

mask 占据了后4位,这个是我们需要关注的。

当我们写指令 ITTTT 时,生成的指令是 01。

当我们写指令 ITTTE 时,生成的指令是 03,发现多了一位 1。

当我们写指令 ITTEE 时,生成的指令是 07,发现又多了一位 1。

当我们写指令 ITEEE 时,生成的指令是 0F,发现又多了一位 1。

所以,我们发现,最后一位一直是1,它表示IT后跟着的第一条指令的条件永远是正,即与 IT 保持一致,后面的几条指令,需要根据对应的bit位来决定条件是正还是反。

相关推荐
sky_ph13 分钟前
JAVA-GC浅析(二)G1(Garbage First)回收器
java·后端
siwangqishiq223 分钟前
Vulkan Tutorial 教程翻译(四) 绘制三角形 2.2 呈现
前端
李三岁_foucsli25 分钟前
js中消息队列和事件循环到底是怎么个事,宏任务和微任务还存在吗?
前端·chrome
尽欢i25 分钟前
HTML5 拖放 API
前端·html
IDRSolutions_CN35 分钟前
PDF 转 HTML5 —— HTML5 填充图形不支持 Even-Odd 奇偶规则?(第二部分)
java·经验分享·pdf·软件工程·团队开发
hello早上好38 分钟前
Spring不同类型的ApplicationContext的创建方式
java·后端·架构
PasserbyX41 分钟前
一句话解释JS链式调用
前端·javascript
1024小神42 分钟前
tauri项目,如何在rust端读取电脑环境变量
前端·javascript
Nano1 小时前
前端适配方案深度解析:从响应式到自适应设计
前端
古夕1 小时前
如何将异步操作封装为Promise
前端·javascript