堆栈指针和分段

时间:2012-07-20 19:22:15

标签: assembly operating-system stack

  

可能重复:
  How does a stack memory increase?

让我们想一下使用分段的操作系统 我的问题是:os是否接受了堆栈指针的每个变化 并且非常(或非常不稳定地)在物理记忆中分配/释放空间
或者它使用一个聪明的策略来分配比你需要的内存更多的内存,只有当释放的内存达到一定数量时才解除内存?

我希望我的讨论足够明确。

2 个答案:

答案 0 :(得分:1)

如果我理解你的要求是正确的,答案如下:

操作系统在创建进程开始时为堆栈分配一定量的空间。当堆栈操作发生时,处理器自动递增和递减堆栈指针,并且软件递减堆栈指针以为临时数据分配空间(如在函数调用中)。它会递减,因为堆栈实际上会减少,如果指针超出给定的分配空间,则会发生堆栈溢出。分配的空间量因系统而异。操作系统可以做的唯一可能的“技巧”是分页,它可以将内存标记为已分配,但在软件使用它之前不会实际分配物理内存。这称为请求分页,并且具有更多应用程序,而不是堆栈。

答案 1 :(得分:0)

另外还要添加上述答案。
 进程的堆栈向堆增长,操作系统必须确保这些区域不重叠 当堆栈需要更多空间(即堆栈指针指向非法/未分配的内存)时,会导致页面错误。

  1. 编写页面错误的中断操作符,使其读取当前堆栈指针,查找是否由于堆栈增长而发生页面错误的最大限制,还是因为我们触及了虚拟内存的一部分(属于代码/数据)尚未映射到物理内存(请求分页)。
  2. 如果由于堆栈增长而发生页面错误
    • 我们检查是否达到了堆栈的最大大小,在GNu / Linux系统上是8Mb(默认)
    • 接下来我们看看是否通过分配新页面来堆叠它是否与堆重叠
    • 接下来可能会进行一些更健全的检查。
    • 如果以上所有内容都通过,则分配新页面
    • 如果其中一个检查失败,则会出现seg fault或stack overflow,具体取决于实现。
  3. 如果我们在上一步中分配了一个新页面,则更新错误进程的堆栈指针,将新映射添加到错误进程的页表中,并且页面错误处理程序将控制权返回到错误指令,通常是push或pusha(在程序集中,x86)。
  4. PS:以上步骤来自我的基于pintos OS的UG OS课程的操作系统分配,实际步骤可能会有所不同(在像OS这样的操作系统中很复杂)。这是link到堆栈的一部分增长见第4.3.3节。