0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言及ARM中堆栈指针SP设置的理解与总结

5RJg_mcuworld 来源:未知 作者:李倩 2018-04-06 19:46 次阅读

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

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

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    8648

    浏览量

    361746
  • 寄存器
    +关注

    关注

    30

    文章

    5025

    浏览量

    117707
  • C语言
    +关注

    关注

    180

    文章

    7528

    浏览量

    128326
  • 指针
    +关注

    关注

    1

    文章

    473

    浏览量

    70361

原文标题:C语言及ARM中堆栈指针SP设置的理解与总结

文章出处:【微信号:mcuworld,微信公众号:嵌入式资讯精选】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    ARM堆栈学习笔记

    以下是我在学习ARM指令记录的关于堆栈方面的知识:1、寄存器 R13 在 ARM 指令中常用作堆栈指针
    发表于 06-15 11:50

    C语言及ARM堆栈指针SP设置理解与总结(转载)

    进线程的上下文。设置栈大小的一个原则是,保证栈不会下溢出到数据空间或程序空间.CPU在运行程序时,会自动的使用堆栈,所以堆栈指针SP就必须要
    发表于 01-26 17:11

    如何设置堆栈指针和清理BSS段

    嵌入式ARM开发环境下,设置堆栈指针和清理BSS段的意义
    发表于 02-04 06:26

    c语言指针详解

    精练而高效的程序。指针极大地丰富了C语言的功能。学习指针是学习C语言中最重要的一环, 能否正确
    发表于 03-26 09:51

    嵌入式ARM开发环境下为什么要设置堆栈指针和清理BSS段?

    嵌入式ARM开发环境下,设置堆栈指针和清理BSS段的意义
    发表于 04-02 06:39

    ARM汇编在嵌入式Linux开发中有何作用

    设置C 环境,比如初始化 DDR、设置 SP指针等等,当汇编把 C 环境
    发表于 12-20 08:20

    ARMV7指令集中堆栈指针SP的变化说明

    首先说明一下,arm函数调用不同的编译器可能差别很大,即使都是arm-linux的交叉编译器,也有差别,有的编译器把r7寄存器作为栈帧寄存器(fp),有的把r11寄存器作为栈帧指针(
    发表于 05-05 10:58

    DR LR与[SP, #-8]这一行程序为什么堆栈指针要减去8个字节的值呢?

    ,SPLDR LR, [SP, #-8]MSR CPSR_c, #(NoInt | SVC32Mode) ;进入管理模式MOV SP, R4 ;设置
    发表于 02-27 10:39

    文件Os_cpu_a.s堆栈指针调整的原因是什么?

    基础与实战》404 页解释:只所以要(1)(2)是因为"OSTCBHighRdy—>OSTCBStkPtr 保存的是任务栈位置,而寄存器恢复后堆栈指针并不指向这,所以要调33整
    发表于 02-28 14:03

    ucos移植C语言无法保证堆栈的结构是什么意思?

    ARM微控制器基础与实战》在 ucos 移植C 语言无法保证堆栈的结构,请问这是什么含
    发表于 02-28 14:29

    C16x堆栈

    80C166的基本设计故意偏向于允许像C这样的结构化语言比在较老的CPU上更高效地运行。 最有用的指令集功能之一是提供16个额外的堆栈指针
    发表于 09-04 07:05

    C语言_指针总结_经典讲解

    C语言_指针总结_经典讲解。
    发表于 01-06 13:47 10次下载

    堆栈指针sp的内容是什么

    堆栈是一块保存数据的连续内存。一个名为堆栈指针SP)的寄存器指向堆栈的顶部。 堆栈的底部在一个
    发表于 11-13 09:04 3.3w次阅读
    <b class='flag-5'>堆栈</b><b class='flag-5'>指针</b><b class='flag-5'>sp</b>的内容是什么

    堆栈指针sp的作用是什么

    SP是一个8位专用寄存器,它批示出堆栈顶部在内部RAM块中的位置。系统复位后,SP初始化为07H,实际上堆栈是由08H单元开始的。考虑08H~1FH单元分别属于工作寄存器区1~3,若在
    发表于 11-13 09:17 6.7w次阅读
    <b class='flag-5'>堆栈</b><b class='flag-5'>指针</b><b class='flag-5'>sp</b>的作用是什么

    C语言指针理解使用

    C语言指针理解使用指针变量的声明给普通变量的赋值对比给指针变量的赋值代*的指针的使用说明
    发表于 01-13 13:42 3次下载
    C<b class='flag-5'>语言</b><b class='flag-5'>指针</b>的<b class='flag-5'>理解</b>使用