ARM汇编程序设计(一)
ARM指令系统
指令编码格式
指令字长为固定的32位,典型ARM指令编码格式如下图所示
语法格式如下:
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 | LDR R0, [R1] ;R0<-[R1] |
4.基址变址寻址
就是将寄存器的内容与指令中给出的地址偏移量相加,从而得到一个操作数的有效地址
例:
1 | LDR RO, [R1, #4] ;R0<-[R1+4] |
5.多寄存器寻址
一次可以传送多个寄存器的值,允许一条指令可以传送16个寄存器的任何子集
例:
1 | LDMIA R0, {R1, R2, R3, R4} ;R1<-[R0] |
6.寄存器移位寻址
LSL: 逻辑左移
LSR: 逻辑右移
ASR: 算术右移
ROR: 循环右移
RRX: 扩展为1的循环右移
1 | MOV R0, R1, LSL#2 ;将R1中的内容左移两位后传送到R0中 |
7.相对寻址
以程序计数器PC的值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。
例:
1 | BL LOOP ;跳转到子程序LOOP处执行 |
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 |