堆栈的深入个人理解

发布者:幸福家园最新更新时间:2015-01-15 关键字:堆栈  MCU 手机看文章 扫描二维码
随时随地手机看文章
对于堆,栈,堆栈的味道,一直就跟猪八戒吃啥来着,从没有细细地品尝过。发了下狠心,各个网页看了很多,这里就把我东抓西拼的东西整理整理。
 
一  这些个概念怎么来的以及怎么记得住
这里,只限于整理我个人对堆/栈/堆栈在内存管理方面的理解。其他,在数据结构方面讲的堆/栈目前不在我整理范围之内。
这里提了三个概念: 堆,栈,以及堆栈。我把栈和堆栈的概念等同了。所以,接下来只要把两个概念弄清楚就可以了:堆和栈。
 
先说由来。由于我的工作大部分是和单片机相关的,因此也是基于嵌入式的这个方面的理解。
每片MCU有一定的内存,这些内存分:程序存储区;数据存储区。举例就是:我们写的每行代码,都会保存到程序存储区里面;而定义的一些全局变量,静态变量,局部变量之类的,就保存到数据存储区。
程序存储区,对于写代码的人来说,可以说是黑盒子:只要你的代码不超过程序代码空间,everything will be fine. 代码究竟是如何执行的,取决于你的编程思想,就是说,你让程序往东走,它就会往东走;让它原地踏步,它也会照做;前提是你的代码要写好。所以,对于编程经验成熟的人,同样的算法,他可能会少敲几行代码,并且算法出错的几率少一些;不怎么会编程的人,就多敲几行,多测试一下。研究深一些的人,可能还会对代码执行效率深入研究。我决定就此止步。继续黑盒子的话题,程序员的代码会烧写到程序存储区里面,至于哪条语句存哪里,这个是不用研究的。反正,一旦发现软件没按照你设计的那样跑,基本就是程序自身的问题,不是存放程序的存储区的问题。
数据存储区,让程序员发挥的空间就很大了。由于程序是动态地执行的,执行的结果是怎么样,会产生什么数据就不是一个确定的事情。
举个例子说说这个程序和数据之间的表象吧。举例的事件就是:一个MP3播放器的上/下键的操作。加入在播放器里有10首歌,若当前是第3首,那么按下[上]键后,应该是播放第2首。因此,实现播放第2首的,就是程序员写程序实现的,他的代码让[上]键实现了能从第3首切换到第2首的操作。这里,表现的就是代码。而且,这个代码是确切的行为,从第3首按了[上]键之后,一定是播放到第2首。这个是确切的行为,如果不能实现,就是代码有bug了,需要改正。终于可以扯到数据了。第2首是什么歌呢? 就是说第2首歌的内容是什么呢? 当然在程序员写代码的时候,他是不知道的,他要做的,就是预先开一片数据空间,以存放歌曲相关的数据。这片数据空间,想放什么就放什么,是灵活的。听烦了这几首歌以后,再更换其它音频文件就是了。再说具体一点,程序就相当于修的一条路,让车可以在上面跑;但车上面装了什么,程序员是不知道的。
 
女人就是啰嗦啊。女人的话题也是可以转得很快的。
堆和栈属于数据存储区的范畴,也可以算是数据管理的手段或方法。基于此,不能一概而论,说哪个手段高明一些;他们也是基于现实的需要而产生的。黑格尔说:存在就是合理的。
这样的概念大家都不陌生:军队的管理是很严格的,很死板的;但是对于一些年轻的技术公司来说,员工就享有很高的自由度。
如果我说,墙角边整齐地摆放着10本书; 以及墙角边的书凌乱地放着。你闭上眼睛,能区分出两种画面吗? 如果没有,就不用往下看了。
栈的特性,就是严格/有序/规范的。栈的英文就是Stack. 如果我说,there are books stacked in that corner,你应该能知道书是怎么放的吧。
相反,堆呢,就是自由/灵活/随意的。堆的英文是Heap. 如果我说,there are books heaped in that corner,你应该能知道书是怎么放的吧。 
 
