ARM:什么是满减栈?为何选择满减栈?

栈的4种方式(以下以满减为主)

1. 满减栈的定义

  • 满(Full) :栈指针SP始终指向最后一个压入栈的有效数据(即栈顶元素)。

  • 减(Descending) :栈向内存低地址方向增长(栈空间从高地址向低地址扩展)。


2. 压栈操作

当数据被压入栈时:

  1. 先递减SP:SP的值先减去操作所需的内存大小(例如,32位系统每次减4字节)。

  2. 再存储数据:将数据写入SP指向的新地址。


3. 弹栈操作

当数据从栈中弹出时:

  1. 先读取数据:从SP当前指向的地址加载数据。

  2. 再递增SP:SP的值加上相应的内存大小。


4. 硬件指令的支持

ARM通过以下两类指令显式支持满减栈:

a. 多寄存器操作指令
  • 压栈STMDB SP!(Store Multiple Decrement Before)

    复制代码

    STMDB SP!, {R0-R3} ; SP -= 16 → 依次存储R3, R2, R1, R0到新地址

    • STMDB(递减存储)会在存储前递减SP,符合"满减"规则。

    • !表示更新SP的值。

  • 弹栈LDMIA SP!(Load Multiple Increment After)

    复制代码

    LDMIA SP!, {R0-R3} ; 依次加载R0, R1, R2, R3 → SP += 16

    • LDMIA(递增加载)在加载后递增SP,符合"先读后增"逻辑。
b. 专用栈指令(Thumb模式)

在Thumb-2指令集中,PUSHPOP指令进一步简化操作:

复制代码

PUSH {R0, R1} ; SP -= 8 → 存储R1, R0到[SP]和[SP+4] POP {R0, R1} ; 加载[SP]到R0, [SP+4]到R1 → SP += 8


5. 为何选择满减栈?

  • ARM ABI规范 :AAPCS(ARM Architecture Procedure Call Standard)规定使用满减栈作为标准调用约定。

  • 硬件效率:递减存储(STMDB)和递增加载(LDMIA)的组合可以高效处理连续内存操作,且与CPU流水线优化兼容。

  • 自然向下扩展:栈从高地址向低地址增长,与堆(Heap)从低地址向高地址扩展形成互补,避免内存区域重叠。

  • 调试友好:栈溢出时,SP指向低地址的非法区域,便于调试工具检测(如MMU异常)。


6. 实际内存变化示例

假设初始时 SP = 0x2000_1000

  1. 压栈R0(值=0x1234)

    1. SP -= 4SP = 0x2000_0FFC

    2. 存储 0x1234 到地址 0x2000_0FFC

  2. 再次压栈R1(值=0x5678)

    1. SP -= 4SP = 0x2000_0FF8

    2. 存储 0x5678 到地址 0x2000_0FF8

  3. 弹栈到R2

    1. 读取 0x2000_0FF8R2 = 0x5678

    2. SP += 4SP = 0x2000_0FFC


总结

ARM通过硬件指令的寻址模式 (如STMDB/LDMIASTMFD/LDMFD)强制SP在压栈时先减后存 、弹栈时先取后增,从而实现了"满减"栈。这种机制由架构直接支持,确保了栈操作的原子性和高效性,同时符合ARM标准调用约定(AAPCS)。


额外注意:

一般来说栈(stack)从高地址向低地址延申,堆(heap)从低地址向高地址延申,他们从两端向中间生长。

相关推荐
森G19 小时前
七、04ledc-sdk--------makefile有变化
linux·c语言·arm开发·c++·ubuntu
VekiSon1 天前
Linux内核驱动——杂项设备驱动与内核模块编译
linux·c语言·arm开发·嵌入式硬件
AI+程序员在路上1 天前
Nand Flash与EMMC区别及ARM开发板中的应用对比
arm开发
17(无规则自律)1 天前
深入浅出 Linux 内核模块,写一个内核版的 Hello World
linux·arm开发·嵌入式硬件
梁洪飞2 天前
内核的schedule和SMP多核处理器启动协议
linux·arm开发·嵌入式硬件·arm
代码游侠2 天前
学习笔记——Linux字符设备驱动
linux·运维·arm开发·嵌入式硬件·学习·架构
syseptember3 天前
Linux网络基础
linux·网络·arm开发
代码游侠3 天前
学习笔记——Linux字符设备驱动开发
linux·arm开发·驱动开发·单片机·嵌入式硬件·学习·算法
程序猿阿伟3 天前
《Apple Silicon与Windows on ARM:引擎原生构建与模拟层底层运作深度解析》
arm开发·windows
wkm9563 天前
在arm64 ubuntu系统安装Qt后编译时找不到Qt3DExtras头文件
开发语言·arm开发·qt