历史上的今天
返回首页

历史上的今天

今天是:2025年03月16日(星期日)

正在发生

2020年03月16日 | C语言及ARM中堆栈指针SP设置的理解与总结

2020-03-16 来源:eefocus

什么是栈:


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


简易理解:


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


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


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


堆栈指针的设置


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


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


栈的整体作用


a.保存现场;

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


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)临时变量保存在栈中


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

推荐阅读

史海拾趣

芯海科技(CHIPSEA)公司的发展小趣事

进入21世纪第二个十年,物联网技术迅猛发展,为芯海科技带来了新的机遇。公司紧跟市场趋势,发布了高精度SoC(系统级芯片)/MCU芯片,广泛应用于智能家居、智能穿戴等领域。这一创新使得芯海科技能够为客户提供一站式的智能硬件解决方案,进一步提升了其市场竞争力。

HDK(北陆电气)公司的发展小趣事

近年来,随着新能源汽车市场的快速崛起,BMS(电池管理系统)技术成为关键。芯海科技凭借在“模拟信号链+MCU”领域的技术积累,成功开发出应用于BMS锂电管理的高精度模拟信号链芯片。这一技术的突破使得芯海科技能够切入新能源汽车市场,为行业的发展提供了有力支持。

台湾晶豪(ESMT)公司的发展小趣事

晶豪科技一直积极寻求与国内外企业的合作机会。通过与合作伙伴的紧密合作,公司不断拓展业务领域,进入了模拟及混合讯号IC领域。目前,公司提供的产品包括音讯转换器(ADC/DAC)及D类音频放大器等IC。这些新产品的推出不仅丰富了公司的产品线,还为客户提供了更多样化的选择。同时,通过与合作伙伴的资源共享和优势互补,晶豪科技在技术研发和市场拓展方面取得了更多突破。

ERP Power公司的发展小趣事

在这个故事中,我们将关注ERP Power在国际市场的拓展情况。通过与国际知名企业的合作和交流,ERP Power系统成功打入国际市场并获得了广泛认可。这一过程中,ERP Power不仅提升了自身的技术实力和服务水平还积累了丰富的国际化经验。

Gustav Klauke GmbH公司的发展小趣事

巨化集团作为我国较早的化工企业,在信息化道路上一直走在前列。为了进一步提升企业的管理水平和竞争力,巨化集团决定实施ERP系统。在选型过程中,巨化集团看中了ERP Power系统的稳定性和可靠性,最终选择了该系统作为企业信息化建设的核心。

通过ERP Power系统的实施,巨化集团实现了企业资源的优化配置和业务流程的标准化管理。系统不仅整合了企业内外部的信息资源,还提供了强大的数据分析功能,帮助企业做出更明智的决策。此外,ERP Power系统还提高了巨化集团的工作效率和员工满意度,为企业带来了显著的经济效益和社会效益。

FutureWafer公司的发展小趣事

在2004年,电源行业资深人士MichaelArcher和AbdulSher-Jan共同创立了ERP Power的母公司EnergyRecoverySystems(ERS),致力于研发降低AC-DC电源能耗同时降低成本的技术。到了2006年,伟创力作为笔记本电脑和台式电脑电源产品的领先制造商,决定采用ERS的专有技术。这一决定标志着ERP Power技术开始进入电子制造领域的核心,为伟创力提供了更高效的电源解决方案,降低了生产成本,提高了产品竞争力。

随着伟创力对ERP Power技术的深入应用,其在电源管理方面的优势逐渐显现。ERP Power的技术不仅优化了伟创力的产品性能,还通过数据分析和智能决策支持系统,提升了伟创力的生产效率和供应链管理水平。这一成功案例为ERP Power在电子行业树立了良好的口碑,吸引了更多企业的关注与合作。

问答坊 | AI 解惑

概念车系列(一)

这是一款三菱的混合动力概念车。…

查看全部问答>

咨询一个问题关于mini2440驱动中的文件

IO口,寄存器是不是都定义在这个地方呢 mini2440驱动中的文件regs-gpio.h的位置在什么地方呢…

查看全部问答>

为什么LPC2103 ARM的IRQ中断无法使用

这是我写的timer1定时器IRQ中断程序:当定时器发生中断时,关闭LED 我用的开发工具是IAR Embedded Workbench(编译成ARM指令,不用THUMB指令) #include #define Fosc        11059200          ...…

查看全部问答>

Verilog 修正miller码编码

在做这个修正miller码的编码时,如何判定输入的序列是不是最后一位啊?我们讨论可能要用寄存器,不知道这样行不行,哪为大虾给点思路?如果能给写一小段VERILOG,更是感激不尽啊。。…

查看全部问答>

arm汇编实现YUV2RGB的问题

YUV2RGB时需要用到下面的公式: R = Y + 1.402 ( Cr - 128 ) G = Y - 0.34414 ( Cb - 128 )  -  0.71414 ( Cr - 128 ) B = Y + 1.772 ( Cb - 128 ) 为了避免浮点数运算,修改为 R = Y + ( 91881*( Cr - 128 ))>>16 当 ...…

查看全部问答>

P4 CPU中断控制器设置问题

我想将并口的中断模式从level触发改成edge触发,是不是得修改CPU的中断控制器相关寄存器值? 我的cpu是celeron D 347,有人知道它的中断控制器地址和相应寄存器偏移么? …

查看全部问答>

串口的中断会影响定时器A和B的中断。

485通讯和TIMER-A,TIMER-B单独运行时均正常。但加在一齐时,程序跑飞了。只要不写 IE2=URXIE1+UTXIE1;程序运行正常。一旦加上这句话,程序就跑飞。为什么呀?…

查看全部问答>

8*8led 点阵 24引脚???

我买了个8*8的点阵,是红色单色的,但是有24四个引脚,一般不是只有16个引脚吗,,跪求引脚定义。。。。…

查看全部问答>

tlv5616出不来数据,麻烦大家看看我的程序有没问题。。

#include \"msp430x14x.h\" #define uint  unsigned int #define uchar unsigned char #define CPU_F ((double)8000000) #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0)) #define delay_ms(x) __delay_cy ...…

查看全部问答>