1什么是栈

百度这么说:栈是一种特殊的线性表,是一种只允许在表的一端进行插入或删除操作的线性表。表中允许进行插入、删除操作的一端称为栈顶。表的另一端称为栈底。栈顶的当前位置是动态的,对栈顶当前位置的标记称为栈顶指针。当栈中没有数据元素时,称之为空栈。栈的插入操作通常称为进栈或入栈,栈的删除操作通常称为退栈或出栈。

简易理解:

客栈,即临时寄存的地方,计算机中的堆栈主要用来保存临时数据,局部变量和中断/调用子程序程序的返回地址。程序中栈主要是用来存储函数中的局部变量以及保存寄存器参数的,如果你用了操作系统,栈中还可能存储当前进线程的上下文。设置栈大小的一个原则是,保证栈不会下溢出到数据空间或程序空间.CPU在运行程序时,会自动的使用堆栈,所以堆栈指针SP就必须要在调用C程序前设定。

CPU的内存RAM空间存放规律一般是分段的,从地址向高地址,依次为:程序段(.text)、BSS段,上面还可能会有堆空间,然后最上面才是堆栈段。这样安排堆栈,是因为堆栈的特点决定的,堆栈的指针SP初始化一般在堆栈段的高地址,也就是内存的高地址,然后让堆栈指针向下增长(其实就是递减)。

这样做的好处就是堆栈空间远离了其他段,不会跟其他段重叠,造成修改其他段数据,而引起不可预料的后果,还有设置堆栈大小的原则,要保证栈不会下溢出到数据空间或者程序空间。所谓堆栈溢出,是指堆栈指针SP向下增长到其他段空间,如果栈指针向下增长到其他段空间,称为堆栈溢出。堆栈溢出会修改其他空间的值,严重情况下可造成死机.

2堆栈指针的设置

开始将堆栈指针设置在内部RAM,是因为不是每个板上都有外部RAM,而且外部RAM的大小也不相同,而且如果是SDRAM,还需要初始化,在内部RAM开始运行的一般是一个小的引导程序,基本上不怎么使用堆栈,因此将堆栈设置在内部RAM,但这也就要去改引导程序不能随意使用大量局部变量。

片内4K的SRAM,SDRAM大小64M,从0x30000000到0x33FFFFFF,当程序在片内SRAM运行的时候,sp的值设置为4096,当程序在SDRAM内运行的时候sp设置为0x34000000,当程序在内部SRAM运行,若已经初始化SDRAM,此时也可以将堆栈指针设置为0x34000000,更加防止了堆栈溢出。

3栈的整体作用

保存现场;

传递参数:汇编代码调用 C 函数时,需传递参数;

保存临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量;

1) 保存现场

现场,意思就相当于案发现场,总有一些现场的情况,要记录下来的,否则被别人破坏掉之后,你就无法恢复现场了。而此处说的现场,就是指 CPU 运行的时候,用到了一些寄存器,比如 r0,r1 等等,对于这些寄存器的值,如果你不保存而直接跳转到子函数中去执行,那么很可能就被其破坏了,因为其函数执行也要用到这些寄存器。因此,在函数调用之前,应该将这些寄存器等现场,暂时保持起来(入栈 push),等调用函数执行完毕返回后(出栈 pop),再恢复现场。这样CPU就可以正确的继续执行了。

保存寄存器的值,一般用的是 push 指令,将对应的某些寄存器的值,一个个放到栈中,把对应的值压入到栈里面,即所谓的压栈。然后待被调用的子函数执行完毕的时候,再调用 pop,把栈中的一个个的值,赋值给对应的那些你刚开始压栈时用到的寄存器,把对应的值从栈中弹出去,即所谓的出栈。其中保存的寄存器中,也包括 lr 的值(因为用 bl 指令进行跳转的话,那么之前的 PC 的值是存在 lr 中的),然后在子程序执行完毕的时候,再把栈中的 lr 的值 pop 出来,赋值给 PC,这样就实现了子函数的正确的返回

2) 传递参数

C 语言进行函数调用的时候,常常会传递给被调用的函数一些参数,对于这些 C 语言级别的参数,被编译器翻译成汇编语言的时候,就要找个地方存放一下,并且让被调用的函数能够访问,否则就没发实现传递参数了。对于找个地方放一下,分两种情况。一种情况是,本身传递的参数不多于 4 个,就可以通过寄存器 r0~r3 传送参数。因为在前面的保存现场的动作中,已经保存好了对应的寄存器的值,那么此时,这些寄存器就是空闲的,可以供我们使用的了,那就可以放参数。另一种情况是,参数多于 4 个时,寄存器不够用,就得用栈了。

3) 临时变量保存在栈中

包括函数的非静态局部变量以及编译器自动生成的其他临时变量。

