为什么不预先分配内存就可以使用堆栈?

进程的虚拟地址空间始于进程的textdatabss段。 在这个堆分配被放置之后,堆向着更大的内存地址增长。 然而,使用堆的一部分的存储器块具有被分配(前valloc等),否则一segfault发生时(或应当发生)。

堆栈从虚拟地址空间中的初始大地址向较小值增长。 据我所知,这个工作没有虚拟内存分配。 在堆不可用的情况下如何在没有事先分配内存的情况下使用堆栈? (它是相同的线性虚拟地址空间。)

据了解, alloca的实现方式与sub esp, <size> alloca类似sub esp, <size> 。 但是堆栈正在使用的虚拟地址空间区域必须在此之前以某种方式分配,对吧?


它以某种方式确实发生段错误。 这是一种“懒惰”的优化。 操作系统会尽可能多地作弊,只要这种差异不是外部可观察的。

但是,陷阱不会像正常的段错误一样产生信号(默认情况下会终止进程)。 而是,操作系统验证是否超出了允许的线程大小,然后从零池中提取新页面。

在Windows下,该机制被命名为“守护页”,我不知道在Linux下有一个类似的命名。 无论哪种方式,一个警卫页在技术上只不过是一个写保护的页面(或一个不存在的页面),它被操作系统记忆为“特殊”,所以当触摸时可能会发生某些特定操作。

这与动态分配( malloc ,称为sbrk )的工作方式非常相似。 分配内存时,只要不访问分配的内存,就不会发生太多事情。 唯一发生的事情是操作系统“记得”你增长了数据段。
如果现在发生故障,操作系统将分别创建页面或将其从零池中取出,并假装它一直在那里。 你永远不知道它之前没有。

链接地址: http://www.djcxy.com/p/62193.html

上一篇: Why can stack usage take place without prior allocating the memory?

下一篇: ASLR and Windows System DLLs for non