ユーザ・プログラム向けの初期化処理は次の要素で構成されます。
コンパイラが生成するコードが使用するスタック領域です。CC-RHは,スタック・ポインタ(sp)の値が4バイト境界に位置していることを前提としたコードを生成し,スタック領域をアドレスの0x0番地方向に成長させます。そのため,.stack.bssセクションの0xffffffff番地側の端が4バイトに整列している必要があります。
ハードウェア向け初期化ルーチンから分岐してくるラベル(アドレス)です。
スタック・ポインタ,gpレジスタ,epレジスタの3つを初期化します。
mov #_stacktop, sp ; set sp register mov #__gp_data, gp ; set gp register mov #__ep_data, ep ; set ep register |
__gp_data, __ep_dataの詳細は,8.4 シンボルを参照してください。
Cソースやアセンブリ・ソース上で定義した変数領域を初期化します。初期化する対象のセクションのアドレスを格納したテーブルを用意し,ライブラリ関数_INITSCT_RHにテーブルのアドレスを渡して呼び出します。
初期値ありデータセクションの初期化テーブルは次の書式で記述します。
初期値ありデータセクションの初期化先セクションは,最適化リンカの-romオプションで指定します。
.section ".INIT_DSEC.const", const .align 4 .dw #__s.data, #__e.data, #__s.data.R .dw #__s.sdata, #__e.sdata, #__s.sdata.R |
初期値なしデータセクションの初期化テーブルは次の書式で記述します。
.section ".INIT_BSEC.const", const .align 4 .dw #__sセクション名1, #__eセクション名1 .dw #__sセクション名2, #__eセクション名2 : .dw #__sセクション名n, #__eセクション名n |
初期化テーブルの先頭アドレス,末尾アドレスを_INITSCT_RHの引数で渡し,初期化を実行します。
それぞれの初期化テーブルの先頭は4バイトに整列している必要があります。
mov #__s.INIT_DSEC.const, r6 mov #__e.INIT_DSEC.const, r7 mov #__s.INIT_BSEC.const, r8 mov #__e.INIT_BSEC.const, r9 jarl32 __INITSCT_RH, lp ; initialize RAM area |
_INITSCT_RHの使用方法は7.4.11 RAMセクション領域初期化関数を参照してください。
PSW.CU0ビットに1を設定して,FPUを使用可能に設定します。
FPSRレジスタに対してFPUの動作モードの設定を行います。
ロックステップ機能を使用する準備として,FPEPCレジスタの初期化を行います。
stsr 5, r10, 0 ; r10 <- PSW movhi 0x0001, r0, r11 or r11, r10 ldsr r10, 5, 0 ; enable FPU movhi 0x0002, r0, r11 ldsr r11, 6, 0 ; initialize FPSR ldsr r0, 7, 0 ; initialize FPEPC |
FPUを搭載しないマイクロコントローラでは,これらの記述を削除してください。
PSW.UMビットに1を設定して,ユーザ・モードへ遷移します。
main関数への分岐と同時に設定を反映させるために,PSWではなくFEPSWへ書き込み,feret命令でFEPSWからPSWへ設定を反映させます。
stsr 5, r10, 0 ; r10 <- PSW xori 0x0020, r10, r10 ; enable interrupt movhi 0x4000, r0, r11 or r11, r10 ; supervisor mode -> user mode ldsr r10, 3, 0 ; FEPSW <- r10 |
FEPCレジスタにmain関数のアドレスを,r31レジスタにmain関数の実行が終わった後に実行したい_exit関数のアドレスを設定して,feret命令を実行することでmain関数へ分岐します。