《操作系统真象还原》——0.15 局部变量和函数参数为什么要放在栈中

简介: 局部变量,顾名思义其作用域属于局部,并不是像static那样属于全局性的。全局的变量,意味着谁都可以随时随地访问,所以其放在数据段中。而局部变量只是自己在用,放在数据段中纯属浪费空间,没有必要,故将其放在自己的栈中,随时可以清理,真正体现了局部的意义。

本节书摘来自异步社区《操作系统真象还原》一书中的第0章,第0.15节,作者:郑钢著,更多章节内容可以访问云栖社区“异步社区”公众号查看

0.15 局部变量和函数参数为什么要放在栈中

局部变量,顾名思义其作用域属于局部,并不是像static那样属于全局性的。全局的变量,意味着谁都可以随时随地访问,所以其放在数据段中。而局部变量只是自己在用,放在数据段中纯属浪费空间,没有必要,故将其放在自己的栈中,随时可以清理,真正体现了局部的意义。这个就是堆栈框架,提到了就说一点吧,栈由于是向下生长的,堆栈框架就是把esp指针提前加一个数,原esp指针到新esp指针之间的栈空间用来存储局部变量。解释一个概念,堆是程序运行过程中用于动态内存分配的内存空间,是操作系统为每个用户进程规划的,属于软件范畴。栈是处理器运行必备的内存空间,是硬件必需的,但又是由软件(操作系统)提供的。堆是堆,而堆栈就是栈,和堆没关系,只是都这么叫。栈和堆栈都是指的栈,在C程序的内存布局中,由于堆和栈的地址空间是接壤的,栈从高地址往低地址发展,堆是从低地址往高地址发展,堆和栈早晚会碰头,它们各自的大小取决于实际的使用情况,界限并不明朗,所以这可能是堆栈常放在一直称呼的原因吧。

函数参数为什么会放到栈区呢?第一也是其局部性导致的,只有这个函数用这个参数,何必将其放在数据段呢。第二,这是因为函数是在程序执行过程中调用的,属于动态的调用,编译时无法预测会何时调用及被调用的次数,函数的参数及返回值都需要内存来存储,如果是递归调用的话,参数及返回值需要的内存空间也就不确定了,这取决于递归的次数。也许这么说您也依然觉得费解,如果完全明白,需要了解一下编译原理,很多知识都是通过实践后才搞明白的。当然我不是说让您为了搞明白这个问题而去尝试写个编译器。

总之,在函数的编译阶段根本无法确定它会被调用几次,其参数和函数的返回地址也要内存来存储,所以也不知道其会需要多少内存。我想,即使神通广大的编译器设计者可以预测这些了,那提前准备好内存也是一种浪费,而且您想啊,在系统中可用内存紧缺的情况下,提前把内存分配给目前并不使用内存的进程(只因为要存储其函数参数),而眼前需要内存的程序若无内存可用,引用罗永浩老师的一句话:“我想不到比这个更伤感的事情了”所以编译器为了让世界更美好一些,选择将为函数参数动态分配内存,也就是在每次调用函数时才为它在栈中分配内存。

相关文章
|
6月前
|
存储
【OS Pintos】用户程序是如何工作的 | Pintos 运行原理 | 虚拟内存 | 页函数 | 系统调用
【OS Pintos】用户程序是如何工作的 | Pintos 运行原理 | 虚拟内存 | 页函数 | 系统调用
171 0
|
7月前
|
Shell Linux Go
《Linux操作系统编程》第八章 Shell程序设计: shell 语言结构,包括测试、分支、循环、跳转、函数、语句组
《Linux操作系统编程》第八章 Shell程序设计: shell 语言结构,包括测试、分支、循环、跳转、函数、语句组
72 0
|
7月前
|
存储 监控 Linux
《Linux操作系统编程》 第六章 Linux中的进程监控: fork函数的使用,以及父子进程间的关系,掌握exec系列函数
《Linux操作系统编程》 第六章 Linux中的进程监控: fork函数的使用,以及父子进程间的关系,掌握exec系列函数
97 0
|
8月前
|
缓存 Python
Python模块和包:sys模块、os模块和变量函数的使用
Python模块和包:sys模块、os模块和变量函数的使用
81 0
|
10月前
|
Shell PHP Windows
php交互式命令行工具window操作系统安装readline扩展函数实现interactive mode enabled到Interactive Shell
php交互式命令行工具window操作系统安装readline扩展函数实现interactive mode enabled到Interactive Shell
62 0
|
12月前
|
Unix 关系型数据库 API
Python os模块——与操作系统相关的函数
Python os模块——与操作系统相关的函数
131 0
函数 os.date
函数 os.date
127 0
函数 os.time
函数 os.time
131 0
os模块下 getcwd()、chidr()、mkdir()、makedirs()、listdir() 等函数用法介绍
os.getcwd() cwd 全称为 Current Working Directory(CWD) ,即为当前工作路径;os.getcwd() 函数返回的就是当前工作路径