单片机里的堆栈

  单片机里的堆栈

  做单片机的应该都听说过堆栈,跟指针一样,一看到这两个就会莫名的蛋疼。但是用汇编的同志肯定不会陌生,因为要经常出栈入栈,但是用C语言的同志有一些可能就比较陌生了,因为出入栈全部交给了编译器。最近我就在这里吃了亏,虽然听说过堆栈,也知道在哪里修改,但因为以前写的代码量很小,变量完全不会让堆栈溢出,所以从来没意识到它的重要性,直到最近写了一个数据量很大的程序,才意识到必须要重视堆栈。

  首先说一下它出现的一些现象,应该说无法推断出它将会出现什么现象,因为堆栈溢出后,程序和参数就会全部乱套了,可能不是很要紧也可能让系统崩溃。我第一次发现奇怪的现象是在调试GSM模块通讯的时候,在处理数据的时候大量使用了sprintf标准函数,通讯经常出现异常,断开或者数据错乱,但是我又不熟悉标准函数,所有一直怀疑是使用不合理的问题,就这样整个工程磕磕碰碰写下去,总是感觉工程不稳定,但是怎么看逻辑都没有错,让自己一度抑郁。直到后来抓到一个现象,有两个连续的for循环,第一个正常运行,第二个运行到一半就跳到第一个for循环重新开始,程序终于在这里崩溃了。这非常明显是指针错乱了,让我意识到了堆栈的问题,我把堆栈改大了,但是算错数,结果还是无效,连我自己都崩溃了。好在意志坚定地锁定为堆栈问题,最终解决了。

  接下来就说说我修改了哪里吧。其实就仅仅是在stm32中修改了两个数值,一个是栈(stack_size)的大小,一个是堆(heap_size)的大小,如图1-1。

图1-1

  堆和栈其实是两个不同的概念,可以这样通俗的去理解,堆是程序猿自己操作的,而栈是编译器帮你操作的。一般在操作系统中,内存是由程序猿自个进行动态分配和回收的,这部分内存就是堆。而我们写的那些个临时变量,通常都是编译器编译的时候自动分配的,这块内存就是栈。

原文地址:https://www.cnblogs.com/wcw12580/p/10439400.html

时间: 2024-10-05 17:11:15

单片机里的堆栈的相关文章

[51单片机] SPI nRF24L01无线 [可以放在2个单片机里实现通信]

main.c 1 #include<reg51.h> 2 #include"2401.h" 3 4 #define uint unsigned int 5 #define uchar unsigned char 6 7 sbit KEY8=P3^7; //发送按键 8 sbit beep=P2^3;//喇叭 9 sbit LED6=P1^6; ////接收到数据后的功能实现灯 10 11 void delay_ms(uint z) //延时函数 12 { 13 uint x

Keil C51里关于堆栈指针的处理

Keil C是非常优秀的C51编译器,可能是最好的C51编译器,提供各种优化模式,对变量的优化和地址安排做得非常好.这是用C语言写代码的好处之一,如果用汇编写,得费一大番功夫给各个变量安排内存物理地址,还得时刻记住哪些地址的内存单元是已经分配了,新增加的变量就不能占用那些已经分配了的单元,以免产生内存交叠冲突和溢出.我一直非常信赖Keil C51的编译结果,在我的印象里,它对内存的分配是完美的,只要代码用它编译时没有报告任何warning和error,代码运行时不可能内存冲突或溢出的现象.但,今

【KEIL&#183;单片机&#183;扫盲贴】关于ARM单片机程序内存使用情况的细致讨论。

