Arm入门第三讲 Arm指令集操作码学习

Arm入门第三讲 Arm指令集学习

一丶Arm指令集

1.1 Arm指令集特点

  • 1.所有指令都是定长的: 4个字节以内 x86指令是变长的可以很长很长.

  • 2.大部分指令都可以在一个时钟周期内完成.这比x86好多了 x86为了优化指令周期才会进行代码优化

  • 3.每一条指令都可以有条件执行. (ADD, ADDEQ QNLY IF Z=1)

    这个条件执行大概是什么意思那. 意思就是ADD是进行加运算,这与x86一样. 但是ADD后面可以加条件状态比如EQ. 如果加了EQ那么他会先检查状态标志位中的Z位. 从而决定执不执行这条指令 这个是ARM汇编的特点

  • 4.指令在通电之后可以配置为低位优先还是高位优先

  • 5.LOAD/STORE 模型,专有指令才能访问内存 这一点是ARM特点. x86基本大部门指令都可以直接访问内存.ARM只能用这个.

1.2 流水线执行

	流水线这个是CPU一个很重要的名字. 大概是什么意思那. 意思就是 把一条指令分成多个阶段分别指令.

以x86汇编为例子

mov eax,10
add eax,11
mov ebx,12
add ebx,13

可以看到 指令是从上往下执行的. 第二条指令需要依赖于第一条指令的结果. 这样就会导致效率很慢.

但是观看指令我们就可以优化为下面的指令

mov eax,10
mov ebx,11
add eax,11
add ebx,12

这样 第二条汇编就不依赖与第一条汇编指令了. 这就算是简单的优化了. 而流水线不只是这些. 那么下面就说下需要了解的名次把.

  • Arm 使用的是三级流水线. 来加快指令的处理速度.

    流水线技术可以使得多个操作**同步进行** 记住是同步进行. 而不是 **串行进行.**   试想一下,如果我们的第二条汇编依赖于第一条汇编的结果.那么是不是就必须等待第一条汇编执行完毕才能执行. 如果是这样就不可以同步执行了.
    

    Arm三级流水线 分别是 取址(fetch) 译码(decode) 执行(execute) 而在ARM汇编中.它的R15寄存器 也就是PC寄存器 执向的就是 fetch指令

  • x86则使用五级流水线

    分别就是 取址(fetch) 译码(decode) 转址(translate)执行(execute)写回(wb)

二丶Arm指令格式(重要)

2.1 Arm Opcode

	在x86下指令格式有x86形式. Arm同样也有自己的指令格式. 知道指令格式可以编写反汇编调试器等.

当然如果不写的话那么学习Arm也要了解指令格式.

首先在32位下有如下图:

总共 32位. 其中这里介绍下什么意思

Condition : 是用来存放我们条件码的. 比如AddEQ 后面的EQ就是条件 NE等...

I 他不会在指令之中,他表示第二操作数的类型标志码, 因为我们无法确定第二操作树的类型

Opcode 位于第21-24位之间(4位) 是用来存放我们的操作码 比如他们的助记符 Add Mov

S =1 表示是否影响我们的CPSR寄存器. 也就是比如MOVS 那么就会影响

Rn 表示第一源寄存器,表示是要从这个寄存器中取数据给RD的 ADDS R0,R1,R2 那么R1就是这里表示的,第一操作数的意思

Rd 表示目的寄存器,是用来存放我们的结果的

Operand2 表示第二操作树的,RN表示第一操作数,他可以有多种形式,可以是立即数 可以是寄存器. 也可以是寄存器加移位,如: MOVS R3,R1 LSL #2

特殊:

BL W W不在指令中.这个只是指令宽度的说明符. 不会影响指令的行为 比如单独写 bl 那么又可能是16位的,也可能32位. 
而我们Keill反汇编的时候 BLW则表示32位. 单独的bl则是16位

Operand2 疑问:

第二操作数,大小是0-11位表示. 如果是0-11位表示那么他如何能表示一个32位的数那? 是不是就不行了那?

Operand2如果是立即数那么必须是一个合法的立即数 这个立即数必须满足循环右移偶数位 而你循环右移的次数则用operand这个操作数的高四位进行保存,其它八位就是一个常数(0-255),虽然这样可以解决保存的数据很大,但是他表达的数也是有限的。所以必须满足这个公式的立即数才是真正意义上的合法立即数。

公式为:

Immediate = imm ROR(2*循环移位次数)  Imm为8位
如:
MOV R0,#4096  = 0X40 ROR(26)位

2.2 指令组成格式了解

指令组成格式看下图:

上面说了指令格式中的意思. 那么这个就是指令格式组成了.

其中在这个图中有很多 <> {} 那么分别说下什么意思把

<> 代表这一项是必须要有的. 而不是能省略的.

{} 代表是可选的就是说可以不要的.

比如有个指令为:

ADDS  那么ADD 就是Opcode 是必须要的  S代表是修改CPSR状态的. 那么中间就把条件给省略了.
你也许看到过 ADDEQ 那么EQ就是带有条件的.

2.3 I模式详解

如果 I 模式为立即数方式

如果为立即数方式,那么看下图

如果为立即数方式,那么我们的第二操作树就按照上面进行解析. 拆分为 4 8组合.

也就是一个32位的数可以用这个12位进行表示. 但是这个32位数必须是由一个八位的常数,循环右移偶数位得到的.

其中循环右移的位数是由一个四位的二进制数的两倍来进行表示的.

比如说我们有一个立即数为

4096  那么我们的八位数最高能表示0xFF(255)字节大小

2.4 指令的条件执行

有以下指令

ADD R0,R1,R2          这个就代表无条件执行 R0 = R1 + R2ADDEQ R0,R1,R2        这个就代表有条件的执行 if (zF == 1){R0 = R1 + R2} ZF = 1表示两数相等 ZF = 0 表示NE不想等  EQ是相等的意思ADDS R0,R1,R2		 这里后缀带S 不会不是判断条件执行而是设置. R0 = R1 + R2 然后SET CPSR 中的ZFlag位

好处:

指令更加精简了. 看如下代码(不懂没关系)
CMP R3,#0 比较R3与立即数0BEQ  Skip 如果相等则跳转到skip标签执行ADD  R0,R1,R2  这里就是如果不想等则会执行 R0 = R1 + R2Skip:     这是标签

第二个程序

CMP R3,#0  同上ADDNE R0,R1,R2  在ADD同时带上条件.  如果不想等 R0 = R1 + R2

所以观看两种汇编代码.发现第二种更简洁.且更好看.

ARM指令后面都可以跟上条件码,下面就是收集的条件码

posted @ 2021-07-01 22:24  Android_IBinary  阅读(2034)  评论(1编辑  收藏  举报