Java教程

Arm入门第三讲 Arm指令集学习 未完待续

本文主要是介绍Arm入门第三讲 Arm指令集学习 未完待续,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

目录
  • Arm入门第三讲 Arm指令集学习
    • 一丶Arm指令集
      • 1.1 Arm指令集特点
      • 1.2 流水线执行
    • 二丶Arm指令格式(重要)
      • 2.1 Arm Opcode
      • 2.2 指令组成格式了解
      • 2.3 I模式详解
      • 2.4 指令的条件执行
    • 三丶Arm汇编指令学习
      • 3.1 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位的数那? 是不是就不行了那?

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 + R2
ADDEQ 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与立即数0
BEQ  Skip 如果相等则跳转到skip标签执行
ADD  R0,R1,R2  这里就是如果不想等则会执行 R0 = R1 + R2
Skip:     这是标签

第二个程序

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

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

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

三丶Arm汇编指令学习

3.1 Arm的加减汇编指令

Arm的加减汇编指令分为如下:

ADD 加法指令
ADC 带进位加法指令
SUB 减法指令
SBC 带借位的减法指令
RSB 逆向减法指令
RSC 带借位的逆向减法指令
  • ADD加法指令

    ADD 指令,是用于把两个操作数相加,并且将结果放到目的寄存器中.

    操作数1(op1)应是一个寄存器,操作数2可以是一个寄存器,也可以是一个立即数,也可以是一个移位寄存器.

    ADD{条件}{S}<dest>,<op1>,<op2>
    例子:
    ADD R0,R1,R2   将R1 + R2赋值给R0 也就是 R0 = R1 + R2
    ADD R0,R1,#2   寄存器与立即数之间的加法操作 R0 = R1 + 2
    ADD R0,R2,R1,LSL@1 包含移位运算的加法操作,先进性移位操作.在进行加法操作
    R0 = R2 + (R1 << 1)
    

    指令中如果带有S后缀 那么就是要影响 ARM中的状态寄存器 状态寄存器 CPSR 也是一个32位 的寄存器. 主要就是保存程序的运行状态. 比如 第29位C标志 那么 如果 R0 = R1 + R2(目的寄存器 = 操作数1 + 操作数2) 两个32位数相加的结果超出了32位 就会产生进位 那么 C标志就会设置为1 否则C就设置为0 如果ADD指令中不加 S后缀的话.那么两数相加 结果是否产生进位都不会改变 CPSR寄存器

    MOV R1,#0XF1000000
    MOV R2,0X800000000
    ADD R0,R1,R2   可以查看CPSR中的C位是否发生改变
    ADDS R0,R1,R2  可以查看CPSR中的C位是否发生了变化
    

    溢出位的了解

    C标志位 如果在加法运算中 产生了进位. 那么C = 1 这表示无符号运算发生了上溢出了. 其它情况则为0

    C标志位 如果在减法运算中产生了借位. 那么C = 0. 简单理解就是C保存了进位.减法借位之后就没了.

    这有个名词,意思就是表示无符号运算发生了下溢出. 其它情况下C为1. 正好与加法相反

  • SUB 减法指令

    SUB指令用于把操作数1减去操作数2的结果 放到目的寄存器中. 操作数1 可以是寄存器. 操作数2 可以是

    立即数 移位寄存器 (与ADD一样)

    例子:

    SUB{条件}{S}<dest>,<op1>,<op2>
    SUB R0,R1,R2    R0 = R1 - R2
    SUB R0,R1,#256  R0 = R1 - 256
    SUB R2,R1,R3,LSL#1   R2 = R1 -(R3<<1)
    
这篇关于Arm入门第三讲 Arm指令集学习 未完待续的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!