栈和栈帧

【摘自Linux/Unix系统编程手册】

函数的调用和返回使栈的增长和收缩呈线性。X86-32体系架构上的Linux(和大多数其它Linux和Unix的实现),栈驻留在内存的高端并向下增长(朝堆的方向)。专用寄存器--栈指针(stack pointer),用于跟踪当前栈顶。每次调用函数时,会在站上新分配一帧,每当函数返回时,再从栈上将此帧移去。

虽然栈向下增长,但仍将栈的增长端称为栈顶,因为抽象地来说,情况本就如此。栈的实际增长方向是个属于硬件范畴的实现细节。在HP PA-RISC的Linux实现中,栈的增长方向就是向上的。

就虚拟内存而言,分配栈帧后,栈段的大小将会增长,但在大多数Linux实现中,释放这些栈帧好,栈的大小并未减少(在分配新的栈帧时,会对这些内存重新加以利用)。当谈论栈段的增长和收缩时,只是从逻辑视角来看待栈帧在栈中的增减情况。

有时,会用用户栈(user stack)来表示此处所讨论的栈,以便与内核栈区分开来。内核栈是每个进程保留在内核内存中的内存区域,在执行系统调用的过程中供(内核)内部函数调用使用。(由于用户栈驻留在不受保护的用户内存中,所以内核无法利用用户栈来达成这一目的)

每个(用户)栈帧包括如下内容:

  • 函数实参和局部变量:由于这些变量都是在调用函数时自动创建的,因此在C语言中称其为自动变量。函数返回时将自动销毁这些变量(因为栈帧会被释放),这也是自动变量和静态(以及全局)变量主要的语义区别:后者与函数执行无关,且长期存在。
  • 函数调用的链接信息:每个函数都会用到一些CPU寄存器,比如程序计数器,其指向下一条将要执行的机器语言指令。每当一函数调用另一函数时,会在被调用函数的栈帧中保存这些寄存器的副本,以便函数返回时能为函数调用者将寄存器恢复原状。

因为函数能够嵌套调用,所以栈中可能有多个栈帧(若一函数递归调用自身,则函数在栈中将有多个栈帧)。

时间: 2024-11-01 08:34:35

栈和栈帧的相关文章

C++中栈的出栈,入栈规则:A,B,C,D,E

考题: 栈底至栈顶一次存放元素 ABCD 在第五个元素E入栈之前  栈中元素可以出栈,则出栈序列可能是_____a d___________. a.  ABCED b.  DBCEA   c.  CDABE   d.  DCBEA 分析: 1.假定进栈序列是从小到大排练的(即A<B<C<D<E),则出栈序列中不可能有  “大小中”这种序列,因为在“大数”出栈后,在栈中“中数”是在“小数”上面的,所以只能是先出“中数”再出“小数”2.出栈序列中如包含下列序列则是错误的:CAB,DAB

栈1--出栈序列

栈1--出栈序列 一.心得 二.题目及分析 进栈序列是123,求所有的出栈序列 用回溯法做 三.代码及结果 1 #include <iostream> 2 #include <stack> 3 using namespace std; 4 5 stack<int> sta; 6 int ans[4]; 7 int total=0; 8 9 void print(){ 10 total++; 11 cout<<total<<": &quo

压栈出栈遍历栈实例代码

#include<stdio.h> #include<stdlib.h> #include<malloc.h> typedef struct Node//定义一个链表结构体 { int data; struct Node* pNext; }NODE,*PNODE; typedef struct Stack//定义一个栈结构体 { PNODE pTop; PNODE pBottom; }STACK,*PSTACK; void initStack(PSTACK); void

栈及栈的链式存储结构(栈链)

栈:线性结构,后进先出.栈(Stack)是一种特殊的线性表(顺序表,链表)只在表尾进行删除和插入操作. 注意:对于栈来说,表尾称为栈的栈顶(top),表头称为栈底(bottom). 栈也是线性结构的一种特例.与队列不同,他只有一个口,只能从这里读或者写数据,这个口称为栈顶(top).栈是一种先进后出的数据结构.先进来的元素会放入栈底,而后进来的元素被放在它的上面,最后进来的元素的上面的位置,称为栈顶. 栈所提供的操作比一般的线性表要少很多,只提供:初始化.销毁.判断是否为空.求栈的长度.清空栈.

栈及栈的C++实现

栈:栈是一种数据结构,栈里元素的添加和删除只能在栈的末端进行.它是一种“后进先出”(LIFO)的数据结构. 栈的操作: initializeStack:初始化栈,使得为一个空栈. destroyStack:清空栈里所有的元素,使得为一个空栈. isEmptyStack:判断栈是否为空,如果为空,返回true,否则返回false. isFullStack  : 判断栈是否溢出,如果溢出,返回true,否则返回false. push : 添加一个新的元素到栈顶.前提是栈存在,且栈没有溢出. top

顺序栈——双栈(Dual Stack)

顺序栈--双栈(Dual Stack) 1. 双栈的概念 1.1 双栈的定义 双栈是指两个顺序栈,是一种特殊的顺序栈. 1.2 双栈中各元素的逻辑及存储关系 双栈共享一个地址连续的存储单元.即程序同时需要两个栈时,可以定义一个足够的栈空间,该空间的两端分别设为两个栈的栈底,用bottom[0]=-1和bottom[1]=maxSize指示. 压入数据时,让两个栈的栈顶top[0]和top[1]都向中间伸展,如果指示栈顶的指针top[0]+1等于另一个栈顶的指针top[1]时两栈已满. 每次进栈时

ACM/ICPC 之 用双向链表 or 模拟栈 解“栈混洗”问题-火车调度(Tshing Hua OJ - Train)

本篇用双向链表和模拟栈混洗过程两种解答方式具体解答“栈混洗”的应用问题 有关栈混洗的定义和解释在此篇:手记-栈与队列相关 列车调度(Train) Description Figure 1 shows the structure of a station for train dispatching. Figure 1 In this station, A is the entrance for each train and B is the exit. S is the transfer end.

顺序栈的初始化入栈出栈以及打印栈的信息

使用的开发工具CLion CLion 2017.2.1 Build #CL-172.3544.40, built on August 2, 2017Licensed to CLion EvaluatorExpiration date: September 15, 2017JRE: 1.8.0_152-release-915-b6 x86_64JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.oMac OS X 10.12.4   1 #include

07.栈(一)栈的存储结构及操作

一.栈 1.栈(stack):是限定仅在表尾进行插入和删除操作的线性表.其中,允许插入和删除的一端被称为栈顶(top),另一端被称为栈底(bottom),不含任何数据元素的栈被称为空栈.栈又被称为后进先出(Last In First Out)的线性表,简称LIFO结构. 栈的插入操作为进栈,栈的删除操作为出栈. 2.栈的抽象数据类型 ADT 栈(stack) Data 同线性表.元素具有相同类型,相邻元素具有前驱和后继关系. Operation InitStack(*S):初始化操作,建立一个空