CC-RLでは変数や定数にfar属性,near属性,またはsaddr属性のいずれかの属性を指定した上で,各々を各属性と同じ名前を持つ領域,すなわち,far領域,near領域,またはsaddr領域に配置します。
変数や定数をアクセスする命令のサイズはこの順番で小さくなるため,変数や定数をnear属性(またはsaddr属性)にしてnear領域(またはsaddr領域)に配置するとコードサイズが小さくなります。
一方,領域のサイズもこの順番で小さくなるため,変数や定数の合計サイズが大きい場合には各変数をどの領域に配置するかの優先順位を付ける必要があります。
以下では,各属性の指定方法,各領域とその配置方法及びについて詳しく説明します。
変数や定数にはオプションやキーワードを使って,属性を指定します。
詳細は各オプションやキーワード,および,「2.6.6 near,farとの関係」を参照してください。
long x; //near属性 long __near y; //near属性 long __far z; //far属性 const int c; //near属性 const int __near d; //near属性 const int __far e; //far属性 char __saddr s; //saddr属性 |
long x; //near属性 long __near y; //near属性 long __far z; //far属性 const int c; //far属性 const int __near d; //near属性 const int __far e; //far属性 char __saddr s; //saddr属性 |
一般的には,変数の静的参照回数が多い変数を,命令サイズが小さな領域に割り付けるとプログラム全体のコードサイズが小さくなります。
しかし,命令サイズが小さな領域はその領域サイズも小さいため,効率的に使う必要があります。
そこで,領域1バイトあたりの削減効率を最大化することを考えると,変数の静的参照回数を変数サイズで割った値が大きい変数ほど命令サイズが小さな領域に割り付けると良いとわかります。
ここで,変数の静的参照回数は,オブジェクト・コード上の参照回数を指し,Cソース上の参照回数とは異なります。
RL78では変数参照に使える命令は1バイトや2バイトのアクセス幅のみのため,例えば4バイト変数を参照するには2つの命令が必要になります。
したがって,Cソース上で4バイト変数を1回参照すると,オプジェクト・コード上では2回参照することになります。
オブジェクト・コード上の参照回数はリンカに-show=reference オプションを指定することで表示することができます。
far領域は,saddr領域やnear領域を含む全領域となります。
アドレスが0xFFE20から0xFFF1Fまでの領域をsaddr領域と呼びます。
このアドレス範囲に配置したsaddr属性変数はサイズが最も小さい命令でアクセスします。
saddr領域は,特殊機能レジスタ(SFR)の一部や汎用レジスタも含みます。
アドレスが0xF0000から0xFFE1Fまでの領域をnear領域と呼びます。
この領域には内部RAM,ミラー領域,データ・フラッシュ・メモリを含みます。
このアドレス範囲に配置したnear属性変数はsaddr領域に次いでサイズが小さい命令でアクセスします。
near領域は,拡張特殊機能レジスタ(2nd SFR)も含みます。
saddr領域やnear領域を含む全領域をfar領域と呼びます。
この領域には内部RAM以外のRAMやミラー領域以外のコード・フラッシュ・メモリ内の定数領域も含みます。
このアドレス範囲に配置したfar属性変数はサイズが最も大きい命令でアクセスします。
各変数や定数を含むセクションの配置アドレスをリンク・オプションを使って指定することによって,変数や定数を各領域に配置します。
.saddr領域に配置するデフォルトのセクションは.sbssと.sdataです。 |
near領域に配置するデフォルトのセクションは.bss,.data,および.constです。 |
far領域に配置するデフォルトのセクションは.bssf,.dataf,および.constfです。 |