堆栈寻址
堆栈是一种数据结构,按先进后出(First In Last Out,FILO)的方式工作,使用一个称作堆栈指针(SP)的专用寄存器(R13)指示当前的操作位置,堆栈指针总是指向栈顶。
当堆栈指针指向最后压入堆栈的数据时,称为满堆栈(Full Stack),而当堆栈指针指向下一个将要放入数据的空位置时,称为空堆栈(Empty Stack)。
根据堆栈的生成方式,又可以分为递增堆栈(Ascending Stack)和递减堆栈(Decending Stack),当堆栈由低地址向高地址生成时,称为递增堆栈,当堆栈由高地址向低地址生成时,称为递减堆栈。
堆栈工作方式
这样就有四种类型的堆栈工作方式
- 满递增堆栈:堆栈指针指向最后压入的数据,且由低地址向高地址生成。
- 满递减堆栈:堆栈指针指向最后压入的数据,且由高地址向低地址生成。
- 空递增堆栈:堆栈指针指向下一个将要放入数据的空位置,且由低地址向高地址生成。
- 空递减堆栈:堆栈指针指向下一个将要放入数据的空位置,且由高地址向低地址生成
堆栈寻址的实现
(1)在ARM指令中,堆栈寻址是通过Load/Store指令来实现的,如:
代码语言:javascript复制 STMFD SP!,{R1-R7,LR} ;将R1-R7,LR入栈
LDMFD SP!,{R1-R7,LR} ;数据出栈,放入R1-R7,LR
(2)在Thumb指令中,堆栈寻址通过PUSH/POP指令来实现,如:
代码语言:javascript复制 PUSH {R1-R7,LR} ;将R1-R7,LR入栈
POP {R1-R7,PC} ;数据出栈,放入R1-R7,PC
相对寻址
与基址变址寻址方式相类似,相对寻址以程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到操作数的有效地址。以下程序段完成子程序的调用和返回,跳转指令BL采用了相对寻址方式:
代码语言:javascript复制BL NEXT ;跳转到子程序
; NEXT处执行
……
NEXT
……
MOV PC,LR ;从子程序返回
ARM指令详细介绍
ARM指令集总体分为以下6类:
- 数据处理指令;
- Load/Store指令;
- 程序状态寄存器与通用寄存器之间的传送指令;
- 转移指令;
- 异常中断指令;
- 协处理器指令。
ARM 指令及功能描述
数据处理指令(22条)
助记符 | 指令功能描述 |
---|---|
ADC | 带进位加法指令 |
ADD | 加法指令 |
SUB | 减法指令 |
SBC | 带借位减法指令 |
RSB | 逆向减法指令 |
RSC | 带借位的逆向减法指令 |
CMP | 比较指令 |
CMN | 负数比较指令 |
MUL | 32 位乘法指令 |
MLA | 乘加运算指令 |
UMLL | 无符号数长乘 |
助记符 | 指令功能描述 |
---|---|
UMLAL | 无符号数长乘累加 |
SMULL | 有符号数长乘 |
SMLAL | 有符号数长乘累加 |
AND | 逻辑与指令 |
ORR | 逻辑或指令 |
EOR | 异或指令 |
BIC | 位清零指令 |
TST | 位测试指令 |
TEQ | 相等测试指令 |
MOV | 数据传送指令 |
MVN | 数据取反传送指令 |
Load/Store指令(5条)
状态寄存器与通用寄存器之间的传送指令(2条)
转移指令(4条)
助记符 | 指令功能描述 |
---|---|
LDR | 存储器到寄存器的数据传输指令 |
STR | 寄存器到存储器的数据传输指令 |
LDM | 加载多个寄存器指令 |
STM | 批量内存字写入指令 |
SWP | 交换指令 |
MRS | 传送CPSR或SPSR的内容到通用寄存器指令 |
MSR | 传送通用寄存器到CPSR或SPSR的指令 |
B | 跳转指令 |
BL | 带返回的跳转指令 |
BX | 带状态切换的跳转指令 |
BLX | 带返回和状态切换的跳转指令 |
异常中断产生指令(3条)
协处理器指令(5条)
助记符 | 指令功能描述 |
---|---|
SWI | 软件中断指令 |
BKPT | 端点指令 |
CLZ | 前导0计数指令 |
CDP | 协处理器数据操作指令 |
LDC | 存储器到协处理器的数据传输指令 |
STC | 协处理器寄存器写入存储器指令 |
MRC | 从协处理器寄存器到ARM寄存器的数据传输指令 |
MCR | 从ARM寄存器到协处理器寄存器的数据传输指令 |
参考文献:
孟祥莲.嵌入式系统原理及应用教程(第2版)[M].北京:清华大学出版社,2017.