ARM 指令集摘要

ARM 指令集摘要

简介: ARM指令系统一般有Thumb指令集和ARM指令集。

Thumb: 指令集具有灵活、小巧的特点,是16位的

ARM:指令集支持ARM核所有的特性,具有高效、快速的特点,是32位的

 

一 寻址方式

a) 寄存器寻址(操作数的值在寄存器中) 

   mov r1, r2   // r1 = r2

b) 立即寻址(操作数在指令中)

   mov r1, #0xff00   //r1 = 0xff00

c) 寄存器移位寻址(2个操作数是寄存器移位方式)

   mov r1, r2, lsl  #3   //r1 = r2  << 3

d) 寄存器简介寻址(2个寄存器中给出的是操作数的地址)

   ldr r0, [r2]    //r0 = [r2]

e) 基址寻址(将基址寄存器的值和指令中的偏移相加得到操作数的地址)

   ldr r0, [r1, #0x0c]  //r0 = [r1 + 0x0c]

f) 多寄存器寻址(一次可以最多传送16个寄存器的值)

   ldmia r1!, {r2-r4, r6}   // r2 = [r1], r1 = r1 + 4, r3 = [r1], ……

g) 堆栈寻址(先进后出)

满递增:堆栈向上增长,堆栈指针指向内含有效数据项的最高地址。指令如LDMFASTMFA等;

空递增:堆栈向上增长,堆栈指针指向堆栈上的第一个空位置。指令如LDMEASTMEA

满递减:堆栈向下增长,堆栈指针指向内含有效数据项的最低地址。指令如LDMFDSTMFD

空递减:堆栈向下增长,堆栈指针向堆栈下的第一个空位置。指令如LDMEDSTMED

h) 块拷贝寻址

STMIA   R0!,{R1-R7} ;R1R7的数据保存到存储器中。

                      ;存储指针在保存第一个值之后增加,;增长方向为向上增长

STMIB   R0!,{R1-R7} ;R1R7的数据保存到存储器中。

                     ;存储指针在保存第一个值之前增加,;增长方向为向上增长。

 

i)  相对寻址: 相对寻址是基址寻址的一种变通。由程序计数器PC提供基准地址,指令中的地址码字段作为偏移量,两者相加后得到的地址即为操作数的有效地址。

bl / beq

 

CPSR(程序状态寄存器)格式

     31 30 29 28 27 ……    8  7 6  5  4   3   2   1    0

    +--+--+--+--+----------------- +--+--+--+----+-----+----+-----+-----+-

| N | Z | C | V| - | - | ……. -| - | I | F | T | M4| M3 | M2 | M1 | M0 |

    +--+--+--+--+-----------------+--+--+--+----+-----+----+-----+-----+-

N: 当用两个补码表示的带符号数进行运算时N=1表示运算结果为负数; N=0表示结果为正或0

Z: Z = 1 表示运算结果为0, Z = 0 表示运算结果为非0

C: 4中方法设置C,  1) 加法运算: 当结果产生进位时C=1,否则C=0;  2) 减法运算: 当运算产生借位时C=0,否则C=1;  3)对于移位操作, C为移出值的最后一位;  4) 对于其他指令, C的值通常不变.

V: 对于加减运算, 当操作数和结果为2进制补码表示的带符号数时,V=1表示符号为溢出.

I:  I=1   禁止IRQ中断

F:  F=1  禁止FIQ中断

T  T=1  运行于Thumb状态,  否则运行于ARM状态

M[4:0]:  1)  0b10000 用户模式   PC, CPSR, R0-R14  2)

        2)  0b10001  FIQ模式  PC, CPSR, SPSR_fiq, R0- R7, R8_fiq – R14_fiq

        3)  0b10010  IRQ模式  PC, CPSR, SPSR_irq, R0- R12, R13_irq – R14_irq

        4)  0b10011  管理模式  PC, CPSR, SPSR_svc R0- R12, R13_svc – R14_svc

        5)  0b10111  终止模式  PC, CPSR, SPSR_abt, R0- R12, R13_abt – R14_abt

        6)  0b11011  未定义模式  PC, CPSR, SPSR_und, R0- R12, R13_und – R14_und

        7)  0b11111  系统模式  PC, CPSR, R0- R14

 

三 指令集   

1 格式: <opcode>{<cond>}{s} <rd>, <rn>{<operand2>}

opcode:指令助记符;  cond:执行条件;        S:是否影响CPSR寄存器的值;

Rd:目标寄存器;       Rn:第1个操作数的寄存器;      operand2:第2个操作数;

 

