使用程序堆栈是否涉及系统调用



我正在学习操作系统理论,我知道堆分配涉及一个特定的系统调用,我知道编译器通常会针对这个请求进行优化,而不是事先需要的。

但我找不到有关堆栈分配的信息。那它呢?每当您从中读取或写入时(例如,当您调用带有某些参数的函数时(,它都会涉及一个特定的系统调用?或者还有其他一些机制可能不涉及系统调用?

通常,当操作系统启动程序时,它会检查可执行文件的标头,并为各种内容安排不同的区域(可执行文件代码的区域和可执行文件数据的区域等(。这包括建立一个初始堆栈(以及更多内容,例如查找共享库和进行动态链接(。

操作系统完成所有这些操作后,可执行文件就会开始执行。在这一点上,您已经有了用于堆栈的内存,并且可以在不进行任何系统调用的情况下使用它。

注意1:如果创建线程,那么可能会有一个系统调用来创建线程,并且该系统调用可能会为新线程的堆栈分配内存。

注2:典型地;虚拟存储器";(您的程序所看到的(和";物理存储器";(硬件所看到的(;在这两者之间,操作系统通常会做很多技巧来提高性能,避免浪费物理内存,并隐藏资源限制(这样你就不必太担心物理内存耗尽(。其中一个技巧是在不分配任何实际物理内存的情况下分配虚拟内存(例如,对于大型堆栈(,然后在首次修改虚拟内存时分配物理内存。其他技巧包括各种";交换空间";方案和内存映射文件。这些技巧依赖于CPU代表程序生成的请求(例如页面故障异常(,这些请求不是系统调用,但具有类似的("要求内核做某事"(特性。

注3:以上所有内容都取决于哪个操作系统。不同的操作系统做事情的方式不同。我仔细地选词,例如";典型地;意味着大多数现代操作系统都像我描述的那样工作(但"典型"并不意味着所有可能的操作系统都是这样工作的;有些操作系统不像我描述的一样工作(。

否,堆栈是正常内存。从进程的角度来看,这并没有什么区别(还有讨厌的安全漏洞,你返回了一个指向堆栈中数据的指针,但堆栈现在已经改变了

正如Brendan所写,操作系统将在程序加载时为进程设置堆栈。但是,如果您访问堆栈中未分配的页面(例如,如果您的堆栈正在增长(,内核可能会自动为您分配一个新的堆栈页面。(与尝试在堆中分配新内存时没有太大区别,并且程序空间上没有更多可用内存:但在这种情况下,您显式地执行系统调用,告诉内核您想要更多的堆内存(。

您会注意到,堆栈通常朝一个方向发展,而堆(分配的内存(则朝另一个方向(通常朝着另一个(发展。所以,如果你的程序需要更多的堆栈,你就有空间,但如果你的编程不需要太多堆栈,你可以使用内存来制作巨大的数组。或者相反:如果你做了很多递归,你会分配很多堆栈(但你可能需要更少的堆内存(。

另外两个考虑因素:CPU可能有特殊的堆栈指令。但你可以把它们看作语法糖(你可以用MOV模拟PUSH和POP。用JMP模拟CALL和RET(以及模拟PUSH与POP(。

内核可能会为了自己的目的使用一个特殊的堆栈(对于中断来说尤其重要(。

最新更新