• 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 代码的例子如下面伪代码所示:

    1. if (R0==R1)
    2. {
    3.     R3 = R4 + R5;
    4.     R3 = R3 / 2;
    5. }
    6. else
    7. {
    8.     R3 = R6 + R7;
    9.     R3 = R3 / 2;
    10. }

    可以写作:

    1. CMP   R0, R1     ; 比较 R0 和 R1
    2. ITTEE EQ         ; 如果 R0 == R1, Then-Then-Else-Else
    3. ADDEQ R3, R4, R5 ; 相等时加法
    4. ASREQ R3, R3, #1 ; 相等时算术右移
    5. ADDNE R3, R6, R7 ; 不等时加法
    6. ASRNE R3, R3, #1 ; 不等时算术右移

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

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

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

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

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

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

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

  • 相关阅读:
    开源组件与中间件的学习笔记5
    首发Yolov8优化:Adam该换了!斯坦福最新Sophia优化器,比Adam快2倍 | 2023.5月斯坦福最新成果
    【SpringCloud】微服务技术栈入门4 - RabbitMQ初探
    Python中的闭包
    浏览器中的Event Loop
    SpringMVC详细复习资料(SpringMVC注解式开发,SpringMVC拦截器,SSM整合)
    微信服务商模式(电商收付通)合单支付APIV3完整Demo,可直接使用,适用于(H5、JSAPI、H5、App、小程序)
    计算机毕业设计django基于python药房药品管理系统(源码+系统+mysql数据库+Lw文档)
    postman连接数据库
    测试员有必要转测试开发吗?
  • 原文地址:https://blog.csdn.net/a5right/article/details/139407912