我发现我的教科书或谷歌搜索技巧都没有给我一个正确的答案。我知道这取决于操作系统,但总的来说:会发生什么,为什么?
我的教科书说系统调用导致操作系统进入内核模式,因为它已经存在。这是必需的,因为内核模式可以控制I / O设备以及特定进程的地址空间之外的其他内容。但是如果我理解正确的话,切换到内核模式并不一定意味着进程上下文切换(在那里你将进程的当前状态保存在CPU以外的其他进程中)。
这是为什么?我有点想到一些“admin”-process被切换进来并处理来自进程的系统调用并将结果发送到进程的地址空间,但我想我错了。我似乎无法掌握在内核模式切换中实际发生的情况以及这会如何影响进程在I / O设备上运行的能力。
非常感谢:)
编辑:红利问题:图书馆通话是否必然会在系统通话中结束?如果不是,您是否有任何未在系统调用中结束的库调用示例?如果是,为什么我们有图书馆电话?
答案 0 :(得分:5)
历史上系统调用已发出中断。 Linux使用0x80
向量,Windows使用0x2F
向量访问系统调用,并将函数的索引存储在eax
寄存器中。最近,我们开始使用SYSENTER
和SYSEXIT
说明。用户应用程序在Ring3
或用户空间/用户模式中运行。这里的CPU非常非常棘手,从内核模式切换到用户模式需要特别小心。它实际上涉及在发出名为iret
的特殊指令时欺骗CPU以认为它来自usermode。从usermode返回到kernelmode的唯一方法是通过中断或已经提到的SYSENTER/EXIT
指令对。他们都使用一种称为TaskStateSegment
或TSS
的特殊结构。这些允许CPU找到内核堆栈的位置,所以是的,它本质上需要一个任务切换。
但究竟发生了什么?
当您发出系统调用时,CPU会查找TSS
,获取其esp0
值,这是内核的堆栈指针并将其放入esp
。然后,CPU在另一个特殊结构InterruptDescriptorTable
或IDT
中查找中断向量的索引,并找到一个地址。该地址是处理系统调用的函数的位置。 CPU按下int
指令之后的下一条指令,按下标志寄存器,代码段,用户堆栈和指令指针。系统调用完成后,内核会发出iret
。然后CPU返回到用户模式,您的应用程序正常继续。
所有库调用是否都以系统调用结束?
他们中的大多数人都这样做,但也有一些人没有。例如,请查看memcpy
和其他内容。