C语言叠堆在变量周围,C语言及ARM中堆栈指针SP设置的理解与总结相关推荐

  1. c语言字符串与字符什么意思,C语言和Java中的字符串异同点是什么?

    2018-04-06 在Turbo C 语言和Java语言中字符串和字符串数组的异同点 1.Turbo C 语言 在C语言中字符串和字符数组基本上没有区别,都需要结束符:如:char s[4]={'a ...

  2. c语言数组数据的输入,在C语言中,数组中的值如何输入到函数中?

    我希望这有帮助: #include /* don't need to specify size of array1 here */ /* rather pass the no. of elements ...

  3. c语言staticint的作用,C语言 static 声明静态变量?大佬原来用它干这事!

    原标题:C语言 static 声明静态变量?大佬原来用它干这事! C语言可变参数只会用算啥本事?看我来抽丝剥茧干翻它! 高手在写代码的时候,会特别注重的一点就是,对外的方法对外,不对外的方法和数据,都 ...

  4. R语言ggplot2可视化分组变量下的数据分布(线条、色彩配置)、WVPlots包的ShadowHist函数比较分组下的数据直方图、ggplot2分面图facet_wrap可视化分组变量下的数据分布

    R语言ggplot2可视化分组变量下的数据分布(线条.色彩配置).WVPlots包的ShadowHist函数比较分组下的数据直方图.ggplot2分面图facet_wrap可视化分组变量下的数据分布 ...

  5. 在叠堆及虚拟化的今天生成树存在的理由

         在叠堆及虚拟化的今天生成树存在的理由 现在网络的堆叠.虚拟化在发展,为什么还要在交换机上存在生成树这种技术?为什么厂商不把生成树功能从交换机上摘掉?为什么还要去深入的研究生成树?   说直白 ...

  6. P5压电陶瓷致动器,纵向极化,叠堆压电陶瓷,多层压电陶瓷促动器

    ➤ 01压电陶瓷促动器 ▲ P5压电陶瓷致动器,纵向极化,叠堆压电陶瓷,多层压电陶瓷促动器 网页上的参数说明: 无负载自振频率: 40 kHz 工作电压:0-100 V 自由电容: 3.28 uF + ...

  7. c语言常量类型转换,c语言基础教程常量变量和类型转换,免费版.doc

    c语言基础教程常量变量和类型转换,免费版 第二章??????常量变量和类型转换2.1.1数字常量??? 数字常量包括整型常量和浮点型常量,浮点型常量又称实数.????1.整型常量???? HYPERL ...

  8. ​Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数

    ​Swift语言中为外部参数设置默认值可变参数常量参数变量参数输入输出参数 7.4.4  为外部参数设置默认值 开发者也可以对外部参数设置默认值.这时,调用的时候,也可以省略参数传递本文选自Swift ...

  9. 用 C 语言开发一门编程语言 — 变量元素设计

    目录 文章目录 目录 前文列表 变量 变量语法规则 变量的读取和存储 将变量加入 Lisp Value 体系 变量的计算 变量的定义与赋值 异常处理优化 源代码 前文列表 <用 C 语言开发一门 ...

  10. go语言笔记——go环境变量goroot是安装了路径和gopath是三方包路径

    Go 环境变量 Go 开发环境依赖于一些操作系统环境变量,你最好在安装 Go 之间就已经设置好他们.如果你使用的是 Windows 的话,你完全不用进行手动设置,Go 将被默认安装在目录 c:/go  ...

最新文章

  1. php mysql百万级数据_php+mysql百万级数据怎么排序_PHP教程
  2. jQuery 效果 - 滑动
  3. [转] Windows系统Net命令使用技巧
  4. Sencha touch Panel之间的跳转(如不使用TabPanel或者Carousel控件而产生跳转的动画效果)...
  5. 一个立即关闭显示器的小软件(Masm开发,只有3KB大小)
  6. 根据条件返回相应值 decode(条件,值1,翻译值1,值2,翻译值2,...值n,翻译值n,缺省值)...
  7. 按照鬼哥学so变化,四,第一章的例子
  8. and/or(||)的理解
  9. 最好用16进制工具wxHexEditor
  10. python中的exec()、eval()以及complie()
  11. 每天一道算法题(16)——翻转链表
  12. network 公网IP与私网IP的区别
  13. 【NB-IoT模块显示屏逻辑显示】
  14. Cadence 17.4 PSpice仿真555定时器输出方波
  15. 数量乘单价秋金额的计算机公式,在电子表格中数量乘以单价等于金额用什么样的公式啊?怎么算呢?...
  16. 【WPS表格】数据透视表:统计各商品及各分店的销售总额
  17. 虚拟机windows10 屏幕大小不能自适应
  18. matlab与数学实验心得体会,数学matlab实验心得体会
  19. ios android耳机,硬件 篇三:安卓ios和win10三大平台几款无线耳机使用体验随写 非评测 电音向...
  20. 10074---深入理解Java中的final关键字

热门文章

  1. Qt编译时报堆空间不足
  2. Keil自动格式化代码
  3. 关于Lambda表达式的简单理解,以及基础使用,仅限新手
  4. python控制台输出_替换Python中的控制台输出
  5. 怎么定义int_「C语言更新」C语言中如何来定义一个指针,并且对其进行初始化...
  6. python在线diff工具在哪_使用Python创建你自己的diff-tool
  7. html文件怎么兼容浏览器,如何扫描HTML和跨浏览器兼容的JavaScript文件?
  8. php 横杠箭头,为什么我的箭头下面有一横线?
  9. Js中Date日期的使用
  10. 【转】JQuery中$.each 和$(selector).each()的区别详解