私はマイクロコントローラのリアルタイムオペレーティングシステムに非常に興味がありますので、私はそのトピックについて深く研究しています。高レベルでは、私はすべてのOSの一般的なメカニズムを理解しています。関数呼び出しとスタックへのコンテキスト保存
これをよりよく理解するために、私はコンテキストスイッチ以外何もしない非常に単純なカーネルを書くことに決めました。これは私に多くの実用的な質問を追加しました。私はそれらの多くに対処することができましたが、私はまだ主なことと疑問に思っています - 現在のタスクのコンテキスト(すべてのCPUレジスタとスタックポインタ)を保存し、新しいタスクのコンテキストを復元します。
一般に、OSはコンテキストスイッチのすべての動作を保持する機能を使用します(OSContextSwitch()))。 OSContextSwitch()の本体は、主にアセンブリで記述されています(C本体関数のインラインアセンブリ)。しかし、OSContextSwitch()がスケジューラによって呼び出されると、私が知る限り、関数呼び出しでは、CPUレジスタのいくつかがコンパイラによって(実際にはコンパイラによって生成されたコードによって)スタック上に保持されます。
最後に、問題は次のとおりです。どのCPUレジスタが既にコンパイラによってスタックに保存されているかを知っているので、残りの部分を保存することができますか?コンパイラの動作に関係なくすべてのレジスタを保持していれば、明らかにスタックリークがあります。
-
はここでARMのCortex-Mマイコン用の典型的なコンテキストスイッチの実装です。あなたがスタックに物をプッシュするコードを書いているのであれば、スタックからその物をポップするコードを書いているわけではありませんか?あなたがプッシュしたすべてをポップする限り、あなたはOKになるはずです。あなたが不必要なものをプッシュ/ポップするとどうなるのですか? (あるいは、「スタックの漏れ」とはどういう意味ですか?) – kkrambo