Linuxカーネルでファイルを開くと、ほとんどすべてのファイルに外部関数とマクロがたくさん#indef
ありますが、#ifndef
ファイルに70個以上のヘッダファイルが含まれている場合は、コンパイル時にどのようにすべての関数とマクロを正確にマップしますか.c/.h
?
これはどのくらい正確かつ迅速に行われますか? GCCはこれらのタスクだけを担当していますか、それともこれらすべてのタスクを実行できる他のプログラムはありますか?
答え1
いいですね。あなたの質問に完全に答えるためには、Cプログラミングの入門に関する本を読んでください。タネンバウムそして龍の本。 Cから学びましょう。
始めるための基本事項:Cプログラムをコンパイルするとき、伝統的にいくつかの異なる手順があります。 (最新のコンパイラはフェーズ間最適化を実行できます。)フェーズは次のとおりです。
- パイオニア。これには、インクルードファイル、#ifdef、#define、およびマクロ拡張が含まれます。
- 翻訳者。これはCコードをより機械レベルの中間表現(時にはアセンブラ)に変換します。
- アセンブラ。これは中間表現を実際の機械語コードに変換します。
- リンカー。これにより、すべてのフラグメントがまとめられ、メモリの問題が処理されます。複数のリンクを渡すことができます。
gccは上記のすべてを行うことができますが、カーネルが複雑であるため、他のツールが使用され、ほとんどはカーネルによって異なります。
カーネルはいくつかの点で別のプログラムですが、ハードウェアに応じてシステムコールを含む多くの違いがあります。
一般的なLinuxプログラムでカーネルにファイルを開くなどの操作を要求した場合
- プログラムはライブラリ関数を呼び出します。
- ライブラリ関数はシステムコールを実行します。
- カーネルはディスパッチテーブルからシステムコールを探します。
- カーネルは認証確認を行います。
- カーネルは自分の仕事をします。
- カーネルは結果をライブラリ関数として返します。
- ライブラリ関数は結果をプログラムに返します。
これは毎秒数百回発生する可能性があります。