次のコンテンツはhttps://mp.weixin.qq.com/s/CXhc71UZtbdbAo15xbJ6_Qから複製されてい ます
阿波はオリジナルプログラムを書くのが大好き張 ソーストラベル 2019-04-24
システムコールに関連するプリエンプティブスケジューリングについては前章で説明しますので、システムコールの基本を理解しておく必要があります。
システムコールとは、オペレーティングシステムによって提供されるAPIを呼び出すために同様の関数呼び出しを使用することを指します。
概念的にはシステムコールは関数呼び出しに似ていますが、本質的に異なります。オペレーティングシステムのコードはカーネルアドレス空間にあり、ユーザーコードを実行するときのCPUの特権レベルは低く、アクセスに最高の優先順位は必要ありません。カーネルアドレス空間のコードとデータにのみアクセスできるため、オペレーティングシステムが提供する関数を単純な呼び出し命令で直接呼び出すことはできませんが、指定された関数を完了するには、オペレーティングシステムカーネルに入るには特別な命令を使用する必要があります。
さらに、ユーザーコードは、関数名に直接基づいてオペレーティングシステムAPIを呼び出すのではなく、各APIのオペレーティングシステムによって提供される整数に基づいて呼び出す必要があります。AMD64Linuxプラットフォームは、raxレジスタを使用して格納することに同意します。システム呼び出しを行うときのシステム呼び出し番号。最初の6つのシステム呼び出しパラメーターを渡すためにrdi、rsi、rdx、r10、r8、およびr9を使用することに同意します。
一部の読者は、通常のプログラミングではシステムコールを使用しないと言うかもしれません。!実際、使われていないわけではありませんが、その存在を感じませんでした。たとえば、文字列を画面に出力したり、ファイルを開いたり、ファイルの読み取りと書き込みを行ったり、ネットワークプログラミングでソケットを作成したりする最も簡単な方法です。 、すべてがシステムコールを使用します。主に、使用する関数ライブラリまたはパッケージがそれらを関数にカプセル化するため、システムコールの存在を感じません。これらの関数を直接呼び出すだけで済みます。たとえば、次のgoコードがあります。
package main import( "os" ) func main(){ fd、err:= os.Open( "./ syscall.go")//システムコールを使用してファイルが開かれます ... fd.Close()/ /ファイルはシステムコールを使用して閉じられます }
ここでのos.Open()関数とfd.Close()関数は、最終的にはシステムコールを介してオペレーティングシステムのカーネルに入り、対応する関数を完成させます。例としてos.Openを取り上げると、最後に次のアセンブリコードが実行され、openatシステムコールを介してファイルが開かれます。
mov 0x10(%rsp)、%rdi#最初のパラメーター mov 0x18(%rsp)、%rsi#2番目のパラメーター mov 0x20(%rsp)、%rdx#3番目のパラメーター mov 0x28(%rsp)、%r10#4thパラメータ mov0x30(%rsp)、%r8#5番目のパラメータ mov 0x38(%rsp)、%r9#6番目のパラメータ mov 0x8(%rsp)、%rax#システムコール番号rax = 267、openatシステムコール syscallを呼び出す手段#system呼び出し命令、Linuxカーネルに入ります
ここで、コードは最初にopenatシステムコールの6つのパラメータと番号267を対応するレジスタに保存し、次にsyscall命令を使用してカーネルに入り、ファイルを開く機能を実行します。
最後に、この記事がお役に立てば幸いです。記事の右下にある「Looking」をクリックするか、友達のサークルに転送してください。ありがとうございます。