立即寻址(立即数寻址)

// R0 = R1 + 4;
ADD R0,R1,#4

// R0 = 1;
// 注意,立即数必须对应8位位图,即一个8位的常数通过循环右移偶数位得到的32位常数。
MOV R0,#1

寄存器寻址

// R0 = R1 + R2;
ADD R0,R1,R2

// R0 = R1;
MOV R0,R1

寄存器移位寻址

// R0 = R1 << 3
MOV R0,R1,#LSR#3

寄存器间接寻址

// R0 = *R1;
LDR R0,[R1]

基址寻址

不自动变址

完成数据传送后不会导致提供基址的寄存器发生变化

// R0 = *(R1 + 4);
LDR R0,[R1,#4]

前变址

数据传送前先对提供基址的寄存器进行操作,类似高级语言中的*(++Rn)

/*
  R1 += 4;
  R0 = *(R1 + 4);
*/
LDR R0,[R1,#4]!

后变址

数据传送完成后对提供基址的寄存器进行操作,类似高级语言中的*(Rn++)

/*
  R0 = *(R1 + 4);
  R1 += 4;
*/
LDR R0,[R1,#4]!

相对寻址

使用PC指针寻址,常见的用法自然就是LABEL了

// 死循环
DEADLOOP
  B DEADLOOP

多寄存器寻址

可以实现一条指令完成多个寄存器值的传送,允许一条指令传送 16 个寄存器的任何子集或所有寄存器

/*
  R1 = *R0;
  R2 = *(R0 + 4);
  R3 = *(R0 + 8);
  R4 = *(R0 + 12);
*/
LDMIA R0,[R1,R2,R3,R4]

堆栈寻址

ARM 处理器支持4种类型的堆栈工作方式

满递增堆栈(Full Ascending Stack,FA)

栈指针指向最后压入的数据,且由低地址向高地址生成(已知STMF103R6不支持这种方式)
STMFA(进栈),LDMFA(出栈);

/*
  PUSH R1
  PUSH R2
  .
  .
  PUSH R7
  PUSH LR
*/
STMFA SP!,[R1-R7,LR]

/*
  POP LR
  POP R7
  POP R6
  .
  .
  POP R1
*/
LDMFA SP!,[R1-R7,LR]

满递减堆栈(Full Descending Stack,FD)

堆栈指针指向最后压入的数据,且由高地址向低地址生成
STMFD(进栈),LDMFD(出栈);

/*
  PUSH R1
  PUSH R2
  .
  .
  PUSH R7
  PUSH LR
*/
STMFD SP!,[R1-R7,LR]

/*
  POP LR
  POP R7
  POP R6
  .
  .
  POP R1
*/
LDMFD SP!,[R1-R7,LR]

空递增堆栈(Empty Ascending Stack,EA)

堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成
STMEA(进栈),LDMEA(出栈);

/*
  PUSH R1
  PUSH R2
  .
  .
  PUSH R7
  PUSH LR
*/
STMEA SP!,[R1-R7,LR]

/*
  POP LR
  POP R7
  POP R6
  .
  .
  POP R1
*/
LDMEA SP!,[R1-R7,LR]

空递减堆栈(Empty Descending Stack,ED)

堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生成(已知STMF103R6不支持这种方式)
STMED(进栈),LDMED(出栈)。

/*
  PUSH R1
  PUSH R2
  .
  .
  PUSH R7
  PUSH LR
*/
STMED SP!,[R1-R7,LR]

/*
  POP LR
  POP R7
  POP R6
  .
  .
  POP R1
*/
LDMED SP!,[R1-R7,LR]