为什么栈和堆的生长方向不一样
栈的生长方向
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.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 2.堆区(heap) - 一般由程序员分配释放, 若程序员不释放,程序结束 ...
- C语言里栈和堆的区别整理
这里说的是C语言程序内存分配中的堆和栈.下面先谈谈C语言的内存管理: 可执行程序在存储时(没有调到内存)分为代码区(text).数据区(data)和未初始化数据区(bss)3个部分. (1)代码区(t ...
- 栈与堆的区别(内存分配与数据结构)
参考自https://blog.csdn.net/K346K346/article/details/80849966/ 堆(Heap)与栈(Stack)包含两层含义: 程序内存布局场景下的内存管理方式 ...
- 栈和堆的区别【总结】
栈和堆的区别[总结] 1.1内存分配方面: 堆:一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 .注意它与数据结构中的堆是两回事,分配方式是类似于链表.可能用到的关键字如下:new.m ...
- C语言:栈和堆的区别
c语言五大内存分区 栈区(stack):存放函数形参和局部变量(auto类型),由编译器自动分配和释放 堆区(heap):该区由程序员申请后使用,需要手动释放否则会造成内存泄漏.如果程序员没有手动释放 ...
- linux java 栈_关于Java中栈与堆的思考
1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快,仅次于直接位于C ...
- JAVA中栈和堆总结
堆栈空间分配 栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等.其操作方式类似于数据结构中的栈. 堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由O ...
- Java中栈、堆和常量池
2019独角兽企业重金招聘Python工程师标准>>> Java内存分配主要包括以下几个区域: 寄存器 最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制.. 栈 存放基 ...
最新文章
- RPC 笔记(01)— RPC概念、调用流程、RPC 与 Restful API 区别
- sed及awk显示指定行内容
- R语言使用线性回归模型来预测(predict)单个样本的目标值(响应值、response)实战
- VTK:IO之ReadCML
- 淘系的音视频编辑方案:非线性编辑引擎
- abp vNext微服务框架分析
- vue基础4——自定义指令
- 从零开始学Pytorch(十二)之凸优化
- 《Algorithms》Comparable 实现归并排序
- 当面试官问你了不了解defineProperty的时候。。。
- Laplacian surface editing
- Jmeter之Bean shell使用(二)——断言加密的响应信息
- 金山打字测试一分钟软件,金山打字2006——一款打字练习及测试软件.doc
- SpringMVC快速上手教程及SSM整合案例
- Vue中native的用法
- 转:SDHC卡驱动及初始化
- 快速掌握阿里云 OSS
- 【转】利用百度BAE3.0搭建原版WORDPRESS博客详细教程
- 手机内存卡大小的计算
- Java集合判空/非空