スパイス  組み込み制御装置の受注製作

Hitech-Cコンパイラを組み込み用に移植する
平成26年4月22日

C言語の開始処理(続き)
 前回の説明では、ROM化対応を行うためには、コンパイラが一つの変数に対して初期値を置くアドレスとアクセスするアドレスを分けて管理できる必要があることを説明しました。
 では具体的にはどうやってやるか?
 Hitech Cではリンカに細工することで実現しています(Cコンパイラ本体には変更を加えていない様子です)。
リンカの説明書(z80Doc.txtに含まれています)を読むと、コマンドラインオプションの中に”-Pspec”という項目があります。これは先のCコンパイラが管理していたグループ(コンパイラではpsectと呼ぶようです)の配置に関する項目です。P73に具体的な使い方が説明されています。このオプションを使えば、各グループの配置の順番・開始アドレスをそれぞれ初期値アドレスとアクセスアドレスの両方で設定できます。
 プロジェクトの雛形におけるこれらの設定を以下に再度示します。
 デバッグ用
#下の段ではRAMの開始番地を固定できるがその分RAMに無駄が出る
LFLAGS = -M$*.map -Ptext=$(D_ROM),data,bss,stack=$(D_STACK)
製品(ROM化)用
LFLAGS = -M$(PROJECT)_r.map -Ptext=$(R_ROM),data=$(R_RAM)/,bss,stack=$(R_STACK)

 デバッグ用の設定ではtextグループをROMアドレス(実際にはデバッグ用のRAM内のアドレス)に設定し、次にdataグループ、bssグループの順番に配置します。アドレスは指定されていないので、先のグループの配置後に連続して配置されます。アドレスの2重化も指定されていないので行われません。最後にあるのはスタック領域の設定です。SPに設定する初期値をD_STACKに設定します。
 製品(ROM化)用では、dataグループの配置から後が変わっています。まず、textグループはR_ROMアドレスに配置されます。次のdataグループはR_RAMアドレスに配置されますが設定の最後に”/”があるため、初期値とアクセスするアドレスが分けられます。この指定では初期値はtextグループの配置に続いて配置されますが、アクセスはR_RAMアドレスから配置されます。つまり、ここでの設定は下記のようになっています(初期値のアドレスは指定されていないので前の配置に続いて配置されます)。
  <グループ名>=<アクセスアドレスの先頭>/<初期値アドレスの先頭>

 これでdataグループはアドレスの2重化が行われました。では、その次にあるbssグループはどうなるか?
bssグループはアドレスに関して何の指定も無いので、一つ前のdataグループの配置に続いて配置されます。つまり、初期値を置くアドレスとアクセスするアドレスが分けられています。この事実はコンパイル終了後のMAPファイルを見ると分かります。実際にはbssグループは初期値を置かない(そういう仕様のグループです)ので、実害はありません。

 他のコンパイラではどうやっているんだろうと気になったので、GAIO Cコンパイラのヘルプを調べてみました。こちらも同じようにリンクの段階でdataグループのアドレスを2重化しています。LSIC-86でも類似の方法を取っています。どうもこのようなやり方が標準的なようです。


タイトル先頭へ 前へ 次へタイトル末尾へ