接触了两年多时间的单片机编程本人对关于单片机程序内存如何耗费的问题一直懵懵懂懂,直到在近日看到某篇有关于MDK MAP文件介绍的帖子后才有种醍醐灌顶的感觉,这里我将分享在此之上的观点与见解以供大家讨论学习. 大家都知道ARM单片机的内部存储空间极其匮乏无论是从Flash还是RAM上,每每给单片机机编程都有一种惜字如金的感觉,工程师们一般会在容量有限的情况下规范其编程习惯简化代码避免冗余,那么首先我们如何知道的程序下载到单片机上到底占用了多少Flash程序运行又会使用多少RAM? 首先上一张图:

单片机中C语言的程序与数据存储

单片机中C语言的程序与数据存储 一.五大内存分区: 内存分成5个区,它们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区. 1.栈区(stack):FIFO就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等. 2.堆区(heap):就是那些由new分配的内存块,它们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete.如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收. 3.自由存储区:就是那些

第一个单片机程序(C言语编写)

忙活了半天,预备任务做了那么多,终于要编写我们的程序代码了.假如学过 C 言语的话,你应当很轻松的跟着我的编程本人写出来,假如没学过 C 言语也没紧要,你先照着我的抄,我会在适宜的地位写出来对 C 言语语法的说明,如许抄几回后再看看说明,就应当很明确了,抄的时分必定要仔细,特别标点符号弗成以搞错.第一个单片机程序: #include <reg52.h> //包括特别功用存放器界说的头文件 sbit LED = P0^0; //位地址声明,留意:sbit 必需小写.P 大写! void main

单片机用定时器分配任务的程序结构总结

转载请注明本文地址:http://blog.sina.cn/dpool/blog/s/blog_6f2b6ba80101bwka.html?vt=4 http://blog.sina.cn/dpool/blog/s/blog_6f2b6ba80101bwka.html?vt=4本文是2013年写的,后来整理成了系统文章,请访问 http://nicekwell.net/ 查看单片机编程系列文章.以下是2013年原文:经过这几天做的程序,和以前做电子钟时的感悟,现在对单片机的整个程序结构做一下总结

嵌入式系统C编程之堆栈回溯(二)

前言 本文作为<嵌入式系统C编程之堆栈回溯>的补充版.文中涉及的代码运行环境如下: 一  异常信号 信号就是软件中断,用于向正在运行的程序(进程)发送有关异步事件发生的信息.Linux应用程序发生异常时,操作系统会产生相应的信号.硬件检测到异常(非法指令.对无效的内存引用等)时也会通知内核,内核将其转换为适当的信号并发给该异常发生时正在运行的进程. 此外,进程可将信号发送给另一进程或进程组(调用kill函数),或向自身发送信号(调用raise函数). 系统中可产生并发送多种类型的信号.在Lin

为什么单片机中既有Flash又有EEPROM

单片机运行时的数据都存在于RAM(随机存储器)中,在掉电后RAM 中的数据是无法保留的,那么怎样使数据在掉电后不丢失呢?这就需要使用EEPROM 或FLASHROM 等存储器来实现. 插播一段:ROM最初不能编程,出厂什么内容就永远什么内容,不灵活.后来出现了PROM,可以自己写入一次,要是写错了,只能换一片.随着不断改进,终于出现了可多次擦除写入的EPROM,每次擦除要把芯片拿到紫外线上照一下,想一下你往单片机上下了一个程序之后发现有个地方需要加一句话,为此你要把单片机放紫外灯下照半小时,然后

单片机入门基础

1什么时钟? 首先我们先讲讲什么是时钟. 时钟就是单片机的心脏.每跳动一下.整个单片机的各个电路就同步的动作一下. 就好像我们做广播体操的时候 广播上喊的节拍1234 2234 3234... . 然后我们所有的同学就依照这个节奏进行一个个动作.节拍越快我们动作越快.节拍越慢我们动作的越慢. 内部时钟和外部时钟? PIC单片机有很多型号能够设置成 用外部时钟(如外部接个4MHZ的石英晶振),也能够设置成用内部RC时钟. 并且还有很多型号能够选择多种频率的时钟. 如 PICLF1823 内部时钟最