二  get closer to the real STACK/HEAP。
栈: 由系统自动分配和回收的。
堆: 由程序员分配和回收的。
基于第一部分的理解,不用想都知道,作为“堆”的数据空间,也必须是灵活的,因为成千上万的程序员在写什么程序是未知的。但可知道的一点,就是他们是跑在确定的某个OS里面的。
因此,也不过就是给系统管理的数据空间起了个名字,就栈;给程序员使用的空间,起了个名,就堆。
我接下来就会废话:起什么名字都不重要,重要的是,我们得对这两种数据存储区的管理的机制由来,方法有深刻认识;这样,即便几个世纪以后它们更名为阿猫阿狗了,我们依然能认知它们。
 
举例: 
void Check_Pro_Code( uint8  style )
{
     uint8 i;
 
     switch( style )
     {
      ......
     }
}
 
void main( )
{
     uint8 j = 1;
     
     Check_Pro_Code( j );              
}
 
在main()函数里调用了Check_Pro_Code(...)函数,事先要对j进行入栈操作;当然这里函数调用的时候,涉及到几个入栈操作:程序的下一个执行地址;局部变量;形参。
这里,我就没有深入介绍了。
 
实在很惭愧的是,我写的嵌入式软件里,没有涉及到任何和堆操作相关的。我就是那样一个人,CM3内核里也没有移植操作系统,实在是汗颜,因为本人对RTOS实在是未曾涉猎。所以,我这里对于堆的介绍,是没有任何实战鹰眼的。并且为了堆我就堆了一下。你说,这样算学术造假吗?
void main( )
{
int j=10;
int *p;
 
 
 
       
 图二,如何知道自己的工程用了多少堆栈
 

 
 
 
整理了2个小时,仅以此文,纪念我美好生活的另一种开始。
关键字:堆栈  MCU 引用地址:堆栈的深入个人理解

上一篇:Verilog乘法运算结果为0问题的解决
下一篇:HR202程序,基本按照数据手册写的

推荐阅读最新更新时间:2024-03-16 13:51

单片机控制的动态数据缓存器的DRAM刷新过程与管理
  动态 存储器 的一个显著特点就是存储的数据具有易失性,必须在规定时间内对其刷新。在本系统中采用8031的定时器1定时中断实现对DRAM的刷新。其定时中断刷新的程序如下:      刷新时,先将Tl置1,在DEC 70H语句的取指 周期 ,8031从外部程序存储器EPROM取指令,PSEN有效,此时Tl为高,使RAS有效;同时,存储指令的EPROM地址也送到了地址线上,其低9位也作为行地址同时送给DRAM,实现对DRAM -行的刷新。由于DEC 70H语句是对内部RAM的操作,此时地址线上不会有其他地址,连续执行OlOOH条DEC 70H语句(0200H个字节),可实现对1 MB DRAM的刷新(1 MB DRAM需9位刷新地
[单片机]
<font color='red'>单片机</font>控制的动态数据缓存器的DRAM刷新过程与管理
PIC12F617单片机ADC初始化配置
#include pic.h #include PIC12F617.h #include ADC.h /************************************************************** @beep_; void Adc_Init(void);//完成ADC初始化 ADC配置过程: 1:端口设置:模拟输入无上拉 TRISIO 5:0 : 1:GPIO引脚配置为输入 0:GPIO引脚配置为输出 *TRISIO3=1.只能输入. ANSEL:bit3:0 ANS 3:0 : GP4|G
[单片机]
stm8单片机的SWIM模式引脚复用
SWIM模式 上电复位后,SWIM复位并进入OFF模式。 1、OFF:上电复位的默认状态。此时,SWIM引脚不能应用为I/O口。 2、I/O:通过将全局配置寄存器(CFG_GCR)中的SWD位置位后可将SWIM引脚设定为普通I/O口。一旦系统复位,SWIM模块重新回到OFF模式。 3、SWIM:当SWIM引脚出现特定序列信号时,就会进入此状态。这种模式下,调试工具通过SWIM引脚使用三种命令(SRST系统复位,ROTF运行中读,WOTF运行中写)来控制STM8。 SWIM引脚复用 通过将全局配置寄存器(CFG_GCR)中的SWD位置位后可将SWIM引脚设定为普通I/O口但需要注意: 如果SWIM引脚用作普通I/O口,最好
[单片机]
stm8<font color='red'>单片机</font>的SWIM模式引脚复用
PIC单片机4X4矩阵键盘检测原理及实现C语言程序
#include pic.h #define uchar unsigned char #define uint unsigned int __CONFIG(0x3B31); const uchar table ={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; uchar key_num; void delay(uint x); void init(); void scan(); void didi(uchar num); void disp(); void mai
[单片机]
单片机红外遥控程序beta
千辛万苦,终于把这个完成了。不错不错。现在的问题就在上板子上测试了。刚才发了,发现 / * * / 居然被屏蔽了。标注只能用两个杠杠表示。为了以后更好的发布,我写程序注释的时候尽量用双斜杠。 #include reg52.h #define uchar unsigned char #define uint unsigned int uchar code table ={ 0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; //定义数字显示 sbit remote=P3^3; //定义中断源外中断3.3 int c
[单片机]
单片机学习的准备工作
1) 足够的信心、恒心和耐心 有同学问过我,单片机这门技术难不难。我觉得这个问题得从两个方面去分析。 首先,我们从战略上藐视它。那么多同学跟着老师学一段时间就可以做出来小车,超声波测距,甚至做出来机器人,似乎很拽的样子。那他们又不是三头六臂,我们也没有什么做不了的道理。实际上要说技术,其实就是一层窗户纸,表面看不透彻,感觉特别神秘,实际只要你稍微一努力就可以捅破它,夸张点说,单片机在逻辑上的关系,只有小学的水平,简单的很。正所谓会者不难,难者不会,大家不懂这个东西,看起来感觉很神秘。所以大家只要认真踏实坚持学下去,肯定能学好这么技术。 其次呢,我们从战术上要重视它。你说单片机这东西,如果十天八天就学会了,那么这个技术还
[单片机]
单片机+PWM来解码WAV真人声乐
本程序是 51hei单片机开发板 所提供一个列子,用单片机解码wav真人声音音乐,并用pwm的方法输出,开发板的p2.2口是接的蜂鸣器,但蜂鸣器的效果实在是太差,在使用中直接把蜂鸣器去掉,接上一个2w的小喇叭效果更佳.wav.h是wav数据请从下面的压缩包下载: http://www.51hei.com/f/waefc.rar 下面是主程序部分: #include reg52.h #include wav.h sbit dataOut = P2^2; #define maxSize 2060 unsigned char pwmData=0; unsigned char pwmCycle=256; //pwm
[单片机]
基于GSM模块Q2403A和8051单片机实现短消息收发系统的应用方案
基于GSM短消息的业务不需要建立拨号连接,只需把待发的消息加上目的地址发送至短消息中心,再由短消息中心转发到最终目标。GSM 短消息业务以其连接简单、费用低廉、覆盖范围广、实现方便等优点得到了广泛的应用。运用 GSM 短消息实现远程测控的可靠性较高、信号传播距离远、覆盖面积广,并且可以节省建网初期的巨额投资。 本文对基于GSM短消息收发系统的设计与实现作了具体描述,给出了系统的软硬件设计方案,对主要硬件,即GSM模块Q2403A 和8051单片机作了重点介绍。给出了系统的软件设计,包括PC与单片机通信部分和短消息收发部分。最后实现系统监控功能。 系统硬件实现 总体系统结构 该系统硬件主要由8051单片机扩展电路、Q2403
[单片机]
基于GSM模块Q2403A和8051<font color='red'>单片机</font>实现短消息收发系统的应用方案
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved