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

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

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

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

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。返回搜狐,查看更多

责任编辑:

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 指针C语言一个非常重要的概念。指针是一个变量,它存储了另一个变量的内存地址。通过使用指针,可以在程序直接操作内存,从而达到动态分配内存空间和访问数组元素等目的。 指针的声明格式如下: ``` 数据类型 *指针名称; ``` 其,数据类型是指指针所指向的变量的数据类型,指针名称是指指针变量的名称。 在使用指针时,需要使用“&”符号获取一个变量的内存地址,并将其赋值给指针变量。然后,可以使用“*”符号来间接访问指针所指向的变量。 总的来说,理解C语言指针需要对内存管理和数据类型有一定的了解,并结合实际的代码练习加以理解。 ### 回答2: C语言指针是一种特殊的变量类型,它存储了其他变量的内存地址。通过指针,我们可以直接访问和操作这些变量的值,而不需要知道变量的具体名称。指针C语言具有重要的作用和灵活性。 首先,指针可以通过传递内存地址来访问和修改函数之外的变量。这在函数调用非常有用,因为通过传递指针作为参数,函数可以直接修改原始变量的值,而不需要返回新值。 其次,指针可以用来动态分配内存。通过使用`malloc`函数,我们可以在程序运行时动态地分配内存来存储数据。指针可以指向这块内存,并通过`free`函数释放内存,以防止内存泄漏。 此外,指针还可以用于创建和操作动态数据结构,例如链表、树和图等。通过将指针链接在一起,我们可以在运行时动态地创建和删除数据节点,实现高效的数据操作。 在使用指针时,我们需要注意指针的初始化和解引用操作。指针应该首先通过给定的变量地址进行初始化,以确保指针指向有效的内存。解引用指针时,我们可以使用`*`运算符来获取指针指向的变量的值。 总之,理解C语言指针是非常重要的,因为它们提供了一种直接访问和操作内存的方式,可以提高程序的效率和灵活性。然而,指针的使用也需要小心谨慎,因为错误的指针操作可能会导致程序的崩溃或内存泄漏等问题。 ### 回答3: C语言指针是一个非常重要的概念。指针可以理解为一个存储内存地址的变量,它可以指向另一个变量或数据的位置。 首先,指针允许我们间接地访问和操作内存的数据。通过使用指针,可以通过修改指针所指向的地址来改变变量的值。这非常有用,特别是在需要传递大量数据的情况下,通过传递指针可以避免数据的复制,提高程序的效率。 其次,指针还可以用于动态内存分配。通过使用指针和相关的内存分配函数,如malloc()和free(),我们可以在运行时分配和释放内存。这对于处理动态数据结构,如链表和树等非常有用。 此外,指针还可以用于在函数之间传递参数。通过传递指针作为参数,可以实现对函数外部变量的修改,从而实现函数之间的数据共享。 虽然指针C语言非常强大和灵活,但同时也要小心使用。在使用指针时,必须确保指针所指向的内存是有效的,并确保在使用指针之前分配了足够的内存。否则可能会导致内存泄漏、段错误等问题。 总之,理解指针C语言编程的基础。它允许我们直接访问内存和处理动态内存分配,提供了更强大和灵活的编程能力。通过正确地使用指针,我们可以编写出高效、灵活和可维护性强的程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值