ARM 堆栈

堆栈严格来说应该叫做栈,栈(Stack)是限定仅在一端进行插入或删除操作的线性表。

因此,对栈来说,可以进行插入或删除操作的一端称为栈顶(top),相应地,另一端称为栈底(bottom)。

不含元素的空表称为空栈。由于堆栈只允许在一端进行操作,因而按照后进先出(LIFO-Last In First Out)的原理运作

      从栈顶的定义来看,栈顶的位置是可变的。空栈时,栈顶和栈底重合;满栈时,栈顶离栈底最远。ARM为堆栈提供了硬件支持,它使用一个专门的寄存器(堆栈指针)指向堆栈的栈顶。而且7种模式都有各自独立的堆栈指针,也就是有各自独立的堆栈空间。

存储器堆栈可分为两种:
                    向上生长:向高地址方向生长,称为递增堆栈
                    向下生长:向低地址方向生长,称为递减堆栈

栈指针指向最后压入的堆栈的有效数据项,称为满堆栈

堆栈指针指向下一个要放入的空位置,称为空堆栈

 

这样就有4中类型的堆栈表示递增和递减的满堆栈和空堆栈的各种组合。

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

满递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向内含有效数据项的最低地址。指令如LDMFD,STMFD等。(Descending 递减)

空递减:堆栈通过减小存储器的地址向下增长,堆栈指针指向堆栈下的第一个空位置。指令如LDMED,STMED等。

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

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

 

使用ARM汇编语言实现堆栈操作时,下面4条指令常被用到。

·  LDM:加载多寄存器指令;

·  STM:存储多寄存器指令;

·  PUSH:将多个寄存器的值存储到堆栈并更新堆栈指针

·  POS:从堆栈中装载多个寄存器的值并更新堆栈指针。

堆 栈 类 型

Push

Pop

满递减

STMFD(STMDB,Decrement Before)

LDMFD (LDM , Icrement Ater) 

满递增

STMFA (STMIB, Increment Before) 

LDMFA (LDMDA , Decrement After) 

空递减

STMED (STMDA, Decrement After) 

LDMED (LDMIB, Increment Before) 

空递增

STMEA (STM , increment after) 

LDMEA (LDMDB, Decrement Before) 

LDM和STM表示多寄存器寻址,即一次可以传送多个寄存器值。
LDM:一次装载多个,这里用来出栈。
STM:一次存储多个,这里用来入栈。

F/E表示指针指向的位置
F:full满堆栈,表示堆栈指针指向最后一个入栈的有效数据项。
E:empty空堆栈,表示堆栈指针指向下一个要放入的空地址。

A/D表示堆栈的生长方式
A:堆栈向高地址生长,即递增堆栈。
D:堆栈向低地址生长,即递减堆栈。
递增递减和硬件无关,这一般是由操作系统决定的。我们一般使用的是递减。LINUX是用递减堆栈。

所以
LDMFD SP!,{R1-R7,LR};将数据出栈,放入R1~R7,LR这8个寄存器,同时SP自动更新。这是一个满递减堆栈。
STMFD SP!,{R1-R7,LR};将R1~R7,LR入栈,SP更新。满递减堆栈。

借鉴 汇编语言程序设计:基于ARM体系结构(第3版).pdf

有一个重要的约定,编号低的寄存器在存储数据或加载数据时对应的是存储器的低地址。

示例:

push / pop 命令等同于 stmdb / ldmia ,因此,下面的 push 指令,将 lr 压栈,之后再将 r11 压栈,也就是 lr 在高地址, r11 在低地址。

S:0x8000215C : PUSH     {r11,lr}

Reference:

http://hi.baidu.com/trical/item/585a24087f9b1a036c9048f0

http://www.52rd.com/Blog/Archive_Thread.asp?SID=7626

https://www.eefocus.com/embedded/323184/p5

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值