つまり、オペレーティング システム API のコアの奥深くで、プログラムが OS に要求する基本機能ごとに割り込み「呼び出し」があるのでしょうか?
2 に答える
はい、そのような割り込みが非常に頻繁にあります。
割り込みハンドラーと例外ハンドラー、およびシステムコールは、多くの場合、同じメカニズムを使用して実装されます。この理由は、これらすべての場合に、制御をカーネルに転送する必要があり、イベントの処理前に多数のレジスタを保持し、処理後に復元する必要があるためです。割り込み処理はカーネルで発生し、どこにでもあり(まれなCPUは割り込みをサポートしません)、割り込み処理、例外処理、およびシステムコールには当然の選択です。
さらに、場合によっては、すでにカーネル内からシステムコールを呼び出すことが望ましい場合もあります。
たとえば、Windowsでは、カーネルコードに、またはのいずれZwFoo()
かを呼び出すオプションがありますNtFoo()
。ここで、Foo
は意味のある関数名でありZw
、Nt
は名前のプレフィックスであり、の2つのバージョンを区別しますFoo()
。ZwFoo()
が選択されている場合は、Foo()
直接呼び出されます。OTOHNtFoo()
が選択されている場合、コントロールは最初にシステムコール(別名トラップ)メカニズム/コードを通過する必要があり、その後、実際に到達しFoo()
ます。2つのバージョンのどちらを選択するかは、と呼ばれるものと関係がありPrevious Mode
ます。
いくつかの言葉Previous Mode
...カーネルコードは信頼されています。ユーザーコードは信頼されていません。がFoo()
ユーザーモードから呼び出されると、カーネルはすべての信頼できない入力を検証し、要求された処理を実行する前にすべてのアクセス許可が設定されていることを確認するために最善を尽くします。そうあるべきです。これで、カーネル自体がを呼び出す必要がある場合がありますFoo()
。それがそれ自体に代わって呼び出す場合Foo()
、多くの厳密なチェックを行う必要はありません。Foo()
ただし、ユーザーモードからの入力(および信頼されていないすべて)を使用してユーザーコードに代わって呼び出す場合は、これらのチェックを行う必要があります。したがって、状況に応じて、カーネルは ZwFoo()
またはを呼び出しますNtFoo()
。がNtFoo()
呼び出されるとPreviousMode
が設定されUserMode
、前述のチェックの必要性を示します。がZwFoo()
呼び出されると、PreviousMode
UserMode
ユーザーモードの呼び出し元の場合はそのまま、またはKernelMode
カーネルモードの呼び出し元の場合はに設定されます。したがって、ユーザーモードの呼び出し元はチェックを回避できませんが、カーネルはチェックを実行するか(必要な場合)、実行しないか(そうでない場合)を選択できます。
少なくとも Linux には syscall があります。ユーザー空間がカーネルから何かを必要とする場合0x80
、レジスタで呼び出したい関数のインデックスを使用してソフトウェア割り込みが発行されます。