ARM体系架构—ARMv7-A指令集:数据处理指令

ARM体系架构—ARMv7-A指令集

  • 一、ARMv7-A指令集
  • 二、ARMv7-A条件码
  • 三、ARMv7-A数据处理指令
    • 3.1算术运算和逻辑运算指令
    • 3.2比较指令
    • 3.3第二操作数
      • 3.3.1立即数
      • 3.3.2寄存器移位
    • 3.4乘法指令

一、ARMv7-A指令集

ARMv7-A架构是32位处理器架构。也是load/store架构,即数据处理指令操作在通用寄存器完成,只有load/store指令可以访问内存。此外ARM指令集还有一大特点,就是ARM指令集几乎所有的指令都可以增加条件码。
ARM指令集可以归为一下四类:

  1. 数据处理操作(ALU操作例如ADD);
  2. 内存操作(load/store);
  3. 控制流(循环,跳转,条件码等);
  4. 系统(协处理器,debug,模式切换等等)。

本文重点介绍数据处理指令。

二、ARMv7-A条件码

ARM指令集的一个特性是几乎所有的指令都可以增加条件码(绝大多数其他处理器架构中,只有跳转指令可以加条件码),以利用CPSR(Current Program Status Register)寄存器中的状态位。在简单的if/then/else结构中,这一特性对于避免条件分支或复合比较非常有用。
举例说明条件码的好处(两个值找到较小的):

if (a < b)
	n = a;
else
    n = b;

无条件码汇编:
ARM体系架构—ARMv7-A指令集:数据处理指令_第1张图片
有条件码汇编:
ARM体系架构—ARMv7-A指令集:数据处理指令_第2张图片
MOV是算术运算指令,功能是将第二操作数传送到目标寄存器。
其后增加了条件码GE和LT,GE(greater than or equal)表示CMP比较结果是大于等于,LT(less than)表示CMP比较结果是小于。因而三条指令实现了相同的功能。

ARM指令集中条件码如下图所示。
ARM体系架构—ARMv7-A指令集:数据处理指令_第3张图片
条件指令码中(Z)ero, (N)egative, (C)arry, o(V)erflow状态位是CPSR寄存器中的4个bit位,如下图所示,[31:27]4个bit分别对应N,Z,C,V,其含义如下表。关于CPSR的说明可以参看 《ARM体系架构—ARMv7-A处理器模式及寄存器》.
CPSR bits

Field 作用
N ALU返回运算结果是否为负数
Z ALU返回运算结果是否为0
C ALU运算是否发生进位
V ALU运算是否发生溢出

三、ARMv7-A数据处理指令

ARM core只能在寄存器上执行数据处理,而不能直接在内存上执行。
数据操作指令一般由一个目标寄存器和两个源操作数组成,所有ARM数据处理指令都可以加后缀(Suffix),并影响状态标志(CPSR)。其基本格式如下:
O p e r a t i o n { c o n d } { S } R d , R n , O p e r a n d 2 Operation \{cond\} \{S\} Rd, Rn, Operand2 Operation{cond}{S}Rd,Rn,Operand2

  • Operation : 指令助记符;
  • cond: 执行条件;
  • S:后缀,是否影响CPSR寄存器状态位;
  • Rd:目标寄存器;
  • Rn:第一个操作数寄存器;
  • Operand2:第二个操作数;
  • {}:可选。

数据操作指令可分为如下两类:

  1. 算术运算和逻辑运算指令;
  2. 比较指令。

3.1算术运算和逻辑运算指令

算术运算和逻辑运算指令增加后缀S可以影响CPSR寄存器的状态位。
ARM体系架构—ARMv7-A指令集:数据处理指令_第4张图片

  • MOV
    将立即数或寄存器值(Operand2)传送到目标寄存器(Rd)。
  • MVN
    将立即数或寄存器值(Operand2)按位取反传送到目标寄存器(Rd)。
  • ADD
    将立即数或寄存器值(Operand2)与第一操作数寄存器(Rn)相加,结果保存到目标寄存器(Rd)。
  • ADC
    将立即数或寄存器值(Operand2)与第一操作数寄存器(Rn)相加,再加上CPSR中C标志位,结果保存到目标寄存器(Rd)。
    ADC实现64位加法(结果存放到R1,R0):
