5. ARM_指令集

概述

分类

汇编中的符号:

  • 指令:能够编译生成一条32位机器码,并且能被处理器识别和执行
  • 伪指令:本身不是指令,编译器可以将其替换成若干条指令
  • 伪操作:不会生成指令,只是在编译阶段告诉编译器怎么编译

对于不同的CPU,指令和伪指令不同。因为指令和伪指令都由CPU来直接识别。

对于不同的编译器,伪操作不同,因为伪操作是控制编译器编译的。

ARM指令集的分类:

  • 数据处理指令:进行数学运算、逻辑运算
  • 跳转指令:实现程序的跳转,本质就是修改了PC寄存器
  • Load/Store指令:访问(读写)内存
  • 状态寄存器传送指令:用于访问(读写)CPSR寄存器
  • 软中断指令:触发软中断
  • 协处理器指令:操作协处理器的指令

其中数据处理指令、跳转指令、Load/Store指令是通用指令,任何一个CPU都具有该指令。并且这些指令在C语言中都有对应的语句。

指令格式:

汇编语言不区分大小写,但是不要出现一个指令里面既有大写也有小写。比如:可以写MOV或mov,但不要写成Mov 

立即数

什么是立即数:

立即数就是能够写在指令后面的数,例如 " MOV R0 #1 " 这个#1当中的数就是立即数。

立即数的本质就是包含在指令当中的数,属于指令的一部分。

注意:立即数不能写到32位,因为汇编指令转为机器码后是32位,这32位中有几位用来表示指令含义和寄存器含义,因此数据位并没有32位。

立即数与变量的区别:

立即数是指令的一部分,在使用立即数赋值时,CPU直接从机器码中就可以获取数据,不需要从内存中读取相应的值。

变量是存放在内存中,通过变量赋值,CPU必须先从内存中取出,再进行赋值。

32位非立即数却可赋值的情况:

当我们使用MOV R0, #0xFFFFFFFF这个指令时,0xFFFFFFFF是一个32位的数,一定不是一个立即数,但最终编译未出错。具体的编译器处理结果如下:

在这里,编译器将MOV R0, #0xFFFFFFFF 替换成了 MVN R0,#00000000,这个MVN的指令就是CPU可以识别执行的指令,原先的MOV就被称作伪指令。

条件码

条件码就是一个条件,当条件满足时执行这个操作,条件不满足时不执行该操作。

大多数的指令后都可以添加条件,具体示例见"跳转指令" - "2、B"

在使用条件码时,需要先使用CMP进行比较,之后再使用条件码进行条件执行。

条件码如下:

数据处理指令

1、数据搬移指令

1.1 MOV

将指定的数据搬移(赋值)到指定的寄存器中。

格式:

MOV 目标寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源操作数:可以是立即数,也可以是寄存器

示例:

将立即数3搬移到寄存器R1,即:令R1=3

MOV R1, #3     @ #3代表十进制的3,#0x3代表十六进制的3

将R2寄存器的值搬移到寄存器R1,即:令R1=R2

MOV R1, R2

1.2 MVN

将指定的数据按位取反后,搬移(赋值)到指定的寄存器中。

格式: 

MVN 目标寄存器, 源操作数

示例:

将立即数0xFF取反后的值搬移到寄存器R1,即:令R1 = ~0xFF。

注意:这时R1存放的值为0xFFFFFF00,而不是0,因为ARM的寄存器是32位,所以在ARM寄存器中0xFF的存放值是0x000000FF,因此按位取反后为0xFFFFFF00,而不是0。

MVN R1 #0xFF

2、数值运算指令

一般格式:<操作码> <目标寄存器> <第一操作寄存器> <第二操作数>

  • 操作码:执行什么操作,如加减乘除
  • 目标寄存器:用于存放运算结果
  • 第一操作寄存器:必须是一个寄存器,是参与运算的数。
  • 第二操作数:可以是寄存器,也可以是立即数,这也是参与运算的数。

2.1 ADD

加法指令,将指定的两个数进行相加,结果存入指定的寄存器。

格式:

ADD 目标寄存器, 源寄存器, 源操作数

目标寄存器: 可以为通用寄存器R0~R12,也可以是PC

源寄存器:只能是寄存器

源操作数:可以是立即数,也可以是寄存器

示例:

已知R2=5,R3=3,实现R1=R2+R3

MOV R2,#5
MOV R3,#3
ADD R1,R2,R3 @ R1 = R2 + R3

已知R2=5,实现R1=R2+5

MOV R2,#5
ADD R1,R2,#5 @ R1 = R2 + 5
注意:这里不能写成ADD R1,#5,R2 对应ADD只有最后一个为源操作数

2.2 ADC

带进位的加法指令,将指定的两个数进行相加,并且会加上CPSR的进位。 

ADC实现64位运算:

实现:

0x00000001 00000002 + 0x00000003 00000004

思路:

将第一个数的低位和高位分别存放在R1、R2;将第二个数的低位和高位分别存放在R3、R4;将结果的低位和高位分别存放在R5、R6

运算代码:

MOV R1,0x00000002
MOV R2,0x00000001
MOV R3,0x00000004
MOV R4,0x00000003

ADDS R5,R1,R3 @将两个低位相加并允许设置CPSR
ADC R6,R2,R4  @将两个高位相加并加上CPSR的C位(溢出进位)

ADCS实现128位运算:

实现:

0x00000001 00000002 00000003 00000004 + 0x00000005 00000006 00000007 00000008

运算代码:

MOV R1,0x00000004
MOV R2,0x00000003
MOV R3,0x00000002
MOV R4,0x000000
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值