arm堆栈操作

堆栈严格来说应该叫做栈,栈(Stack)是限定仅在一端进行插入或删除操作的线性表。因此,对栈来说,可以进行插入或删除操作的一端端称为栈顶(top),相应地,另一端称为栈底(bottom)。不含元素的空表称为空栈。由于堆栈只允许在一端进行操作,因而按照后进先出(LIFO-Last In First Out)的原理运作。

      从栈顶的定义来看,栈顶的位置是可变的。空栈时,栈顶和栈底重合;满栈时,栈顶离栈底最远。ARM为堆栈提供了硬件支持,它使用一个专门的寄存器(堆栈指针)指向堆栈的栈顶。而且7种模式都有各自独立的堆栈指针,也就是有各自独立的堆栈空间。但这里的堆栈和uC/OS操作系统的任务堆栈又有区别,uC/OS的每个任务都有自己的堆栈,要是把uC/OS移植到ARM上,可以借助ARM的堆栈指针来实现。存储器堆栈可分为两种:
                    向上生长:向高地址方向生长,称为递增堆栈
                    向下生长:向低地址方向生长,称为递减堆栈
      堆栈指针指向最后压入的堆栈的有效数据项,称为满堆栈;堆栈指针指向下一个要放入的空位置,称为空堆栈。这样就有4中类型的堆栈表示递增和递减的满堆栈和空堆栈的各种组合。

满递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向内含有效数据项的最高地址。指令如LDMFA,STMFA等。
      空递增:堆栈通过增大存储器的地址向上增长,堆栈指针指向堆栈上的第一个空位置。指令如LDMEA,STMEA等。

满递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址。指令如LDMFD,STMFD等。
      空递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置。指令如LDMED,STMED等。

      为什么说“向上生长”和“向下生长”呢?那是以为,一般画堆栈示意图都是把低地址画在下面,高地址画在上面。如下图。

arm堆栈操作 - Ntern - My World My Dream

 

 

      有一点需要注意的是,虽然ARM处理器核对于两种生长方式的堆栈均支持,但ADS的C语言编译器仅支持一种方式,即从上往下长,并且必须是满递减堆栈。所以STMFD等指令用的最多。

 

 arm对于堆栈的操作一般采用 LDMFDpop)和STMFD push) 两个命令。
以前困惑的就是STMFD 命令对于操作数是按照什么顺序压栈的
比如:STMFD sp{R0-R5LR} 进栈顺序是:
高地址(1方式)
LR
R5
R4
```````
R0   <-sp
低地址
还是
高地址(2方式)
R0
R1
```
R5
LR <-sp
低地址
现在通过下表,可以轻松的解决这个问题:
寻址方式
说明
pop
=LDM
push
=STM
FA
递增满
LDMFA
LDMDA
STMFA
STMIB
FD
递减满
LDMFD
LDMIA
STMFD
STMDB
EA
递增空
LDMEA
LDMDB
STMEA
STMIA
ED
递减空
LDMED
LDMIB
STMED
STMDA
按照图表,可知 STMFD对应的是STMDB,根据arm指令手册,可知STMDB入栈顺序是(1方式)
LDMFD对应的是LDMIA,这样这两个操作就可以成功配对
arm堆栈操作 - Ntern - My World My Dream
posted @ 2013-05-20 12:08  barrychen528  阅读(2001)  评论(0)    收藏  举报