C:
int64 a = 0x1FFFFFFFF;
int64 b = 0x100000001;
int64 c = a + b;
ASM:
MOV   R0, 0xFFFFFFFF ;R0存放变量a低32bit数据
MOV   R2, 0x00000001 ;R2存放变量b低32bit数据
MOV   R1, 0x1        ;R1存放变量a高32bit数据
MOV   R3, 0x1        ;R3存放变量b高32bit数据
ADDS  R0, R0, R2     ;R0 = R0 + R2, 发生进位C = 1, 计算结果低32存放到R0
ADC   R1,R1,R3       ;R1 = R1 + R3 + C,  计算结果高32存放到R1
  • SUB
    第一操作数寄存器(Rn)减去立即数或寄存器值(Operand2),结果保存到目标寄存器(Rd)。
  • SBC
    第一操作数寄存器(Rn)减去立即数或寄存器值(Operand2),再减去CPSR中C标志位取反,结果保存到目标寄存器(Rd)。
    SBC实现64位加法(结果存放到R1,R0):
C:
int64 a = 0x100000000;
int64 b = 0x000000001;
int64 c = a - b;
ASM:
MOV   R0, 0x0        ;R0存放变量a低32bit数据
MOV   R2, 0x1        ;R2存放变量b低32bit数据
MOV   R1, 0x1        ;R1存放变量a高32bit数据
MOV   R3, 0x0        ;R3存放变量b高32bit数据
SUBS  R0, R0, R2     ;R0 = R0 - R2, 发生借位C = 0, 计算结果低32存放到R0
SBC   R1,R1,R3       ;R1 = R1 - R3 - !C,  计算结果高32存放到R1
  • RSB
    立即数或寄存器值(Operand2)减去第一操作数寄存器(Rn),结果保存到目标寄存器(Rd)。
    显然等效于SUB R0,#100,R1,但是SUB这条指令是不合法的,因而引入RSB指令。
  • RSC
    立即数或寄存器值(Operand2)减去第一操作数寄存器(Rn),再减去CPSR中C标志位取反,结果保存到目标寄存器(Rd)。
  • AND
    立即数或寄存器值(Operand2)和第一操作数寄存器(Rn)按位“”操作,结果保存到目标寄存器(Rd)。
  • ORR
    立即数或寄存器值(Operand2)和第一操作数寄存器(Rn)按位“”操作,结果保存到目标寄存器(Rd)。
  • EOR
    立即数或寄存器值(Operand2)和第一操作数寄存器(Rn)按位“异或”操作,结果保存到目标寄存器(Rd)。
  • BIC
    第一操作数寄存器(Rn)和立即数或寄存器值(Operand2)的反码按位“”操作,结果保存到目标寄存器(Rd)。

3.2比较指令

比较指令会影响CPSR寄存器的状态位。
ARM体系架构—ARMv7-A指令集:数据处理指令_第5张图片

  • CMP
    第一操作数寄存器(Rn)减去立即数或寄存器值(Operand2)的值,根据结果更新CPSR寄存器的标志位。
  • CMN
    第一操作数寄存器(Rn)加上立即数或寄存器值(Operand2)的值,根据结果更新CPSR寄存器的标志位。
  • TST
    第一操作数寄存器(Rn)和立即数或寄存器值(Operand2)的值按位做“与”操作,根据结果更新CPSR寄存器的标志位。
  • TEQ
    第一操作数寄存器(Rn)和立即数或寄存器值(Operand2)的值按位做“异或”操作,根据结果更新CPSR寄存器的标志位。

