【问题标题】:Why Operating System need to create its own stack?为什么操作系统需要创建自己的堆栈?
【发布时间】:2017-01-21 07:25:11
【问题描述】:

我正在阅读 grub 手册中的 multiboot 规范。在阅读本手册时,我发现了一个规范。该规范中提到“当引导加载程序调用 32 位操作系统时,操作系统映像必须在需要时立即创建自己的堆栈。”。我不明白这个规范,为什么操作系统需要创建堆栈。

【问题讨论】:

  • 多重引导规范说您不应该依赖 ESP 中存在适当的堆栈指针值。只要您不需要使用任何堆栈操作(例如:推送、弹出调用等)就可以了。由于许多多引导引导程序最终会执行 CALL 指令(如果您尝试调用 C 函数则很典型),那么无效的堆栈指针可能会导致错误(除非您使用身份映射启用了分页),但是如果您的程序在运行时无意中覆盖了堆栈,则可能会被破坏。设置自己的临时堆栈意味着您知道它在哪里。
  • 您可以在 BSS 段中创建一个临时堆栈,因为它不会占用您的代码空间。然后将 ESP 设置为您分配的内存区域的末尾(因为堆栈向下增长)。这通常使用多重引导对象中的汇编代码完成,并且在第一个 push/pop/call(或任何其他需要将某些内容压入堆栈的指令)指令之前完成。
  • 由于您可能正在做操作系统开发,因此可以在#OSDev IRC chat 中提出此类问题。那里的许多人在操作系统开发方面都有很多经验,包括多引导问题。那里的许多人都在开发自己的两个操作系统,有些人已经使用了很多年。
  • 谢谢。现在,从你的回答中,我明白了,这个规范想说什么。

标签: linux-kernel operating-system nasm bootloader systems-programming


【解决方案1】:

这是一个规范。规范通常会“保证”合作组件可以依赖什么状态,以及它可能依赖什么。

在这种情况下,规范说加载的操作系统可能不会假定堆栈指针的内容引用可用作堆栈的内存区域。这并不意味着堆栈指针实际上指向可用作堆栈的内存区域(它可能)。这意味着您最好不要依赖它,因为加载器的未来版本可以免费将寄存器用于其他用途。然后,您的操作系统在被该更高版本加载时可能会崩溃。

话虽如此,可能还有其他原因。例如,在 x86 中,堆栈指针 (RSP/ESP/SP) 相对于 SS 段寄存器的内容进行解释。当改变模式时——比如,从实模式到保护模式——段寄存器的结构和解释发生了变化;因此,在一种模式下有意义的堆栈指针值可能指向另一种模式下完全不同的内存区域(甚至没有有效的内存区域)。

【讨论】:

  • 使用多重引导规范,您可能会假设它们已经处于 32 位保护模式,因为这是兼容多重引导的引导加载程序将为您做的一件事。那是假设你没有手动跳回实模式
猜你喜欢
  • 2016-10-03
  • 2012-05-04
  • 1970-01-01
  • 2014-05-27
  • 2020-09-26
  • 1970-01-01
  • 2011-04-06
  • 2016-05-18
  • 2014-11-25
相关资源
最近更新 更多