无OS时,RAM的使用可以分为数据、栈和堆区域;有OS时,将RAM分成若干个段,每个任务分配一个段,用于各自的数据、栈和堆区域。
局部变量(Local Variable)是指作用域和生命周期都局限在所在函数或过程范围内的变量,它是相对于全局变量(Global variable)而言的。
编译器在为局部变量分配空间时通常有两种做法:使用寄存器和使用栈。寄存器的访问速度快,但数量和空间有限,所以像字符串或数组不适合分配在寄存器中。编译器通常只会把频繁使用的临时变量分配在寄存器中,比如for循环中的循环变量。
栈上的变量会随着函数的调用和返回而自动分配和释放,所以栈有时也称为自动内存。编译器在编译时,会计算当前的代码块中所声明的所有局部变量所需要的空间,并将其按照内存对齐要求来分配3,一般为4字节对齐。
X86 CPU中定义了栈指针ESP(栈顶)寄存器,和栈基址指针EBP(栈底)寄存器,使用EBP寄存器,函数可以把自己将要使用的栈空间的基准地址记录下来,然后使用这个基地址来引用局部变量和参数。在同一函数内,EBP寄存器的值是保持不变的,这样函数的局部变量就有了一个固定的参照物。
通常,一个函数在入口处将当时的EBP值压入堆栈1,然后把ESP值(栈顶)赋值给EBP2,这样EBP中的地址就是进入本函数时的栈顶地址。
每个函数在栈中所使用的区域称为一个栈帧(stack frame),每发生一次函数调用,便产生一个新的栈帧,当一个函数返回时,这个函数所对应的栈帧被清除。
C语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。
栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构。
C语言
编辑
从逻辑上讲,栈帧就是一个函数执行的环境:函数参数、函数的局部变量、函数执行完后返回到哪里等等。
实现上有硬件方式和软件方式(有些体系不支持硬件栈)
首先应该明白,栈是从高地址向低地址延伸的。每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息。寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低地址)。
注意:EBP指向当前位于系统栈最上边一个栈帧的底部,而不是系统栈的底部。严格说来,“栈帧底部”和“栈底”是不同的概念;ESP所指的栈帧顶部和系统栈的顶部是同一个位置。
————————————————
版权声明:本文为CSDN博主「光明磊」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/happygaohualei/article/details/52692839