ARM 汇编指令集

寄存器

寄存器的寄存器用于数据处理及控制。

如内存中数据处理,需先从内存中加载数据到寄存器中,处理完毕后,再把寄存器的数据存放到内存中。

寄存器组拥有16个寄存器,R0R12是通用寄存器,R13R15是特殊寄存器。

寄存器 作用 comment
R0~R7 通用寄存器-Low register 16 bits 指令
R8~12 通用寄存器-Hig Register 16 bits 指令 + 32 bits 指令
R13 Stack Pointer-SP MSP:(Main stack pointer) 复位默认的SP指针,PSP:(Process stack pointer):进入线程后的指针
R14 Link Register-LC 函数调用时,会首先将LC的值存入堆栈中,用于保存返回地址,当调用函数完毕后,将LC的值赋给PC。
R15 Program conutner 当前执行指令的地址

Thumb2 指令集:可以16bits指令与32位指令的混合使用。

ARM汇编指令语法格式:

label 
 mnemonic operand1, operand2, ....;comments

label 
    标签用以表示一个参考地址。
    Label放在指令前,Label用以表达指令的地址。
    Label也可以用以表达数据的地址。
    
mnemonic
   助记符,助记符是指令的名字,。

operand
   操作数有,操作可以是立即数,也可以是寄存器,操作数的个数视具体汇编指令。

;comment  注释


eg:
MOVS R0, #0x12 ; Set R0 = 0x12 (hexadecimal)
MOVS R1, #’A’ ; Set R1 = ASCII character A  

后缀

ARM处理器汇编器中,一些指令支持带后缀,常用的后缀如下:

后缀简写 备注
S 需要更新APSR标志
EQ Equal
NE Not Equal
LT Lesser Than
GT Great Than
.N 使用16位指令集
.W 使用32位指令集

汇编指令集:

1 Moving data within the processor 数据拷贝

MOV  R4, R0 ;            从R0拷贝数据到R4。
MOV  R4,[R0];            从R0数据指向的地址中读取数据到R4;
MOVS R4, R0;             从R0拷贝数据到R4,更新APSR。
MOVS R4, [R0};           从R0数据指向的地址中拷贝数据到R4,更新APSR。


eg:

MOV  R4, #0x34;         R4的值设置为0x34
MOVS R4, #0x34;        R4的值设置为0x34,更新APSR

(move word指令)
MOVW R4, #0x1234;      把16位立即数放到寄存器的低16位,高16位清零 。(若执行指令前R4的值为全为F,执行完毕后,R4的值为0x00001234)
MOVT R4, #0x1234;      把16位立即数放到寄存器的高16位,低16位不变。(若执行指令前R4的值为0x00001234,执行完毕后,R4的值为0x12341234)

MVN  R4, R0;           对R0按位取反,然后放入R4中。


MSR  CONTROL, R2;       把状态寄存器的值放到通用寄存器中。
MRS  R2, CONTROL;      把通用寄存器的值放到状态寄存器中。

Notes:

移动8bits内的数据使用MOV指令;

移动8bits~16bits的数据使用MOVW/MOVT指令

移动32bits的数据;使用LDR指令;如LDR R0. 0x12345678;Set R0 to 0x12345678

2 Memory access 内存访问

根据数据的传输方向,传输数据的大小,有如下的指令。
ARM 汇编指令集_第1张图片

