软件堆栈和硬件堆栈概念分析

软件堆栈和硬件堆栈概念分析,第1张

     函数中的栈

  栈是一种具有先入后出特性的数据结构,前面说过,这种特性常常用来帮住我们“原理返回”或者“保持原样”。试想,当我们第一次来到一个陌生的城市,走在陌生的街道上,寻找一个陌生的目标,最令我们有安全感的莫过于仔细记录走过的每一个街道、穿过的每一个路口--这种安全感来源于潜意识里“万一找不到目的地就原路返回”的想法。记得20世纪90年代,有一首家喻户晓的流行歌曲《星星点灯》中曾这样唱到“星星点灯。。。为迷失的孩子,照亮来时的路”。

  “找到来时的路”这种想法是人们基本的求生本能,对有人类编写的C语言编译器来说,也是这样--面对一层一层复杂嵌套关系的函数调用,编译器总是试图记录下我们调用的过程,以便“找回回去的路”。栈就在这种场合中,得到了广泛的应用。

  C语言支持函数的调用,这完全得益于栈式分配策略的使用。所谓栈式分配,抛去复杂的技术细节,简单说来,就是将函数内部使用的种种信息(例如,局部变量)在发生函数嵌套调用时,压入栈中“记录下所走过的路”。这样,当调用的函数运行结束需要返回时,编译器就能很容易从栈中找到“来时的路”。使用模拟的方法,我们来具体看看这一过程。

  我们假设:一个函数中所有牵涉到的局部信息都被包含在一个与函数同名的接节点中。当我们在某一个函数中发生了对另外一个函数的调用,就将本函数的局部信息压入栈中--也就是将以该函数命名的结点压入栈中:当我们从某一函数中返回,就从栈中d出一个结点。观察一段代码的函数调用情况,了解编译器如何借助来实现函数的嵌套调用。

  

      软件堆栈和硬件堆栈

  ICCAVR 使用两个堆栈:一个用于子程序调用和中断 *** 作的硬件堆栈,一个用于传递参数、临时变量和局部变量的软件堆栈。可以使用堆栈检测函数检测两个堆栈是否溢出。

  看其栈顶指针是否和CPU具有特殊的关联,有关联者(如SP)“硬”,而无关联者“软”。

  单片机在执行调用子程序的指令时,一般会把返回地址自动存入堆栈,而没有被单片机自动入栈但是也需要保存的内容比如状态寄存器、通用寄存器等,就得通过PUSH等指令把它们人为地保存到堆栈中。自动入栈和“人为入栈”可能使用的是一个堆栈指针。有的单片机可以分开,比如AVR,可以通过“ST -Y, R0”这样的指令把R0存入软件堆栈区(Y是由R28和R29两个寄存器的值组成的16位指针),有的单片机缺少这样的指令,就会把软件堆栈和硬件堆栈放在一个栈空间,都使用SP,比如51.

  硬件堆栈:或许也可以称作系统堆栈,是位于片内RAM区。有人说,只要能使用PUSH,POP指令的单片机,都可以说含有硬件堆栈。这样的说法我个人觉得不是很全面。通过指令进行压栈和出栈 *** 作只是系统堆栈中的一种 *** 做。系统堆栈还可以被隐含调用。例如,当调用子程序时,系统会主动把返回地址压入堆栈,并不需要用户通过指令 *** 作。通常,栈底设在内存的高端,也就是把内存的最高一段空间划作栈区。这些都是向下生长栈。栈指针可能是专用的寄存器,也可能借用一通用寄存器。也有单片机是在数据区里划一块作栈区,可能是向上生长,也可能是向下生长。

  硬件堆栈:是通过寄存器SPH,SPL做为索引指针的地址,是调用了CALL,RCALL等函数调用指令后硬件自动填充的堆栈!

  软件堆栈:是编译器为了处理一些参数传递而做的堆栈,会由编译器自动产生和处理,可以通过相应的编译选项对其进行编辑。

  简单一点说,硬件堆栈主要做为地址堆栈用,而软件堆栈主要会被分配成数据堆栈!

  如果没有硬堆栈,你可以选定一个寄存器作堆栈指针,通过软件实现堆栈 *** 作。移植μC/OS-II也不一定要硬堆栈。ARM 就很难说它的堆栈是软的还是硬的。32位的ARM指令中没有PUSH、POP指令。ARM习惯上用R13作堆栈指针(SP),但用别的寄存器作堆栈指针也未常不可。ARM习惯上用LDM/STM(多寄存器加载/存储指令)来 *** 作堆栈,压多少,按什么顺序都能选择。应该说ARM是软硬结合的堆栈。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/dianzi/2717514.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-08-17
下一篇 2022-08-17

发表评论

登录后才能评论

评论列表(0条)

保存