我的意思是,在操作系统API的深处,对于程序从OS请求的每个基本功能,是否存在中断“调用”?
0x80
,其中包含要在寄存器中调用的函数的索引。中断和异常处理程序以及系统调用通常使用相同的机制来实现。这样做的原因是,在所有这些情况下,都必须将控制权转移到内核中,并且必须在处理事件之前保留许多寄存器,并在事件处理之后恢复许多寄存器。中断处理发生在内核中,无处不在(罕见的CPU不支持中断),并且是中断处理,异常处理和系统调用的自然选择。
此外,在某些情况下,最好从内核中调用系统调用。
例如,在Windows中,内核代码通常可以选择调用ZwFoo()
或NtFoo()
,其中Foo
是一些有意义的函数名称,Zw
和Nt
是名称前缀,用于区分两者Foo()
的版本。如果选择ZwFoo()
,则直接调用Foo()
。 OTOH,如果选择NtFoo()
,则控件首先必须通过系统调用(AKA陷阱)机制/代码,然后才能到达实际的Foo()
。两种版本之间的选择与Previous Mode
有关。
Previous Mode
上的几句话...内核代码受信任。用户代码不受信任。当从用户模式调用Foo()
时,内核将尽力验证所有不受信任的输入,并在执行请求的操作之前检查所有权限是否到位。那就是应该的样子。现在,内核本身有时需要调用Foo()
。如果它代表自己调用Foo()
,则无需进行许多严格的检查。但是,如果它使用用户模式(以及所有不受信任的模式)的输入代表用户代码调用Foo()
,则必须进行这些检查。因此,根据情况,内核调用ZwFoo()
或NtFoo()
。调用NtFoo()
时,将PreviousMode
设置为UserMode
,这表明必须进行上述检查。调用ZwFoo()
时,对于用户模式调用者,PreviousMode
保留为UserMode
;对于内核模式调用者,其设置为KernelMode
。因此,用户模式调用者无法避免检查,但是内核可以选择是否执行检查(必要时)或不需要(不需要时)。