2012-09-19 135 views

回答

2

至少在Linux上有syscalls。当用户空间想要内核中的东西时,会发出一个软件中断0x80以及它想要在寄存器中调用的函数索引。

More here

+0

这就是我需要知道的。在内部深处,由OS IVT处理的软件中断存在问题。 API只是将你这样的东西隐藏起来。谢谢。 –

+1

@ JoAoSilva:已经有好几年了,x86处理器通过'syscall' /'sysenter'指令可以更快地创建系统调用。 glibc使用OS传递给它的信息来选择合适的一个。 – ninjalj

2

是的,有很多时候是这样的中断。

中断和异常处理程序和系统调用通常使用相同的机制来实现。原因在于,在所有这些情况下,必须将控制权转移到内核中,并且必须在处理事件之前保存许多寄存器并将其恢复。中断处理发生在内核中,无处不在(罕见的CPU不支持中断),这是中断处理,异常处理和系统调用的自然选择。

更重要的是,在某些情况下,需要从内核中调用系统调用。

在Windows中,例如,内核代码经常有打电话或者ZwFoo()NtFoo(),其中Foo是一些有意义的函数名和ZwNt的名称前缀的Foo()两个版本之间区别的一个选项。如果选择ZwFoo(),则直接调用Foo()。 OTOH,如果选择NtFoo(),则控制首先必须通过系统呼叫(AKA陷阱)机制/代码,然后才能达到实际的Foo()。这两个版本之间的选择与Previous Mode之类的东西有关。

关于Previous Mode的几句话...内核代码是可信的。用户代码不受信任。从用户模式调用Foo()时,内核将尽最大努力验证所有不受信任的输入,并在执行所请求的操作之前检查是否存在所有权限。这就是它应该如此。现在内核本身有时需要调用Foo()。如果它代表自己调用Foo(),则不需要进行一些严格的检查。但是如果它代表用户代码调用Foo()以及来自用户模式的输入(以及所有不可信),则必须进行这些检查。因此,根据内核调用ZwFoo()NtFoo()。当NtFoo()被调用时PreviousMode被设置为UserMode并且表示上述检查的必要性。当调用ZwFoo()时,对于用户模式调用者,PreviousMode仍为UserMode,对于内核模式调用者,PreviousMode设置为KernelMode。所以,用户模式的调用者不能避免检查,但内核有选择做(当他们需要时)或不(当他们不需要时)。

+0

你可以用'CreateFile'或'ReadFile'替代'Foo'来得到一个想法。 –