栈的生长方向
8051的栈是向高地址增长,INTEL的8031、8032、8048、8051系列使用向高地址增长的堆栈;但同样是INTEL,在x86系列中全部使用向低地址增长的堆栈。其他公司的CPU中除ARM的结构提供向高地址增长的堆栈选项外,多数都是使用向低地址增长的堆栈。

历史原因
在没有MMU的时代,为了最大的利用内存空间,堆和栈被设计为从两端相向生长。那么哪一个向上,哪一个向下呢?
  人们对数据访问是习惯于向上的,比如你在堆中new一个数组,是习惯于把低元素放到低地址,把高位放到高地址,所以堆向上生长比较符合习惯。而栈则对方向不敏感,一般对栈的操作只有PUSH和pop,无所谓向上向下,所以就把堆放在了低端,把栈放在了高端。MMU出来后就无所谓了,只不过也没必要改了。
  51这种单片机,没有堆,只有栈,所以把栈设计成向上,有利于扩展,比如52在127后面加个128个字节,程序就不必修改可以直接移植,如果是向下的话要利用这多出来的128字节就要修改程序,改变堆栈指针了。

数据间的地址高低看cpu的体系,一般是固定的。数据内的地址高低看cpu的大小端模式,有时可以改的。

ARM 同时支持这两种增长方式,向上生长和向下生长。 对于向上生长,在向堆栈写入数据后,堆栈指针的值变大,称之为递增堆栈。 反之为递减堆栈。

另外需要注意的一点是堆栈指针(SP)所指向的存储单元是否已经保存有数据,可以分成两种情况,分别为“满堆栈”和“空堆栈”。这并不意味着堆栈是满的或者是空的,而是说当前SP指向的单元是否有有效数据的情况。 如果SP指向最后压入栈的有效数据项,称为满堆栈,这种堆栈的入栈操作要先将SP先调整然后再写入数据。 另外一种SP指向下一个待压入数据的空位置(SP指向的位置没有有效数据),称为空堆栈,这种堆栈的操作先写入数据再调整SP。

51单片机使用的是满堆栈的情况,SP总是默认指向07位置,相0的R7寄存器。插入数据时需要先将SP自增,然后才能写入数据。只是PUSH时,51自己完成了这个操作,但SP确实是指向了有效数据的位置。POP则相反,先赋值然后SP自减。

ARM支持这2种情况。结合起来ARM共支持4种堆栈类型,满递增,空递增,满递减,空递减。

说明:此文整理自网络,原文地址:http://www.dzsc.com/dzbbs/20061126/200765184739359366.html

为什么栈和堆的生长方向不一样相关推荐

  1. 栈和堆的区别(转 知乎)

    ①管理方式:栈由编译器自动管理:堆由程序员控制,使用方便,但易产生内存泄露. ②生长方向:栈向低地址扩展(即"向下生长"),是连续的内存区域:堆向高地址扩展(即"向上生长 ...

  2. 栈、堆、静态存储区的三分天下

    1.栈区(stack)-   由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) -   一般由程序员分配释放, 若程序员不释放,程序结束 ...

  3. C语言里栈和堆的区别整理

    这里说的是C语言程序内存分配中的堆和栈.下面先谈谈C语言的内存管理: 可执行程序在存储时(没有调到内存)分为代码区(text).数据区(data)和未初始化数据区(bss)3个部分. (1)代码区(t ...

  4. 栈与堆的区别(内存分配与数据结构)

    参考自https://blog.csdn.net/K346K346/article/details/80849966/ 堆(Heap)与栈(Stack)包含两层含义: 程序内存布局场景下的内存管理方式 ...

  5. 栈和堆的区别【总结】

    栈和堆的区别[总结] 1.1内存分配方面: 堆:一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式是类似于链表.可能用到的关键字如下:new.m ...

  6. C语言:栈和堆的区别

    c语言五大内存分区 栈区(stack):存放函数形参和局部变量(auto类型),由编译器自动分配和释放 堆区(heap):该区由程序员申请后使用,需要手动释放否则会造成内存泄漏.如果程序员没有手动释放 ...

  7. linux java 栈_关于Java中栈与堆的思考

    1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快,仅次于直接位于C ...

  8. JAVA中栈和堆总结

    堆栈空间分配 栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由O ...

  9. Java中栈、堆和常量池

    2019独角兽企业重金招聘Python工程师标准>>> Java内存分配主要包括以下几个区域: 寄存器 最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.. 栈 存放基 ...

最新文章

  1. RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别
  2. sed及awk显示指定行内容
  3. R语言使用线性回归模型来预测(predict)单个样本的目标值(响应值、response)实战
  4. VTK:IO之ReadCML
  5. 淘系的音视频编辑方案:非线性编辑引擎
  6. abp vNext微服务框架分析
  7. vue基础4——自定义指令
  8. 从零开始学Pytorch(十二)之凸优化
  9. 《Algorithms》Comparable 实现归并排序
  10. 当面试官问你了不了解defineProperty的时候。。。
  11. Laplacian surface editing
  12. Jmeter之Bean shell使用(二)——断言加密的响应信息
  13. 金山打字测试一分钟软件,金山打字2006——一款打字练习及测试软件.doc
  14. SpringMVC快速上手教程及SSM整合案例
  15. Vue中native的用法
  16. 转:SDHC卡驱动及初始化
  17. 快速掌握阿里云 OSS
  18. 【转】利用百度BAE3.0搭建原版WORDPRESS博客详细教程
  19. 手机内存卡大小的计算
  20. Java集合判空/非空

热门文章

  1. MySQL语句第二高的薪水查询
  2. OpenCV-Python形态变换、图像金字塔、轮廓属性、直方图
  3. python基础知识整理 第七节:单例设计模式、异常、模块、包、制作模块、文件
  4. 温控自动烘焙系统的研究与实现
  5. keras 的 example 文件 mnist_siamese.py 解析
  6. 【JAVA小游戏+水果售卖系统】基于GUI界面编程的水果“人生”模拟系统
  7. 线上分享会预告之三维模型检索技术介绍
  8. 基于Sobel计算图像梯度图
  9. 计算机图形学——三角形网格
  10. python-eggs异常解决方法