3.3第二操作数

ARM数据处理指令基本格式中第一操作数是寄存器,第二操作数Operand2可以是寄存器(Rm),也可以是立即数(#x),也可以是寄存器移位( “Rm, shift #x” or “Rm, shift Rs”)。

3.3.1立即数

ARM指令集第二操作数为立即数时,ARM指令编码如下图所示。
在这里插入图片描述

  • [31:28]cond :指令条件码(EQ,NE等);
  • [24:20]op:指令操作码(ADD,SUB等);
  • [25]:二进制1表示立即数;
  • [19:16]Rn:目标寄存器;
  • [11:0]:立即数。

由该指令编码可以看出ARMv7指令只留给立即数12bit空间。12bit立即数的范围是[-2048,2047],为了使指令中的立即数范围更广,ARM将12bit立即数做了划分:[7:0]8bit是立即数(immediate),[11:8]4bit是循环位(rotation)。如下图所示,a-h即表示立即数,rotation即表示循环位。立即数的范围是[0,0xFF],循环位的范围是[0,15]。
在这里插入图片描述
循环位值表示将立即数循环右移偶数位。具体移位方式如下图所示,图中const一列以二进制表示。
当rotation=0时,表示立即数不移位。
当rotation=1时,表示立即循环右移两位。
当rotation=N时,表示立即循环右移2*N位(N<16)。
ARM体系架构—ARMv7-A指令集:数据处理指令_第6张图片

3.3.2寄存器移位

第二操作数除了可以是立即数外,还可以是寄存器(Rm),寄存器移位( “Rm, shift #x” or “Rm, shift Rs”)。
寄存器方式不再介绍,本节介绍寄存器移位方式。
寄存器移位的方式有五种:

  1. LSL:逻辑左移;
  2. LSR:逻辑右移;
  3. ASR:算术右移;
  4. ROR:循环右移;
  5. RRX:带扩展循环右移。

第二操作数举例:
ARM体系架构—ARMv7-A指令集:数据处理指令_第7张图片

3.4乘法指令

需要注意的是ARM乘法指令集,不能操作立即数,只能对寄存器中的值进程操作。
ARM乘法指令如下图所示。
ARM体系架构—ARMv7-A指令集:数据处理指令_第8张图片

  • MLA:32位乘加指令。将寄存器Rm和Rn相乘,再加上第三个操作数寄存器Ra,将结果的低32位保存到Rd;
  • MLS:32位乘减指令。将寄存器Rm和Rn相乘,再由第三个操作数寄存器Ra将去乘积,将结果的低32位保存到Rd;
  • MUL:32位乘法指令。将寄存器Rm和Rn相乘,将结果的低32位保存到Rd;
  • SMLAL:64位有符号乘加指令。有符号32位数Rn和Rm乘积,结果与RdHi和RdLo相加,低32位保存到RdLo,高32位保存到RdHi;
  • SMULL:64位有符号乘法指令。有符号32位数Rn和Rm乘积,结果低32位保存到RdLo,高32位保存到RdHi;
  • UMLAL:64位无符号乘加指令。32位数Rn和Rm做无符号乘积,结果与RdHi和RdLo相加,低32位保存到RdLo,高32位保存到RdHi;
  • UMULL:64位无符号乘法指令。32位数Rn和Rm做无符号乘积,结果低32位保存到RdLo,高32位保存到RdHi;

除了以上常见的乘法指令外,ARM提供了用于保存乘法结果高32的指令:SMMUL, SMMLA and SMMLS。

  • SMMUL:32位高位有效有符号乘法指令。有符号32位数Rn和Rm乘积,提取结果中的高32位保存到目标寄存器Rd;
  • SMMLA :32位高位有效有符号乘减指令。有符号32位数Rn和Rm乘积,再减去左移32位后的第三个操作数寄存器,提取结果中的高32位保存到目标寄存器Rd。

你可能感兴趣的:(ARM体系架构)