[ARM] ARM指令集

ARM指令集

 

1、ARM指令的格式和分类

经典ARM指令格式以下:性能

<opcode>    {<cond>}    {S}    <Rd>,<Rn>,<operand2>
 
  • <> 为必选项,{}为可选项
  • 为操做码,如ADD表示算术加操做指令
  • {} 决定指令执行条件域
  • {S} 决定指令执行是否影响CPSR寄存器的值
  • 为目的寄存器
  • 的第一个操做数为寄存器
  • 为第二个操做数
 

2、ARM指令条件执行及标志位

  • ARM指令能够经过添加适当的条件码后缀来达到条件执行的目的
    这样能够提升代码密度,减小分支跳转指令数目,提升性能。
    测试

  • 默认状况下,数据处理指令不影响条件码标志位,但能够选择经过添加“S”来影响标志位
    CMP不须要增长 “S”就可改变相应的标志位。
    spa

  • 使用条件码能够实现高效的逻辑操做,节省跳转和条件语句,提升代码效率
    若是指令不标明条件码,将默认为无条件(AL)执行。
    code

  • 条件码表
    blog

 

3、跳转指令

  跳转指令用于实现程序流程的跳转,在ARM程序中有两种方法能够实现程序的跳转,一种是使用跳转指令直接跳转,另外一种是直接向PC寄存器赋值实现跳转。进程

  • B{条件} 目标地址
      B指令最简单的跳转指令,一旦遇到一个B指令,ARM处理器当即跳转至给定的目标地址,由此处继续执行。跳转指令B限制在当前指令的土32MB范围内ip

  • BL{条件} 目标地址
      BL是一另个跳转指令,在跳转前会将下一条指令的地址复制到R14中,而后跳转到指定的地址运行程序。能够经过将R14的内容从新加载到PC中,并返回到跳转指令以后的那个指令处执行。 BL是实现子程序调用的一个基本但经常使用的手段。内存

  • BLX{条件} 目标地址
      BLX指令从ARM指令集跳转到指令中所指定的目标地址,并将处理器的工做状态由ARM状态切换到Thumb状态,该指令同时将PC的当前内容到寄存器R14中。当程序使用Thumb指令集,而调用者使用ARM指令集时,能够经过BLX指令实现程序的调用和处理器工做状态的切换。子程序的返回能够经过将寄存器R14复制到PC中来完成。it

  • BX{条件} 目标地址
      BX指令是带状态切换的跳转指令,跳转到指定的目标地址执行程序。若目标地址寄存器的[0]位为1,则跳转时自动将CPSR中的标志T置位,即把目标地址的代码解释为Thumb指令。若目标地址寄存器的[0]位为0,则跳转时自动将CPSR中的标志T复位,即把目标地址的代码解释为ARM指令。io

 

4、数据处理指令

  • MOV{条件} {S} 目的寄存器,源操做数
    MOV指令能够完成的功能包括:
    • 数据从一个寄存器到另外一个寄存器的传输
    • 将常数传送到寄存器中
    • 实现移位操做,左移位能够实现将操做数乘以2^n
    • 当PC寄存器做为目标寄存器时能够实现程序的跳转
    • 当PC寄存器做为目标寄存器且指令中S位被设置时,指令在执行跳转操做的同时,将当前处理器模式的处理器模式的SPSR寄存器内容复制到CPSR中
MOV    R0,R1
MOVS   R1,R3,LSL,#3
MOV    PC,LR

 

  • MVN{条件} {} 目的寄存器,源操做数
      MVN指令可完成从另外一个寄存器、被移位的寄存器或将一个当即数加载到目的寄存器。与MOV指令不一样之处是在传送以前按位被取反了,即把一个被取反的值传送到目的寄存器中。其中S决定指令的操做是否影响CPSR中条件标志位的值,当没有S时指令不更新CPSR中条件标志位的值。由于其具备取反功能,因此能够装载范围更广的当即数。
MVN    R1,#0xFF
MVN    R1,R2
MVN    R0,#0

 

 

  • ADD{条件} {S} 目的寄存器,操做数1,操做数2
      ADD指令用于把两个操做数相加,并将结果存放到目的寄存器中,同时根据操做的结果更新CPSR中相应的条件标志位
ADDS   R1,R1,#1
ADD    R1,R1,R2
ADD    R0,R2,R3,LSL,#1

 
  • SUB{条件} {S} 目的寄存器,操做数1,操做数2
      SUB指令用于把操做数1减去操做数2,并将结果存放在目的寄存器中,同时根据操做的结果更新CPSR中相应的条件标志位。该指令可用于有符号数或无符号数据减法运算。