预锁引寻址
  数据的传输的内存地址是寄存器的值与立即数的值的总和。
  这个立即数的值可正可负。
  LDRB R0,[R1,#0x1234];     从内存地址Ro+0x1234中读取一个byte,然后放入RO寄存器中。
  LDRB R0, [R1,#0x1234]!    从内存地址Ro+0x1234中读取一个byte,然后放入RO寄存器中。同时R1的值更新为R1+0x1234
  Note:指令中!表明指令完成后,地址需要被更新。

  LDRD R0, R1,[R2,#0x5];   从内存地中R2+0x5中读取2个bytes,然后放入R0,R1寄存器中。
  STRD R0,R1,[R2,#0x05];   把R0,R1的值写入内存R2+0x05
寄存器寻址
   LDR R0, [R1,R2, LSL #2];  从内存地址R1 + (R2<<2)中读取一个字到R0中。
   STR R0,[R1,R2];          把R0的值写入地址R1+R2中。     
   LDR R0, R1,#0x05;      从内存地址为R1的值的内存中读取数据到R0中,并更新R1 = R1+5.
连续读/写多个寄存器从一个连续的地址空间内。
LDM指令 Load multiple registers
STM指令 Store multiple register
  LDR R4,=0x8000; 设值R4的值为0x8000.
  LDMIA R4, {R0-R3}; 读取4个words并且把他们依次存取到R0,R1,R2,R3中。
  寄存器组的设置是灵活的;如{R1,R3,R5-R7,R9,R10-R12}.
堆栈操作:
   PUSH {R0, R4-R7, LC}; push R0,R4,R5,R6,R7进去堆栈
   POP {R2, R3};POP R2,R3从堆栈里。

通常PUSH与POP指令是成对出现,且寄存器列表是一致的。
如
PUSH {R0, R4-R7, LC}; push R0,R4,R5,R6,R7进去堆栈
POP{R0, R4-R7, PC}; 恢复R4_R7,直接把LC的值赋给PC。

LC返回的是函数执行的地址,返回的LC会直接赋值给PC,所以可以直接POP LC的值给PC

3 Arithmetic operations 算数操作

算数加 addition
ADD  R0, R0, R2 ; R0 = R0 + R2
ADDS R0, R0, R2 ; R0 = R0 + R2,更新APSR

ADD  RO, R1,#0x5; RO = R0 +5;
ADDS RO, R1,#0x4‘ RO = R0 +5;更新APSR

ADC(ADD with carry)
ADC RO,R1, R2; R0 = R1 + R2 + carry 
ADC R0, #0x3; R0 = R0 + 3 + carry


算数减 subtraction
SUB R0, R1, R2;  R0 = R1 - R2
SUB R0, #3;      R0 = R0 -3
SUB R0, R1, #5;  R0 = R1 -5

SBC R0, R1, R2; R0 = R1 - R2 - borrow

逆向算数减 Reserve subtraction
RSB R0, R1, R2;      R0 = R2 - R1
RSB R0, R1, #0x55;   R0 = 0x55 - R1
  

算数乘 multiply
MUL RO, R1, R2 ; R0 = R1 * R2

算数除法 divide
UDIV R0, R1, R2; R0 = R1/R2 (unsigned)
SDIV R0, R1, R2;  R0 = R1/R2 (Signed)

4 Logic opeations 逻辑操作

逻辑按位与 & and
AND R0, R1;                  R0 = R0 & R1
AND R0, R1, R2;              R0 = R1 & R2
AND R0, R1, #3;              R0 = R1 & 3

按位或 | or
ORR R0, R1;                  R0 = R0 | R1
ORR R0, R1, R2;              R0 = R1 | R2
ORR R0, R1, #3               R0 = R1 | 3

按位清除  bit clear
BIC R0, R1;                R0 = R0 & ~R1
BIC R0, R1, R2;              R0 = R1 & ~R2
BIC R0, R1, #3;              R0 = R1 &~3

按位异或 bitwise exclusive or
EOR R0,R1;                  R0 = R0 ^ R1;

5 Shift and rotate instruction 移动旋转操作

算术右移  Arithmetic shift right
ASR R0, R1;              R0 = R0 >> R1
ASR R0, R1, R2            R0 = R1 >> R2
ASR R0, R1, #0x3          R0 = R1 >> 0x3

逻辑右移动 Logic shift right
LSR R0, R1;               R0 = R0 >> R1
LSR R0, R1, R2;           R0 = R1 >> R2
LSR R0, R1, #0x3          R0 = R1 >> 3

逻辑左移动 Logic Shift Left
LSL R0, R1;            R0 = R0 << R1
LSL R0, R1, R2;          R0 = R1 << R2
LSL R0, R1, #0x3         R0 = R1 << 0x03

6 Bit-Filed operation instruction 位操作指令

6.1 BFC(Bit filed cler)
    LDR R0, = 0x1234FFFF
    BFC R0,#4,#8;    #4代表其实的bit,#8代表c户里的bit长度;指令完毕后 R0 = 0x1234F00F

6.2 BFI(Bit filed insert)
   命令格式: BFI R0, R1, #lsb, #width
   该命令会从R1中拷贝width指定的bit到R0的LSB指定的位置。   

   LDR R0, = 0x12345678
   LDR R1, = 0x3355AACC
   BFI R0, R1, #8, #16;命令执行完毕R0 = 0x335678CC

7 Compare and Test instruction 比较与测试指令

7.1 CMP - compare
    CMP R0, R1;     计算R0-R1,更新APSR
    CMP R0,#0x5;  计算R0-3,更新APSR

7.2 CMN- Compare negtive
    CMP R0, R1;    计算R0+R1;更新APSR
    CMP R0,#0x3; 计算R0+3;更新APSR

7.3 TST-bitwise AND
 	TST R0, R1;    
    TST R0,#0x37.4 TE!-bitwise XOR
 	TEQ R0, R1;    
    TEQ R0,#0x3

比较与测试指令会更新APSR的标志位,用于选择分支或者条件执行。

8 Program flow control 程序流程控制

用于条件分支;函数调用;条件执行

8.1 函数调用
   BL  Label; Branch and link instruction-跳转到Label指定的地址并且保存返回值在LR中
   函数调用时,如果函数有三个参数,会把参数依次放进R0,R1,R2中,如果函数有返回值会把返回值放进R0中。  

eg:

8.2 条件分支
   B<Conditon> Label; 跳转到Label如果满足条件。

8.3  用于循环的 指令
   CBZ  Compare and Branch if Zero
   CBNZ Compare and branch if not Zero
 
8.4 IT If-Then 指令
    待更新

函数调用流程:

C语言定义如下代码

BL Label; Branch and link instruction-跳转到Label指定的地址并且保存返回值在LR中 函数调用时.

调用带参的函数时,如果函数有三个参数,会把参数依次放进R0,R1,R2中,如果函数有返回值会把返回值放进R0中。

如果有俩个参数,会把参数依次放进R0,R1中。

你可能感兴趣的:(ARM_CM4_CORE,arm,嵌入式硬件)