灵活的使用第2个操作数operand2能够提高代码效率。它有如下的形式:

§        #immed_8r——常数表达式;

§        Rm——寄存器方式;

§        Rm,shift——寄存器移位方式;

常数格式必须为8位常数循环右移偶数位的值. 

 移位方法有:

操作码

说明

操作码

说明

ASR  #n

算术右移n            

ROR  #n

循环右移n

LSL  #n

逻辑左移n

RRX

带扩展的循环右移1

LSR  #n

逻辑右移n

Type  Rs

Type为移位的一种类型,Rs为偏移量寄存器,低8位有效。

 

所有的ARM指令都可以条件执行,而Thumb指令只有B(跳转)指令具有条件执行功能。如果指令不标明条件代码,将默认为无条件(AL)执行

操作码

条件助记符

标志

含义

0000

EQ

Z=1

相等

0001

NE

Z=0

不相等

0010

CS/HS

C=1

无符号数大于或等于

0011

CC/LO

C=0

无符号数小于

0100

MI

N=1

负数

0101

PL

N=0

正数或零

0110

VS

V=1

溢出

0111

VC

V=0

没有溢出

1000

HI

C=1,Z=0

无符号数大于

1001

LS

C=0,Z=1

无符号数小于或等于

1010

GE

N=V

有符号数大于或等于

1011

LT

N!=V

有符号数小于

1100

GT

Z=0,N=V

有符号数大于

1101

LE

Z=1,N!=V

有符号数小于或等于

1110

AL

任何

无条件执行 (指令默认条件)

1111

NV

任何

从不执行(不要使用)

 

2 指令集:

a)存储器访问指令

 1 单寄存器存取

LDR/STR指令用于对内存变量的访问、内存缓冲区数据的访问、查表、外围部件的控制操作等。若使用LDR指令加载数据到PC寄存器,则实现程序跳转功能,这样也就实现了程序散转。

 

助记符

说明

操作

条件码位置

LDR    Rd
,addressing

加载字数据

Rd[addressing]addressing索引

LDR{cond}

LDRB Rd
,addressing

加载无符号字节数据

Rd[addressing]addressing索引

LDR{cond}B

LDRT Rd
,addressing

以用户模式加载字数据

Rd[addressing]addressing索引

LDR{cond}T

LDRBT Rd
, addressing

以用户模式加载无符号字节数据

Rd[addressing]addressing索引

LDR{cond}BT

LDRH   Rd
, addressing

加载无符号半字数据

Rd[addressing]addressing索引

LDR{cond}H

LDRSB  Rd
, addressing

加载有符号字节数据

Rd[addressing]addressing索引

LDR{cond}SB

LDRSH  Rd
, addressing

加载有符号半字数据

Rd[addressing]addressing索引

LDR{cond}SH

 

助记符

说明

操作

条件码位置

STR  Rd
, addressing

存储字数据

[addressing]Rd

addressing索引

STR{cond}

STRB Rd
,addressing

存储字节数据

[addressing]Rd

addressing索引

STR{cond}B

STRT Rd
,addressing

以用户模式存储字数据

[addressing]Rd

 addressing索引

STR{cond}T

STRBT Rd
,addressing

以用户模式存储字节数据

[addressing]Rd

addressing索引

STR{cond}BT

STRH Rd
,addressing

存储半字数据

[addressing] Rd

addressing索引

STR{cond}H

LDR    R2,[R5]    ;R5指向地址的字数据存入R2

ldr    rd, [rd1], #0x04   // rd = [rd1], rd1 = rd1 + 0x04