SUB     R0,R0,#1
SUBS   R0,R1,R2
SUB     R0,R2,R3,LSL,#1

 
  • RSB{条件} {S} 目的寄存器,操做数1,操做数2
      RSB指令称为逆向减法指令,用于把操做数2,减去操做数1,并将结果存放到目的寄存器中,同时根据操做的结果更新CPSP中相应的条件标志位。该指令可用于有符号数或无符号数据减法运算。
RSB    R3,R1,#0xFF00
RSB    R0,R2,R3,LSL,#1
RSB    R0,R1,#0 

 
  • ADC{条件} {S} 目的寄存器,操做数1,操做数2
      ADC指令用于把两个操做数相加,再加上CPSR中的C条件标志位的值,并将结果存放到目的寄存器中。同时根据操做的结果更新CPSR中相应的条件标志位。它使用一个进位标志位,这样就能够作比32位大的数据加法,注意不要忘记S后缀来更改进位标志。操做数1应是一个寄存器,操做数2能够是寄存器、被移位的寄存器或一个当即数。
ADDS   R0,R0,R2
ADC     R1,R2,R3

 
  • SBC{条件} {S} 目的寄存器,操做数1,操做数2
      SBC指令用于把操做数1减去操做数2,再减去CPSR中的C条件标志位的反码,而后将结点存放到目的寄存器中。同时根据操做的结果更新CPSR中相应的条件标志位。该指令使用进位标志来表示借位,这样就能够作大于32位的减法。注意不要忘记设置S后缀来更改进位标志,该指令可用于有符号数或无符号数据减法运算。
SUBS  R0,R0,R2
SUB   R1,R1,R3

 
  • RSC{条件} {S} 目的寄存器,操做数1,操做数2
      RSC指令用于把操做数2减去操做数1,再减去CPSR中的C条件标志位的反码,并将结果存放到目的寄存器中。同时根据操做的结果更新CPSR中相应的条件标志位。该指令使用进位标志来表示借位,这样就能够作大于32位的减法。注意不要忘记设置S后缀来更改进位标志,该指令可用于有符号数或无符号数据减法运算。
RSBS   R2,R0,#0
RSC    R3,R1,#0
RSC    R0,R1,R2

 
  • AND{条件} {S} 目的寄存器,操做数1,操做数2
      AND指令用在两个操做数上进行逻辑与运算,并把结果存放到目的寄存器中。同时根据操做的结果更新CPSR中相应的条件标志位,该指令学用于屏蔽操做数1的某些位。
AND   R0,R0,#3
AND   R2,R1,R3

 
  • ORR{条件} {S} 目的寄存器,操做数1,操做数2
      ORR指令用在两个操做数上进行逻辑或运算,并把结果旋转到目的寄存器中。同时根据操做的结果更新CPSR中相应的条件标志位,该指令经常使用于设置操做数1的的某些位。
ORR     R0,R0,#3
MOV    R1,R2,LSR,#4
ORR     R3,R1,R3,LSL,#4

 
  • EOR{条件} {S} 目的寄存器,操做数1,操做数2
      EOR指令用在两个操做数上进行逻辑异或运算,并把结果放置到目的寄存器中。同时根据操做的结果更新CPSR中相应的条件标志位,该指令经常使用于反转操做数1的某些位。
EOR    R1,R1,#0x0F
EOR    R2,R1,R0
EORS   R0,R5,#0x01

 
  • BIC{条件} {S} 目的寄存器,操做数1,操做数2
      BIC指令用于清除操做数1的某些位,并把结果放置到目的寄存器中。同时根据操做的结果更新CPSR中相应的条件标志位。操做数2为32位的掩码,若是在掩码中设置了某一位,则清除这一位,未设置掩码位保持不变。
BIC    R0,R0,#%1011
BIC    R1,R1,#0x0F
BIC    R1,R2,R3

 
  • CMP{条件} 操做数1,操做数2
      CMP指令用于把一个寄存器的内容和另外一个寄存器的内容或当即数进行比较,同时更新CPSR中的条件标志位的值。该指令进行一次减法运算,但不存储结果,只更改条件标志位,标志位表示的是操做数1与操做数2的关系。若是操做数1大于操做数2,则此后GT后缀的指令将执行,不需显示的指定S后缀更改状态标志,若是指定了则忽略。

  • CMN{条件} 操做数1,操做数2
      CMN指令用于把一个寄存器的内容和另外一个寄存器的内容或当即数据取反后进行比较。同时更新CPSR中条件标志位的值,该指令实际完成操做数1和操做数2相加,并根据结果更改条件标志位。CMN指令与ADD指令的区别在于CMN指令不保存运算结果。

