内核堆栈和用户堆栈有什么区别?

use*_*306 10 stack operating-system kernel

在同一个程序中使用两个不同堆栈的需求是什么?陷阱如何将当前的程序堆栈从用户堆栈更改为内核堆栈?完成系统调用后,它如何回到用户堆栈?

每个进程都有内核和用户堆栈吗?

Bra*_*rad 12

每个CPU有一个"内核堆栈".每个进程都有一个"用户堆栈",尽管每个线程都有自己的堆栈,包括用户和内核线程.

"陷阱如何改变堆栈"实际上非常简单.

由于中断,CPU会更改进程或"模式".中断可能由于许多不同原因发生 - 发生故障(如错误或页面错误),或物理硬件中断(如来自设备) - 或定时器中断(例如在使用进程时发生)所有这些都分配了CPU时间").

无论哪种方式 - 当调用此中断时,CPU寄存器都保存在堆栈中 - 所有寄存器 - 包括堆栈指针本身.

通常,然后调用"调度程序".然后,调度程序选择另一个要运行的进程 - 恢复其所有已保存的寄存器,包括堆栈指针,并从它停止的位置继续执行(存储在返回地址指针中).

这称为"上下文切换".

我正在简化一些事情 - 比如如何保存和恢复内存管理上下文,但这就是主意.它只是保存和恢复寄存器以响应中断 - 包括"堆栈指针"寄存器.

  • 在Windows中,每个线程(甚至用户模式线程)都有自己的内核堆栈.内核堆栈绝对不是每个CPU. (8认同)

小智 10

有2个堆栈,因为有2个CPU执行上下文.用户模式堆栈将满足您的程序关于为函数,局部变量,返回地址等创建堆栈帧.当CPU将上下文切换到内核模式时,例如在系统调用执行期间,它需要访问内核内存和数据结构然后切换到使用它的内核堆栈.是的,我认为Unix使用每进程内核堆栈.


luo*_*uan 7

我在大学学习OS,我们的项目基于哈佛构建的OS/161。所以我的答案都是基于这个操作系统。

在 OS/161 中,每个线程有2 个堆栈- 一个用于用户/应用程序,一个用于内核程序。

1. 在同一个程序中使用两个不同的堆栈有什么需要?

假设我们只在应用程序模式下使用堆栈。由于内存空间是由多个线程共享的,如果其他线程不小心覆盖了内核使用的地址,那么内核可能会崩溃,从而导致操作系统非常脆弱。

2、trap如何将当前程序栈从用户栈变为内核栈?

在 OS/161 中,trap 用于从应用程序传输到内核。有三种机制可以调用 trap:系统调用、异常和中断。内核堆栈中的陷阱帧用于保存当前线程上下文。

以下是详细过程(来自UWaterloo CS350的讲义):

  • 当上述机制之一发生时,硬件将 CPU 切换到特权模式并将控制转移到预定义的位置,内核处理程序应位于该位置。

  • 内核处理程序创建一个陷阱帧并使用它来保存应用程序线程上下文,以便可以在 CPU 上执行处理程序代码。

  • 就在内核处理程序完成执行之前,它从陷阱帧恢复应用程序线程上下文,然后将控制权返回给应用程序。

3. 系统调用完成后如何回到用户栈?

上面的过程也清楚地解释了这个问题。


Gab*_*abe 4

拥有单独的内核堆栈的原因之一是内核需要一个地方来存储用户模式代码无法触及的信息。这可以防止在不同线程/进程中运行的用户模式代码意外或恶意地影响内核的执行。