我对第二段内容有所争议。
Process A正在运行,然后被定时器中断打断。硬件会将其寄存器(存放在内核栈上)保存并进入内核(切换到内核模式)。
我不知道有哪个系统可以在中断时将所有寄存器都保存在内核栈上。通常,处理器在中断后只在内核栈上保存最少量的必要状态。然后,中断处理程序会在退出之前保存它想要使用的任何其他寄存器,并在退出时恢复它们。处理器的“从中断或异常返回”指令会自动恢复由中断自动存储的寄存器。
这个描述假设进程没有改变。
如果中断处理程序决定更改进程,则保存当前的寄存器状态(“进程上下文”,大多数处理器都有一个单独的指令)。在英特尔领域中,您可能需要使用多个指令),然后执行另一个指令以加载新进程的进程上下文。
回答您的标题问题“内核栈用于什么?”它在处理器处于内核模式时使用。如果内核没有受保护免受用户访问的堆栈,则系统的完整性可能会受到损害。内核栈往往非常小。
回答你的第二个问题,“将寄存器保存到内核栈和进程结构中的确切目的是什么,为什么需要两者?”
它们用于两个不同的目的。在内核栈上保存的寄存器用于退出内核模式。上下文进程块中保存整个寄存器集,以便更改进程。
我认为你的误解来自源代码措辞的措辞,这表明进入内核模式时将所有寄存器都存储在堆栈上,而不仅仅是必要的最少数量的寄存器,以进行内核模式切换。系统通常只会保存返回到用户模式所需的内容(并且可能在另一个上下文切换中使用相同的信息返回到原始进程)。进程上下文的更改则保存了所有寄存器。
回答额外的问题:
如果中断处理程序需要使用CPU自动未保存的寄存器,它会在进入时将它们推送到内核栈上,并在退出时将它们弹出。中断处理程序必须显式保存和恢复任何[通用]寄存器。 进程上下文块不会被触及。
进程上下文块仅作为实际上下文切换的一部分而被更改。
例如:
假设我们有一台带有程序计数器、堆栈指针、处理器状态和16个通用寄存器的处理器(我知道没有这样的系统),并且所有模式都使用相同的SP。
1. 中断发生。
硬件将PC、SP和PS推入堆栈,并从中断处理程序(从处理器的分派表中)加载SP的地址和PC。
2. 调用中断处理程序。
处理程序编写者决定要使用R0-R3。因此,处理程序的第一行为:
Push R0 ; on to the kernel mode stack
Push R1
Push R2
Push R3
中断处理程序可以执行任何想要执行的操作。
清理工作
编写中断处理程序的人需要做的事情:
Pop R3
Pop R2
Pop R1
Pop R0
REI
- 硬件接管
从内核模式堆栈中恢复PS、PC和SP,然后在中断前继续执行。
为简化起见,我自己设计了一个处理器。某些处理器具有可中断的长指令(例如块字符移动)。这种指令通常使用寄存器来维护其上下文。在这样的系统上,处理器必须自动保存用于在指令中维护上下文所使用的任何寄存器。
除非正在更改进程,否则中断处理程序不会与进程上下文块交互。