STR    R1,[R0,#0x04]  ;R1的数据存储到R0+0x04地址

str    rd, [rd1], #4    // [rd1] = rd, rd1 = rd1 + 4

LDRB   R3,[R2],#1     ;R2指向地址的字节数据存入R3R2R2+1

STRB   R6,[R7]        ;R7指向地址的字节数据存入R6

LDRSB  R1,[R0,R3]    ;R0+R3地址上的字节数据存入R1,高24位用符号扩展

LDRH   R6,[R2],#2    ;    ;R2指向地址的半字数据存入R6,高16位用0扩展读出后,R2=R2+2

STRH   R1,[R0,#2]!   ;R1的半字数据保存到R0+2地址,只修改低2字节数据,R0=R0+2

str    r1, [r0, #2]!     ;( [r0 + 2] = r1, r0 = r0 + 2) 

 

2.     多寄存器操作

多寄存器加载/存储指令可以实现在一组寄存器和一块连续的内存单元之间传输数据。LDM为加载多个寄存器;STM为存储多个寄存器。允许一条指令传送16个寄存器的任何子集或所有寄存器。它们主要用于现场保护、数据复制、常数传递等

LDM{cond}<mode> Rn{!}, reglist{^}  //多寄存器加载  reglist ß [Rn…], 

 STM{cond}<mode> Rn{!}, reglist{^}   //多寄存器存储  [Rn…] ß reglist 

 

 cond为条件码,  mode为控制地址的增长方式, !表示在操作结束后,将结果写回Rn, ^为当进行数据传送且寄存器列表不含pc,加载/存储的寄存器是用户模式下的, 若在LDM下使用PC,则除正常的寄存器操作外,还将SPSR拷贝到CPSR(它不能用在用户和系统模式下), reglist :表示寄存器列表,可以包含多个寄存器,它们使用“,”隔开,如{R1,R2,R6-R9},寄存器由小到大排列;

mode:

模式

说明

模式

说明

IA

每次传送后地址加4

FD

满递减堆栈

IB

每次传送前地址加4

ED

空递减堆栈

DA

每次传送后地址减4

FA

满递增堆栈

DB

每次传送前地址减4

EA

空递增堆栈

数据块传送操作

堆栈操作

进行数据复制时,先设置好源数据指针和目标指针,然后使用块拷贝寻址指令LDMIA/STMIALDMIB/STMIBLDMDA/STMDALDMDB/STMDB进行读取和存储 。

    进行堆栈操作操作时,要先设置堆栈指针(SP),然后使用堆栈寻址指令STMFD/LDMFD STMED/LDMEDSTMFA/LDMFASTMEA/LDMEA实现堆栈操作。

    STMDA  r0!, {r5-r6}   … LDMIB r0!, {r5-r6}

STMED r0!, {r5, r6}   …. LDMED r0!, {r5-r6}

 

b) 寄存器和存储器交换指令

SWP{cond}{B}  Rd, Rm, [Rn]   Rd ß[Rn] , [Rn] ß Rm

swp  r1, r1, [r0] R1的内容与R0指向的存储单元的内容进行交换

swpb r1, r2, [r0] R0指向的存储单元的内容读取一个字节存入R1,并将R2的内容写入该内存单元

 

c) 数据处理指令

1 数据传送

  MOV{cond}{S} Rd, operand2    Rd ß operand2        mov r1, #0x10  /   movs r3, r1, lsl, #2

  MVN{cond}{s} Rd, operand2    Rd ß (~operand2)      mvn r1, #0xff    ; r1=0xffffff00

2 算术指令

ADD{cond}{S} Rd, Rn, operand2  ;Rd ßRn+operand2  add r1, r1, r2 ; r1 = r1 + r2

SUB{cond}{S} Rd, Rn, operand2  ;Rd ß Rn – operand2  subs r0, r0, #1  ; r0 = r0 – 1

RSB{cond}{S} Rd, Rn, operand2  ;Rd ßoperand2 –Rn  rsb r3, r1, #0xff00   ; r3 = 0xff00 – r1

ADC{cond}{S} Rd, Rn, operand2  ;Rd ß Rn + operand2 + Carry adc r1, r1, r3  ; r1 = r1 + r3 +进位标志

SBC{cond}{S} Rd, Rn, operand2  ;Rd ßRn – operand2 – (Not)Carry sbc r1, r1, r3; r1=r1–r3–借位标志

  RSC{cond}{S} Rd, Rn, operand2  ;Rd ßoperand2 – Rn – (Not)Carry rsc r3, r1, #0

3 逻辑运算指令

  AND{cond}{s} Rd, Rn, operand2  Rd ßRn & operand2   and r2, r1, r3  ; r2 = r1 & r3

  ORR{cond}{s} Rd, Rn, operand2  Rd ß Rn |operand2  orr r0, r0, #0x0f  ; r0 = r0 | 0x0f

  EOR{cond}{s} Rd, Rn, operand2  Rd ß Rn ^ operand2 eor r1, r1, #0x0f  ; r1 = r1 ^ 0x0f

  BIC{cond}{s} Rd, Rn, operand2  Rd ß Rn &( ~operand2) bic r1, r1, #0x0f  ;R1的低4位清0

4 比较指令

  CMP{cond}  Rn, operand2  标志N,Z,C,V ß Rn – operand2  cmp r1, #10 ;R110比较,设置相关标志位

  CMN{cond}  Rn, operand2  标志N,Z,C,V ß Rn + operand2  cmn r1, #1   ;R0+1,判断R0是否为1的补码

如果是,则设置Z标志位

  TST{cond}  Rn, operand2  标志N,Z,C,V ß Rn & operand2  tst r1, #0x01 ;判断R0的最低位是否为0

  TEQ{cond}  Rn, operand2  标志N,Z,C,V ß Rn ^ operand2  teq r0, r1    ;比较R0R1是否相等 (不影响V位和C)

5 乘法指令

1  32位乘法

MUL{cond}{s}  Rd, Rm, Rs  Rd ßRm * Rs (Rd != Rm)     Mul r1, r2, r3  ; r1 = r2 * r3

MLA{cond}{s}  Rd, Rm, Rs,Rn  Rd ßRm * Rs + Rn (Rd != Rm)     Mla r1, r2, r3, r0  ; r1 = r2 * r3 + r0
2  64

UMULL{cond}{s}  RdLo, RdHi, Rm,Rs   (RdLo.RdHi) ß Rm * Rs   Umull r0, r1, r5, r8  ;(r1,r0) = r5 * r8

UMLAL{cond}{s}  RdLo, RdHi, Rm,Rs   (RdLo.RdHi) ß Rm * Rs +(RdLo.RdHi)    

umlal r0, r1, r5, r8  ;(r1,r0) = r5 * r8 + (r1, r0)

SMULL{cond}{s}  RdLo, RdHi, Rm,Rs   (RdLo.RdHi) ß Rm * Rs   Smull r2,r3, r7, r6  ;(r3,r2) = r7 * r6

SMLAL{cond}{s}  RdLo, RdHi, Rm,Rs   (RdLo.RdHi) ß Rm * Rs +(RdLo.RdHi)   

smlal r2, r3, r7, r6  ;(r3,r2) = r7 * r6 + (r3, r2)

d) 分支指令