CMN    R1,R0
CMN    R1,#100

 
  • TST{条件} 操做数1,操做数2
      TST指令用于把操做数1的内容和操做数的内容进行按位与运算,并根据运算结果更新CPSR中条件标志位的值。操做数1是要测试的数据,而操做数2是一个位掩码,该指令通常用来检测是否设置了特定的位。
TST    R0,#0x01
TST    R0,#0x0F    

 
  • TEQ{条件} 操做数1,操做数2
      TEQ指令用于把操做数1的内容和操做数的内容进行按位异或运算,并根据运算结果更新CPSR中条件标志位的值。该指令一般用于比较操做数1和操做数2是否相等。
TEQ    R1,R2
 

 

5、程序状态寄存器传输指令

  ARM指令有两条指令用于状态寄存器和通用寄存器之间传送数。修改寄存器通常是经过 “读取-修改-写回” 三个步骤的操做来实现的。这两指令分别是状态寄存器到通用寄存器的传送指令MRS,通用寄存器到状态寄存器的传送指令MSR。

  • MRS{条件} 通用寄存器,程序状态寄存器
      当异常中断容许被嵌套时,须要在进入异常中断后嵌套中断发生以前的保存当前处理器对应的SPSR。在进程切换时也须要保存当前状态寄存器的值。
MRS    R0,CPSR
MRS    R0,SPSR

 
  • MSR{条件} 程序状态寄存器_<域>,通用寄存器
      当退出异常中断处理程序时,若是事先有保存状态寄存器的内容,一般使用MSR将事先保存的数据恢复到状态寄存器中。域用于设置程序状态寄存器中须要操做的位,32位的程序状态寄存器可分为4个域:
    • [31:24] 为条件标志位域,用f表示
    • [23:16] 为状态位域,用s表示
    • [15:8] 为扩展位域,用x表示
    • [7:0] 为控制位域,用c表示
MSR   CPSR_c,#0xD3
MSR   CPSR_cxsf,R3
 

 

6、Load与Store指令

  Load指令用于从内存中读取数据放入寄存器中,Store指令用于将寄存器中的数据保存到内存。

  • LDR{条件} 目的寄存器,<存储器地址>
      LDR指令用于从存储器中将一个32位的数据传送到目的寄存器中。当程序计数器PC做为目的寄存器时,指令从存储器中读取的数据被目的地址,从而实现程序流程的跳转。
LDR    R0,#8
LDR    R0,[R1,R2]
LDR    R0,[R1, 8] 

 
  • STR{条件} 源寄存器,<存储器地址>
    STR指令用于从源寄存器中将一个32位数据传送到存储器中。
STR    #8,R0
STR    R0,[R1,#8]    

 
  • LDM/STM{条件} {类型} 基址寄存器,寄存器列表
      LDM和STM能够实如今一组寄存器和一块连续的内存单元之间传输数据。LDM为加载多个寄存器,STM为存储多个寄存器。LDM、STM的主要用途是现场保存,数据复制,参数传递,其模式有8种:
    • 用于数据块传输
      IA 每次传送后地址加4
      IB 每次传送前地址加4
      DA 每次传送后地址减4
      DB 每次传送前地址减4
    • 用于堆栈操做
      FD 满递减堆栈
      ED 空递减堆栈
      FA 满递增堆栈
      EA 空递增堆栈
STMFD    R13,{R0,R4-R12,LR}
DMFD    R13,{R0,R4-R12,LR}

 
  • SWP {条件} 目的寄存器,源寄存器1,[源寄存器2]
      SWP指令用于将源寄存器2中的把指向的存储器中的数据传送到目的寄存器中。同时将源寄存器1中的数据传送到源寄存器2所指向的存储器中。当源寄存器1和目的寄存器为同一寄存器时,指令将交换目的寄存器和存储器的内容。

 

七、异常中断产生指令

SWI,即software interrupt软件中断。该指令产生一个SWI异常。意思就是处理器模式改变为超级用户模式,CPSR寄器保存到超级用户模式下的SPSR寄存器,而且跳转到SWI向量。

  指令格式以下:SWI{cond} immed_24
  Cond域:是可选的条件码 (参见 ARM汇编指令条件执行详解).
  immed_24域:范围从 0 到 224-1 的表达式, (即0-16777215)。用户程序可使用该常数来进入不一样的处理流程。

相关文章
相关标签/搜索