首页

文章

为什么要初始化堆栈?

发布网友 发布时间:2022-03-27 09:59

我来回答

2个回答

懂视网 时间:2022-03-27 14:20

栈的初始状态是在栈中还没有对元素进行进栈或者出栈的操作时,栈本身最开始的状态。

  

  栈又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素。从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

  

  栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。

热心网友 时间:2022-03-27 11:28

  之前看了很多关于uboot的分析,其中就有说要为C语言的运行,准备好堆栈。
  而自己在Uboot的start.S汇编代码中,关于系统初始化,也看到有堆栈指针初始化这个动作。但是,从来只是看到有人说系统初始化要初始化堆栈,即正确给堆栈指针sp赋值,但是却从来没有看到有人解释,为何要初始化堆栈。所以,接下来的内容,就是经过一定的探究,试图来解释一下,为何要初始化堆栈,即:
  为何C语言的函数调用要用到堆栈,而汇编却不需要初始化堆栈。

  要明白这个问题,首先要了解堆栈的作用。
  关于堆栈的作用,要详细讲解的话,要很长的篇幅,所以此处只是做简略介绍。
  总的来说,堆栈的作用就是:保存现场/上下文,传递参数。

  1.保存现场/上下文

  现场,意思就相当于案发现场,总有一些现场的情况,要记录下来的,否则被别人破坏掉之后,你就无法恢复现场了。而此处说的现场,就是指CPU运行的时候,用到了一些寄存器,比如r0,r1等等,对于这些寄存器的值,如果你不保存而直接跳转到子函数中去执行,那么很可能就被其破坏了,因为其函数执行也要用到这些寄存器。
  因此,在函数调用之前,应该将这些寄存器等现场,暂时保持起来,等调用函数执行完毕返回后,再恢复现场。这样CPU就可以正确的继续执行了。

  在计算机中,你常可以看到上下文这个词,对应的英文是context。那么:
  1.1.什么叫做上下文context
  保存现场,也叫保存上下文。
  上下文,英文叫做context,就是上面的文章,和下面的文章,即与你此刻,当前CPU运行有关系的内容,即那些你用到寄存器。所以,和上面的现场,是一个意思。

  保存寄存器的值,一般用的是push指令,将对应的某些寄存器的值,一个个放到堆栈中,把对应的值压入到堆栈里面,即所谓的压栈。
  然后待被调用的子函数执行完毕的时候,再调用pop,把堆栈中的一个个的值,赋值给对应的那些你刚开始压栈时用到的寄存器,把对应的值从堆栈中弹出去,即所谓的出栈。

  其中保存的寄存器中,也包括lr的值(因为用bl指令进行跳转的话,那么之前的pc的值是存在lr中的),然后在子程序执行完毕的时候,再把堆栈中的lr的值pop出来,赋值给pc,这样就实现了子函数的正确的返回。

2.传递参数

  C语言进行函数调用的时候,常常会传递给被调用的函数一些参数,对于这些C语言级别的参数,被编译器翻译成汇编语言的时候,就要找个地方存放一下,并且让被调用的函数能够访问,否则就没发实现传递参数了。对于找个地方放一下,分两种情况。
  一种情况是,本身传递的参数就很少,就可以通过寄存器传送参数。
  因为在前面的保存现场的动作中,已经保存好了对应的寄存器的值,那么此时,这些寄存器就是空闲的,可以供我们使用的了,那就可以放参数,而参数少的情况下,就足够存放参数了,比如参数有2个,那么就用r0和r1存放即可。(关于参数1和参数2,具体哪个放在r0,哪个放在r1,就是和APCS中的“在函数调用之间传递/返回参数”相关了,APCS中会有详细的约定。感兴趣的自己去研究。)
  但是如果参数太多,寄存器不够用,那么就得把多余的参数堆栈中了。
  即,可以用堆栈来传递所有的或寄存器放不下的那些多余的参数。

3.举例分析C语言函数调用是如何使用堆栈的

  对于上面的解释的堆栈的作用显得有些抽象,此处再用例子来简单说明一下,就容易明白了:
  用:

  arm-inux-objmp –d u-boot > mp_u-boot.txt
  复制代码

  可以得到mp_u-boot.txt文件。该文件就是中,包含了u-boot中的程序的可执行的汇编代码,
  其中我们可以看到C语言的函数的源代码,到底对应着那些汇编代码。

  下面贴出两个函数的汇编代码,
  一个是clock_init,
  另一个是与clock_init在同一C源文件中的,另外一个函数CopyCode2Ram:
