描述

栈这种结构在嵌入式里其实是非常常用的,比如函数调用与返回就是典型的栈应用,虽然很多时候栈都是 CPU 系统在自动管理,我们只需要在链接文件里分配栈大小以及栈存放位置,但稍微了解一下栈的原理会更加利于我们去理解嵌入式代码执行机制,以及帮助我们进一步去调试。

1. 何为堆栈?

堆 HEAP 与栈 STACK 是两个不同概念,其本质上都是一种数据结构。

栈是一种按数据项排列的数据结构,只能在一端(栈顶 top)对数据项进行插入和删除,其符合后进先出(Last-In / First-Out)原则。栈(os)一般是由编译器自动分配释放,其使用的是一级缓存。

堆也是一种分配方式类似于链表的数据结构,其可以在任意位置对数据项进行操作。堆(os)一般由程序员手动分配释放,其使用的是二级缓存。

在嵌入式世界里,堆栈一般指的仅是栈。

2. 作用与意义

在 MCU 中,栈这种结构一般被 cpu 和 os 所使用。

在 cpu 裸机中使用情况分两种:一、主动进行函数调用时,STACK 用以暂存下一条指令地址、函数参数、函数中定义的局部变量;二、硬中断来临时,暂存当前执行的现场数据(下一条指令地址、各种缓存数据),中断结束后,用以恢复。

在 os 中使用时,硬栈的使用同 cpu 裸机;但 os 一般会为每个任务额外分配一个软栈,在任务调度时,可用软中断打断当前正在执行的任务,栈则用以保存各自任务以恢复。

3. 软硬之分

硬件堆栈:是通过寄存器 SP 作为索引指针的地址,是调用了 BL 等函数调用指令后硬件自动填充的堆栈。

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

简单一点说,硬件堆栈主要做为地址堆栈用,而软件堆栈主要会被分配成数据堆栈。或看其栈顶指针是否和 CPU 具有特殊的关联,有关联者(如 SP)“硬”,而无关联者“软”。

4. 栈的纯 C 实现

基本的抽象数据类型(ADT)是编写 C 程序必要的过程,这类 ADT 有链表、堆栈、队列和树等,本节主要讲解下堆栈的几种实现方法以及他们的优缺点。

堆栈(stack)的显著特点是后进先出(Last-In First-Out, LIFO),其实现的方法有三种可选方案:静态数组、动态分配的数组、动态分配的链式结构。

静态数组:特点是要求结构的长度固定,而且长度在编译时候就得确定。其优点是结构简单,实现起来方便而不容易出错。而缺点就是不够灵活以及固定长度不容易控制,适用于知道明确长度的场合。

动态数组:特点是长度可以在运行时候才确定以及可以更改原来数组的长度。优点是灵活,缺点是由此会增加程序的复杂性。

链式结构:特点是无长度上线,需要的时候再申请分配内存空间,可最大程度上实现灵活性。缺点是链式结构的链接字段需要消耗一定的内存,在链式结构中访问一个特定元素的效率不如数组。

首先先确定一个堆栈接口的头文件,里面包含了各个方案下的函数原型,放在一起是为了实现程序的模块化以及便于修改。然后再接着分别介绍各个方案的具体实施方法。

堆栈接口 stack.h 文件代码:

4.1 静态数组

在静态数组堆栈中,STACK_SIZE 表示堆栈所能存储的元素的最大值,用 top_element 作为数组下标来表示堆栈里面的元素,当 top_element == -1 的时候表示堆栈为空;当 top_element == STACK_SIZE - 1 的时候表示堆栈为满。push 的时候 top_element 加 1,top_element == 0 时表示第一个堆栈元素;pop 的时候 top_element 减 1。

a_stack.c 源代码如下:

4.2 动态数组

头文件还是用 stack.h,改动的并不是很多,增加了 stack_size 变量取代 STACK_SIZE 来保存堆栈的长度,数组由一个指针来代替,在全局变量下缺省为 0。

create_stack 函数首先检查堆栈是否已经创建,然后才分配所需数量的内存并检查分配是否成功。destroy_stack 函数首先检查堆栈是否存在,已经释放内存之后把长度和指针变量重新设置为零。is_empty 和 is_full 函数中添加了一条断言,防止任何堆栈函数在堆栈被创建之前就被调用。

d_stack.c 源代码如下:

4.3 链式结构

由于只有堆栈顶部元素才可以被访问,因此适用单链表可以很好实现链式堆栈,而且无长度限制。把一个元素压入堆栈是通过在链表头部添加一个元素实现。弹出一个元素是通过删除链表头部第一个元素实现。由于没有长度限制,故不需要 create_stack 函数,需要 destroy_stack 进行释放内存以避免内存泄漏。

l_stack.c 源代码如下:

打开APP精彩内容

点击阅读全文

