我发现无论是我的教科书还是我的谷歌搜索技能都没有给我一个正确的答案。我知道这取决于操作系统,但一般来说:会发生什么和 为什么?
我的教科书说系统调用会导致操作系统进入内核模式,因为它尚未存在。这是必需的,因为内核模式可以控制 I/O 设备和特定进程地址空间之外的其他事物。但是如果我理解正确的话,切换到内核模式并不一定意味着进程上下文切换(您将进程的当前状态保存在 CPU 之外的其他地方,以便其他进程可以运行)。
为什么是这样?我有点想一些“管理”进程被切换进来并处理来自进程的系统调用并将结果发送到进程的地址空间,但我想我错了。我似乎无法理解在内核模式和内核模式之间的切换中实际发生了什么,以及这如何影响进程在 I/O 设备上运行的能力。
非常感谢 :)
编辑:奖励问题:库调用一定会以系统调用结束吗?如果不是,您是否有任何不以系统调用结束的库调用示例?如果是,为什么我们要调用库?
最佳答案
历史上,系统调用是通过中断发出的。 Linux 使用了 0x80
vector 和 Windows 使用了 0x2F
vector 访问系统调用并将函数的索引存储在 eax
中登记。最近,我们开始使用 SYSENTER
和 SYSEXIT
指示。用户应用程序运行于 Ring3
或用户空间/用户模式。 CPU 在这里非常棘手,从内核模式切换到用户模式需要特别小心。它实际上涉及在发出名为 iret
的特殊指令时欺骗 CPU 认为它来自用户模式。 .从用户模式返回内核模式的唯一方法是通过中断或已经提到的 SYSENTER/EXIT
指令对。它们都使用一种称为 TaskStateSegment
的特殊结构。或 TSS
简称。这些允许 CPU 找到内核堆栈的位置,所以是的,它本质上需要一个任务切换。
但究竟发生了什么?
当您发出系统调用时,CPU 会查找 TSS
, 得到它的 esp0
value,它是内核的堆栈指针并将其放入 esp
.然后 CPU 在另一个特殊结构 InterruptDescriptorTable
中查找中断向量的索引。或 IDT
简而言之,并找到一个地址。这个地址就是处理系统调用的函数所在的地址。 CPU 压入标志寄存器、代码段、用户堆栈和下一条指令的指令指针,该指令位于 int
之后。操作说明。在系统调用被服务后,内核发出 iret
.然后 CPU 返回到用户模式,您的应用程序继续正常运行。
所有的库调用都以系统调用结束吗?
好吧,他们中的大多数都这样做,但也有一些没有。例如看看memcpy
其余的。
关于operating-system - 当操作系统进入内核模式时究竟会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20038636/