B{cond} Label    PCß label     B WAITA  ;跳转到WAITA标号处

BL{cond} Label   LRßPC – 4, PC ß label  ;BL  delay  ;调用子程序delay,delay结束会后将lr存入PC,即返回

BX{cond} Rm    PCßRm, 切换处理器状态(通过Rm[0]指示)   BX  R0;跳转到R0,并根据R0的最低位来切换处理器状态

e) 协处理器指令

CDP{cond} coproc, opcode1, CRd, CRn, CRm{, opcode2}   //通知协处理器执行特定的操作

CDP p7,0,c0,c2,c3,0   ;对协处理器7操作,操作码为0,可选操作码为0     

LDC{cond}{L}  coproc, CRd, <地址>  数据读取指令

        LDC    p5,c2,[R2,#4]   ;读取R2+4指向的内存单元的数据,传送到协处理器p5c2寄存器中

 STC{cond}{L}  coproc, CRd, <地址>  数据存储指令

         STC   p5,c1,[R0]     ;将协处理器p5C1寄存器内数据传送到R0指向的内存单元

MCR{cond}  coproc,opcode1, Rd, CRn, CRm{,opcode2}  //寄存器间数据交换(ARM à 协处理器)

MCR p6,2,R7,c1,c2    ;ARM中的R7寄存器内容传递到协处理器6C1C2寄存器

MRC{cond}  coproc,opcode1, Rd, CRn, CRm{,opcode2}  //寄存器间数据交换(协处理器à ARM)

       MRC p5,2,R2,c3,c2     ;将协处理器5C3C2寄存器内容传递到ARM中的R2寄存器

 

f) 杂项指令

 SWI{cond} immed_24  产生软中断,处理器进入管理模式,并且将CPSR保存到管理模式的SPSR

        SWI    12         ;调用12号软中断

 MRS{cond} Rd, psr  Rd ß psr  psrCPSR,SPSR

              MRS    R1,CPSR   ; CPSR状态寄存器读取,保存到R1

 MSR{cond} psr_fields, Rd  /  immed_8r    psr_fields ßRd / immed_8r,  

fields:c(psr[7..0]), x(psr[15..8]), s(psr[23…16]), f(psr[31…24])的一个组合


g)
伪指令

  ADR{cond}  register, expr   //将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中

      ADR  R0,  delay   ; 将标号delay的地址存入R0

……    

Delay

        Mov r0, r14
  
    ADRL{cond}  register, expr   //
将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,ADR可以读取更大范围的地址, 用法同ADR

 LDR{cond}  register, =expr  //用于加载32位的立即数或一个地址值到指定寄存器

       LDR  R0,  =delay   ; 将标号delay的地址存入R0

  ……    

Delay

    Mov r0, r14
    
LDR指令相比, 此伪指令的操作数有 “ = ”

 

NOP   空操作

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章