linux堆栈有什么作用,嵌入式世界里,堆栈的作用和意义相关推荐

  1. 嵌入式Linux能调用cheese吗,嵌入式系统BootLoader技术内幕

    本文详细地介绍了基于嵌入式系统中的 OS 启动加载程序 ―― Boot Loader 的概念. 软件设计的主要任务以及结构框架等内容. 1. 引言 在专用的嵌入式板子运行 GNU/Linux 系统已经 ...

  2. Unix / Linux世界里的4-2-1

    Unix / Linux世界里的4-2-1 在Unix / Linux世界里,4代表可读( r ),2代表可写入 ( w ),1代表可执行 ( x ) 如果拥有7 = 4+2+1 的权限,即代表这个人 ...

  3. linux世界里类似source insight的工具(zz)-如梦初醒-中国教育人博客

    linux世界里类似source insight的工具(zz)-如梦初醒-中国教育人博客 linux世界里类似source insight的工具(zz)-如梦初醒-中国教育人博客 sourcenav ...

  4. 嵌入式Linux开发系列之一: 走进嵌入式Linux的世界

    走进嵌入式Linux的世界 一.嵌入式系统 嵌入式系统是以应用为中心,以计算机技术为基础,并且软硬件是可裁剪的,适用于对功能.可靠性.成本.体积.功耗等有严格要求的专用计算机系统.嵌入式系统最典型的特 ...

  5. 腾讯首发Linux内核源码《嵌入式开发进阶笔记》差距差的不止一点点哦

    一,前言 Linux内核是一个操作系统(OS)内核,本质上定义为类Unix.它用于不同的操作系统,主要是以不同的Linux发行版的形式.Linux内核是第一个真正完整且突出的免费和开源软件示例.Lin ...

  6. Linux+MCSM9+Docker 搭建我的世界mohist1.18.2版服务器,MC开服教程

    Debian系统使用MCSManager9面板和Docker容器搭建Minecraft Java版私服的教程,本教程用的mohist1.18.2服务端,用其他服务端的也可以参考一下. mohist支持 ...

  7. 视频和投票|中国有哪些基于Ceph研发的存储 amp;amp; 闲聊Ceph amp;amp; 视频《开源世界里的SDS剖析》

    首先祝大家端午节快乐! 首先谢谢朋友们的留言和私信的互动,根据2017-01-21的投票文章 <930个朋友的投票结果 - 你心目最好的HCI品牌是?>及反馈.截止到目前,Server S ...

  8. 《嵌入式 Linux应用程序开发标准教程(第2版)》——第1章 Linux快速入门 1.1 嵌入式Linux基础...

    本节书摘来自异步社区<嵌入式 Linux应用程序开发标准教程(第2版)>一书中的第1章,第1.1节,作者 华清远见嵌入式培训中心,更多章节内容可以访问云栖社区"异步社区" ...

  9. 中国速度之二神山建设(3):有力的技术保障,基建世界里的云原生缩影 | IDCF DevOps案例研究...

    内容来源:DevOps案例深度研究第4期 – 火神山雷神山 DevOps实践研究战队(本文只展示部分PPT及研究成果,全程视频请移步文末) 本案例内容贡献者:赖泽薇.张扬.邓茜芸.韦一.刘德权.候利涛 ...

  10. 在比特币世界中矿工的作用是什么

    转载自   在比特币世界中矿工的作用是什么 如题.本人技术小白,花了大量时间查阅了比特币的一些资料.虽然不敢说把每个细节都完全搞懂了,不过整体思路和关键部分的主要原理还是搞明白了. 要说矿工的作用就要 ...

最新文章

  1. CSharp数据库代码生成工具
  2. Android Studio 单刷《第一行代码》系列 06 —— Fragment 生命周期
  3. Failed to instantiate file__from module__The specified list does
  4. django返回指定html文件,Django返回HTML文件的实现方法
  5. 反射——类(Class)
  6. nginx documentation | Development guide
  7. Python还能走多远?
  8. Redis性能基准测试
  9. 设置HttpClient的授权标头
  10. git如何将远程仓库代码,覆盖本地代码
  11. 【引向】全栈开发工程师之路
  12. Mac电脑使用svn下载版本
  13. (转发)RJ45水晶头网线的做法
  14. iOS使用CNContact对通讯录增删改查
  15. Stata-交乘项专题: 主效应项可以忽略吗?
  16. windows编译 zlib
  17. 雷军给陈年总结的小米十条经验
  18. mosquitto出现由于目标计算机积极拒绝,无法连接
  19. PDPS软件:导出插枪文件功能(Gun Cloud)介绍与使用方法
  20. 浙大版《Python 程序设计》题目集第4章-17——第4章-21

热门文章

  1. python正态分布拟合曲线怎么打印出中位数值,如何用对数正态分布函数拟合数据...
  2. ts 正负条形图 组件_手把手教你使用ggplot2绘制条形图
  3. laravel--6 eloquent查询作用域
  4. java 手机智能拨号_智能拨号 CeleDial v1.8
  5. python游走代码_用Python模拟随机游走(Random walks)
  6. GSP算法与SPADE算法
  7. python爬取招聘网站视频教程_Python爬取拉钩招聘网
  8. 在简历中使用STAR法则
  9. 阿里datav使用记录1
  10. python的十句名言_程序员的二十句励志名言,看看你最喜欢哪句?