私の mini os のスケジューラーはアセンブリーで書かれていますが、なぜだろうと思います。この命令は C コンパイラで生成できないことがわかりましたeret
。これは、Nios 以外のプラットフォームや x86 および/または MIPS アーキテクチャに一般化できるものですか? os の一部は常にアセンブリで記述されていると考えているため、システム プログラマがオペレーティング システムを記述するためにアセンブリを知らなければならない理由を探しています。eret
割り込み後にプログラムを元の状態に戻すような特定のアセンブリ命令を生成できない C コンパイラの組み込みの制限がある場合はどうなりますか?
4 に答える
ええ、それだけです。C 言語を使用して生成できない命令があります。また、通常、OS に必要な 1 つまたはいくつかの命令があるため、いくつかのアセンブリが必要です。これは、ほとんどすべての命令セット、x86、arm、mips などに当てはまります。Cコンパイラでは、命令を詰め込むためにインラインアセンブリを実行できますが、言語自体は各命令セットのニュアンスを実際に処理して説明しようとすることはできません. 一部のコンパイラは、コンパイラ固有のものを追加して、たとえば return の割り込みフレーバーを使用して関数を返します。言語やコンパイラをカスタマイズするよりも、必要に応じてアセンブリを記述する方がはるかに簡単であるため、実際には必要ありません。
一般的な答えは、次の 3 つの理由のいずれかです。
その特定のタイプのコードは C で記述できないためです。
eret
「例外からの復帰」命令だと思うので、これに相当する C はありません (ページ フォールト、ゼロ除算などのハードウェア例外は C ではないため)。 /C++ スタイルの例外)。別の例として、タスク切り替え時にレジスタをスタックに保存し、スタック ポインタをタスク制御ブロックに保存することが考えられます。スタック ポインターに直接アクセスできないため、C コードではそれができません。コンパイラは、アセンブラを書く賢い人ほど良いコードを生成しないからです。一部の特殊な操作は、C で記述するのが難しい場合があります。コンパイラは非常に優れたコードを生成しない場合や、アセンブラーで単純なことを実現するためにコードが非常に複雑になる場合があります。
実際の C コードを実行する前に C プログラムをセットアップする必要があるため、C コードの起動はアセンブラーで記述する必要があります。たとえば、スタックポインターやその他のレジスターを構成します。
C で実行できないこと、または実行できる場合は、アセンブリで実行した方が簡単で保守しやすいため、次のようなものがあります。
- 例外からの復帰命令と割り込みからの復帰命令を実行します。
- 特別なプロセッサ レジスタ (プロセッサの状態、メモリ マッピング、キャッシュ構成、例外管理などを制御するレジスタ) の読み取りと書き込みを行います。
- メモリではなくハードウェア デバイスへの接続である特別なアドレスに対して、アトミックな読み取りと書き込みを実行します。
- 上記のように、特定のサイズまたは特性のロードおよびストア命令を特別なアドレスに実行します。(たとえば、特定のデバイスへの書き込みには、通常の 32 ビット ストア命令ではなく、16 ビット ストア命令のみを使用する必要がある場合があります。)
- メモリ バリアまたは順序付け、キャッシュ制御、およびメモリ マップのフラッシュの命令を実行します。
一般に、C 言語は主に計算 (入力の読み取り、計算、出力の書き込み) を行うように設計されており、マシンを制御する (マシン内のすべてのコントロールとデバイスと対話する) ようには設計されていません。