RL78コンパイラコーステキスト要旨(2回目)

RL78コンパイラコーステキスト、2013年5月22日Rev.1.06版の要旨、2回目の今回は、スタック設定です。

スタック設定の要旨

スタックとは、RAM内にある特別な領域のことです。関数の呼出し時に、最低限必要なデータを、このスタック領域へ積み重ねて一時保存し、呼出された関数の処理が終わったら、そのデータを使って呼出し側の関数へ戻ります。使い終わったデータは、積み重ねから取り除きますので、スタック領域は、関数呼出し毎に使用サイズが増えたり減ったりします。

最低限必要なデータとは、1.関数の引数で汎用レジスタに割り付かないもの、2.関数の戻り番地、3.使用する汎用レジスタの退避領域、4.関数の局所変数で汎用レジスタに割り付かないもの、5.コンパイラ処理上必要になったワーク領域、などです。

関数を呼ぶだけで、これらデータの一時保存や、このような複雑な処理をしているのです。しかも、関数呼出し経路や、割込み順位に応じて使用サイズが変わるので、最大スタックサイズを求めるのも大変です。しかし、CubeSuite+では、スタック見積もりツールが用意されていて、自動的に(コンパイラ設定でアセンブル・ファイル出力の「はい」変更は必要)関数毎の使用サイズが求まります。このツールを使えば、プログラマが意図した関数の呼び出し経路かどうかの確認もできます。

マイコンソフトの出荷時には、「必ずスタックサイズを求め、必要サイズ分を1回目で説明したリンク・ディレクティブを使って確保すること。この確保値は自動的に更新されないので、スタックサイズを反映させるのは、プログラマの責任」とテキストには明記されています。例えば、再帰呼出し関数などを使ってスタックが不足するような場合は、異常終了などを引き起こしますので、スタック領域の不足は避けなければなりません。テキストには、スタックサイズを削減する方法も記載されています。

では、出荷時前のデバッグ時はこのスタックサイズがどのように確保されているかというと、リンカがRAM領域の一番大きいGap(空き領域)を見つけ、自動的にスタック領域を確保しています。確保領域は、ビルド・ツール生成ファイル:*.symファイルの、@STBGN~@STEND間です。@STBGN>@STENDなので、スタック領域が上位アドレスから下位側へ使われることが判ります。一方、コンパイラ領域は、下位アドレスから上位側へ使われます。RAMに両方の領域が隣り合わせに配置されても、領域侵犯の可能性が少ない方法です。

対象マイコンのスタック領域確保の必要性

RAM 4KB/5.5KBの対象マイコンを、シングル・チップで動作させるシステムでは、ここで解説したスタック領域確保は不要と思います。スタック見積もりツール算出のスタックサイズよりも大きければ、リンカが確保する最大Gapの場所が、スタック領域としては最適で、リンカ任せでも大丈夫と考えるからです。

システム拡張/変更に対して内臓RAMの空きが少なくなりスタックサイズを削減する場合、リンカの代わりにプログラマ自身でセクション配置をする場合の方法として知っておけば十分でしょう。対象マイコンでRAM空き領域が少なくなった時には、経験上、このような対処療法より、より大容量RAMを持つ機種への変更の方が安全、かつ、費用対効果も高いのでお勧めです。

コメントを残す