C

H8コンパイラの出力するセクション情報

に投稿しました。

何かを調べる時付随するマニュアルを第一に参照するのですが、マニュアルに書かれている内容に疑問があった場合は確かめてみるしか有りませんね。(お付き合いのある特約店やメーカーに問い合わせた方がいいケースがあります)

今回のケースではセクション情報に関することです。

H8マイコン向けのCコンパイラにはセクションの先頭アドレスを取得できる__sectop()と終端アドレスを取得できる__secend()という特殊関数があります。

マニュアルには以下のような説明があったようです。
__sectop <セクション名>の先頭アドレスを参照します。
__secend <セクション名>の末尾+1 アドレスを参照します。

質問されている方が懸念されているのは、この説明に合わせて初期化処理が下記のように行われているからでした。

static void clearblock(void *b_top, void *b_end)
{ // 未初期化データセクションをゼロで初期化します
    char *p;
    for( p=b_top; p<(char *)b_end; p++)
        *p = 0;
}

確かにこの説明ですとセクションサイズが0のとき、__sectop()と__secend()のアドレス差は1以上となってしまうため、サイズが0であるにも関わらず、

 for( p=b_top; p&amp;lt;(char *)b_end; p++)
        *p = 0;

にて0埋めが行われてしまいます。サイズ0のセクションの後ろに何らかの値を持つセクションがあると上書きされてしまう可能性があります。

では実際の__sectop()と__secend()はどうなっているのでしょう。

secend1
ダミーセクション(B_EE)を0xF900に作成しました。
secend2
初期化テーブルに登録しました。これで__secend()の挙動が確認できます。
seend3
コンパイル-リンクと通して出力されたmotファイルの内容です。今回はS1フォーマットになっているので、フォーマットを示すS1、データ長さ2文字、データ配置アドレス4文字、(実際のデータ)、チェックサム2文字の構成になっています。
該当箇所のみスペースで区切ると、データ長さは0B(11バイト)、データ配置アドレス0x0816、データ群が F780 F880 F900 F900,
チェックサムF5でした。

今回、B_EEセクションは0xF900に作っているのでデータ群では先のF900が__sectop()の出力、後ろのF900が__secend()の出力に相当します。

これならセクションサイズ0の時、

 for( p=b_top; p&amp;lt;(char *)b_end; p++)
        *p = 0;

の処理があってもfor文の継続条件を満たすことがないので、初期化処理されずに済みます。

今回の問題はマニュアル側の説明にあった、ということでしょうか。

ABOUT ME
Nozomu.Kon
トータルソフトウェアコーディネーターがあなたのお困りを即時に解決!