堆与栈

    堆”和“栈”是独立的概念日常说的“堆栈”其实是两个概念:“堆”和“栈”。在英文中,堆是heap,栈是stack,不知道何时,什么缘由,在中文里,这两个不一样的概念硬是被搞在一块儿了,因此,围绕这个混合词所发生的误解和争执这几年就没有断过。

“栈”通常是由硬件(CPU)实现的,CPU用栈来保存调用子程序(函数)时的返回地址,高级语言有时也用它做为局部变量的存储空间。

“堆”是个实实在在的软件概念,使用与否彻底由编程者“显示地(explicitly)”决定,如malloc。

程序通过编译链接生成执行程序后,堆和栈的起始地址就已经肯定了(具体说,是经过“链接程序”),在一个具备反向增加的栈的CPU上,数据空间可表示以下:

低    ->|-----------------|
      | 全局量(全部已初始化量 .data, |
      | 未初始化量 .bss )       |
  堆起始->|-----------------|
      |    堆向高地址增加      |
      |                 |
      |                 |
      |     自由空间        |
      |                 |
      |                 |
      |    栈向低地址增加      |
高 栈起始->|-----------------|

在内存中,“堆”和“栈”共用所有的自由空间,只不过各自的起始地址和增加方向不一样,它们之间并无一个固定的界限,若是在运行时,“堆”和“栈”增加到 发生了相互覆盖时,称为“栈堆冲突”,系统确定垮台。因为开销方面的缘由,各类编译在实现中都没有考虑解决这个问题,只有靠设计者本身解决,好比增长内存 等。

=================================================================
说明(128为例)硬堆栈:
即SP,一般汇编中讲的所谓堆栈(用于PC指针等压栈),通常设置从片内RAM的顶部0X10FF开始向下生长,基本上64个足够足够了
软件堆栈:
C编译器自动分配的堆栈,在硬堆栈和全局变量之间的空间,也是向下生长,通常用于局部变量。好比一个子程序定义一个局部变量A[256],那么此空间即在 软堆栈中,假设当前软堆栈用到0X800,分派A[256]后,软堆栈用到0X700,A[0]地址为0X700,A[1]地址为0X701 ……,固然若是局部变量较少,用寄存器就能够了,用不着软堆栈了。此子程序退出后软堆栈恢复到0X800。
另:你的C程序编译后,生成的汇编文件中,R28:R29就是软堆栈指针
编程

相关文章
相关标签/搜索