嵌入式系统与开发(二)

ARM汇编程序设计(一)

ARM指令系统


指令编码格式

指令字长为固定的32位,典型ARM指令编码格式如下图所示

image

语法格式如下:

1
<opcode>{<cond>}{s}<Rd>,<Rn>,<shifter_operand>

各字段含义:

  • cond: 条件码——决定指令是否执行的条件编码
  • opcode: 操作码——指令操作符编码
  • s: 条件码设置域
  • Rd: 目标寄存器编码
  • Rn: 源寄存器编码;第一操作数
  • shifter_operand: 第二操作数

寻址方式

1.立即寻址

也叫作立即数寻址,操作数本身就在指令中给出,只要取出指令也就取到了操作数,这个操作数也被称为立即数。
例:

1
ADD R0, R0, #1		;R3<-R0+1

立即数的表示以”#”为前缀,十六进制的立即数在”#”后面加”&”符号,二进制的立即数在”#”后加上”%”.

2.寄存器寻址

指令地址码给出寄存器的编号,寄存器中的内容为操作数。
例:

1
ADD R0, R1, R2		;R0<-R1+R2

R0: 结果寄存器
R1: 第1操作数寄存器
R2: 第2操作数寄存器

3.寄存器间接寻址

以寄存器中的值作为操作数的地址,操作数本身存放在存储器中
例:

1
2
LDR R0, [R1]		;R0<-[R1]
STR R0, [R1] ;[R1]<-R0

4.基址变址寻址

就是将寄存器的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址

例:

1
2
3
4
LDR RO, [R1, #4]		;R0<-[R1+4]
LDR R0, [R1, #4]! ;R0<-[R1+4]、R1<-R1+4
LDR R0, [R1], #4 ;R0<-[R1]、R1<-R1+4
LDR R0, [R1, R2] ;R0<-[R1+R2]

5.多寄存器寻址

一次可以传送多个寄存器的值,允许一条指令可以传送16个寄存器的任何子集
例:

1
2
3
4
LDMIA R0, {R1, R2, R3, R4}		;R1<-[R0]
;R2<-[R0+4]
;R3<-[R0+8]
;R4<-[R0+12]

6.寄存器移位寻址

LSL: 逻辑左移
LSR: 逻辑右移
ASR: 算术右移
ROR: 循环右移
RRX: 扩展为1的循环右移

1
2
3
4
5
MOV R0, R1, LSL#2		;将R1中的内容左移两位后传送到R0中
MOV R0, R1, LSR#2 ;将R1中的内容右移两位后传送到R0中,左端用0来填充
MOV R0, R1, ASR#2 ;将R1中的内容右移两位后传送到R0中,左端用第31位的值来填充
MOV R0, R1, ROR#2 ;将R1中的内容循环右移两位后传送到R0中
MOV R0, R1, RRX#2 ;将R1中的内容进行带扩展的循环右移两位后传送到R0中

7.相对寻址

以程序计数器PC的值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。
例:

1
2
3
4
5
BL LOOP			;跳转到子程序LOOP处执行
... ...
LOOP
... ...
MOV PC, LR ;从子程序返回

8.堆栈寻址

堆栈是一种数据结构,按照先进先出的方式工作,使用一个称作堆栈指针的专用寄存器指示当前的操作位置,堆栈指针总是指向栈顶。
当堆栈指针指向最后压入堆栈的数据时,称为满堆栈,而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈。
同时,根据堆栈的生成方式,又可以分为递增堆栈和递减堆栈。

四种堆栈动作方式:

  • 满递增堆栈:堆栈指针指向最后压入的数据,且由低地址向高地址生成
  • 满递减堆栈:堆栈指针指向最后压入的数据,且由高地址向低地址生成
  • 空递增堆栈:堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成
  • 空递增堆栈:堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生成

ARM指令集

类型指令说明
加载/存储指令LDR, STR单寄存器
LDM, STM多寄存器
分支B, BL, BLX, BX
数据处理MOV, MVN数据传递
CMP, CMN, TST, TEQ比较
ADD, ADC, SUB, SBC, RSB, RSC, MUL,MLA算术加减乘除
AND, ORR, EOR, BIC逻辑运算
状态寄存器访问MSR, MSR
异常中断SWI, BKPT
协处理器相关CDP, LDC, STC, MCR, MRC