贷款记录在征信保留几年? 安徽徽商城有限公司公司简介 安徽省徽商集团新能源股份有限公司基本情况 安徽省徽商集团有限公司经营理念 2019哈尔滨煤气费怎么有税? 快手删除的作品如何恢复 体育理念体育理念 有关体育的格言和理念 什么是体育理念 万里挑一算彩礼还是见面礼 绿萝扦插多少天后发芽 绿萝扦插多久发芽 扦插绿萝多久发芽 炖牛排骨的做法和配料 网络诈骗定罪标准揭秘 “流水不争先”是什么意思? mc中钻石装备怎么做 为什么我的MC里的钻石块是这样的?我想要那种。是不是版本的问题?如果是... 带“偷儿”的诗句 “君不见巴丘古城如培塿”的出处是哪里 带“奈何”的诗句大全(229句) 里翁行()拼音版、注音及读音 带“不虑”的诗句 “鲁肃当年万人守”的出处是哪里 无尘防尘棚 进出口报关流程,越详细越好。谢谢大家指教。 双线桥不是看化合价升多少就标多少的吗?为什么CL2+2KI=2KCL+I2中I失... 出师表高锰酸钾有画面了吗 2021年幼儿园新学期致家长一封信 电脑屏幕一条黑线怎么办? 销售代理商销售代理商的特点 商业代理商业代理的特征 如何看微信有没有开通微众银行 为什么微众没有开户 微众银行怎么开户 微众银行APP开户流程是什么? 唐古拉山海拔唐古拉山海拔是多少 怎么看待取消跳广场舞的人的退休金 如何选购新鲜的蓝田水柿? 恭城水柿柿树作用 创维洗衣机使用教程 创维全自动洗衣机怎么使用 自动开门器 狗羊属相婚姻相配吗 3岁的小孩不会说话怎么办 3岁孩子不会说话,应该挂什么科? 3岁小孩不会说话正常吗 鹿茸炖乌鸡怎么做? 新型冠状肺炎吃什么药可以预防 冰箱上电后一直响 食品生产许可证编号开头为“ G”。 库存过期香精 什么是栈? 栈的初始状态为负数为什么表示栈为空? 二级计算机怎么理解栈中的初始状态? 栈的初态为什么是top=m+1 想知道栈的初始状态,栈的top是什么意思,,12-14题看不大懂,请大佬说详细点 华为fla-tl10是什么型号 华为trt-tl10是什么型号 荣耀9和stf-tl10/6gb ram有什么区别 手机设置里显示型号是STF-TL10,IMEI:865982030550365,官方标称是什么型号 华为nova6pro机身颜色普罗旺斯适合男生用吗! 华为Nova有几个版本 华为Nova版本区别与参数详解 华为nova6紫色怎么变成正常色? 华为nova哪个颜色好看 华为nova青春版手机都有什么颜色 华为nova 青春版有什么颜色 华为nova机身有几种颜色 华为nova68+256G有些什么颜色? 华为nova有几款颜色 哪个好看 华为nova有几种颜色?面板是黑的还是白的 华为nova有几种颜色 栈的初始化(c++) 栈的初始化 int initstack 是什么意思 设栈的存储空间为S(1:m),初始状态为top=m+1 怎么理解? c语言中为什么栈的初始化时候栈顶指针要指向-1? C语言数据结构 栈的初始化 数据结构栈的初始化 C语言数据结构中,关于栈的初始化的问题! c语言栈的初始值存在哪里 C语言初始化栈的问题! 一个栈的初始状态为空。首先将元素5,4,3,2,1 依次入栈,然后退栈一次,再将元素A,B,C,D 依次入... 在栈中 Top被初始化为 0和-1的区别是? 设栈的顺序存储空间为s(1:m),初始状态为top=m+1 小米8可以上内存卡吗? 小米8能扩容吗? 小米8青春版可以加内存卡吗? 小米8se怎么插内存卡 小米8内存卡放置方法 小米8可以插内存卡吗 对于手机内存拓展需了解 小米8自己加内存 小米8支持多大的内存卡
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com