2.2.1 はじめに
複雑なソフトウェアプロジェクトは、多くの場合小さなプログラムユニットに分けられます。これらのサ ブプログラムは、プログラマのチームが同時進行で記述することができる他、開発の過程で再利用する目 的で記述することもできます。as88アセンブラでは、プログラムを小さな部品、つまりモジュールに分割す るための擬似命令をサポートしています。シンボルをあるモジュールに対してローカルに定義することに より、他のモジュールでもそのシンボルに関係なくシンボル名を使用できるようにすることができます。
またコードとデータを、別のセクションに入れることもできます。これらのセクションは、異なるモジュー ルが、これらのセクションの異なる部分を実装できるような方法で、命名することができます。これらの セクションは、ロケータがメモリ内にロケートできるため、メモリの配置の問題は、アセンブリプロセス 以降に先送りされます。独立したモジュールを使用すれば、他のモジュールをアセンブルし直さずにモ ジュールを変更できるようになります。こうすることによって、開発プロセスの所要時間を短縮すること ができます。
2.2.2 モジュール
モジュールとは、プロジェクトの個別の実装部分を示します。それぞれのモジュールは、個別のファイル で定義されます。各モジュールは、それぞれ個別にアセンブルされます。INCLUDE擬似命令を使用するこ とで、共通の定義およびマクロをそれぞれのモジュールにインクルードすることができます。mk88ユー ティリティを使用すると、モジュールファイルとインクルードファイルの依存関係を指定できるため、モ ジュールが依存するファイルを変更した後、適切なモジュールのみをアセンブルし直すことができます。
2.2.2.1 モジュールおよびシンボル
モジュールでは、他のモジュールまたはそのモジュールで定義されているシンボルを使用することができ ます。モジュールで定義されているシンボルは、ローカル(他のモジュールがアクセスできない)にするこ ともグローバル(他のモジュールがアクセスできる)にすることもできます。モジュールの外部のシンボル は、EXTERN擬似命令で定義します。シンボルをLOCAL擬似命令で定義するか、SET擬似命令またはEQU 擬似命令で定義すると、ローカルシンボルになります。グローバルシンボルは、ラベルになるか、GLOBAL 擬似命令で明示的にグローバルと定義したシンボルになります。
2.2.3 セクション
セクションとは、コードとデータの再配置可能なブロックを示します。セクションは、DEFSECT擬似命令 で定義され、名前が付けられます。セクションにはさまざまな属性があり、この属性によって、近くまた は遠くのメモリにある定義済みの開始アドレスに配置するようロケータに指示することができます。また、
このセクションを他のセクションで重ね書きできることを指示することも可能です。使用できる属性の詳 細については、DEFSECT擬似命令の説明を参照してください。セクションは、一度定義した後、SECT擬似 命令で起動します。リンカは、異なるモジュール間をチェックし、セクションの属性が適切でない場合、
エラーメッセージを出します。またリンカは、一致するすべてのセクション定義を1つのセクションに連結 します。そのため、コンパイラが生成したすべての".text"セクションは、1つの".text"チャンクにリンクさ れ、1つの断片としてロケートされます。この命名方式を使用することにより、リンクフェーズで、すべて のコードまたはデータの断片を集めて1つの大きなセクションにすることができます。すでに定義されてい るセクションを参照するSECT擬似命令は、継続と呼ばれます。この場合、名前のみを指定することができ ます。
2.2.3.1 セクション名
アセンブラは、オブジェクトファイルをリロケータブルIEEE-695オブジェクトフォーマットで生成します。
アセンブラは、オブジェクトファイルで、セクションを使用してコードおよびデータのユニットをグルー プ化します。すべてのリロケータブル情報は、セクションの開始アドレスとの相対値になります。ロケー タは、セクションに絶対アドレスを割り当てます。セクションは、コードまたはデータの最小単位で、ソー スファイルをアセンブルした後、メモリ内の特定のアドレスに移動させることができます。コンパイラに よる必要性のため、アセンブラは、特定の特性を割り当てるために適切な属性を持つ複数の異なるセクショ ン(読み取り専用データを持つセクション、コードを持つセクションなど)をサポートする必要があります。
DEFSECT sect̲name, sect̲type [, attrib] ... [AT address]
セクションは、宣言してからでないと使用できません。DEFSECT擬似命令では、属性を付けてセクション を宣言します。セクション名は、どのような識別子でもかまいません。ただし通常のセクション名には"@"
文字を使用することはできません。この文字は、重ね書き可能なセクションを作成するときに、アセンブ ラとリンカによって使用されます。これについては、後で説明します。
セクションの型には、次のようなものを使用することができます。
sect̲type : CODE¦DATA これは、セクションがロケートされるメモリ(CODE、DATA)を定義するものです。
セクションの属性には、次のようなものを使用することができます。
attrib : SHORT コードメモリの最初の32K内に収まるか、データメモリの最初の64K内に収まります。
FIT 100H セクションを256Bページに収める必要があります。
FIT 8000H セクションを32KBページに収める必要があります。
FIT 10000H セクションを64KBページに収める必要があります。
CLEAR プログラムのスタートアップ時にセクションをクリアします。
NOCLEAR セクションがプログラムのスタートアップ時にクリアされません。
INIT スタートアップ時に初期化データがROMからRAMへコピーされます。
OVERLAY セクションが、重ね書きの名前を持っている必要があります。
ROMDATA セクションが、実行可能コードの代わりに、データを含んでいます。
JOIN セクションをグループ化します。
オフになっていない限り、ツールチェーンのスタートアップコードは、CLEAR属性を持つデータセクショ ンをクリアする必要があります。これらのセクションには、イニシャライザが指定されていないデータ空 間割り当てが含まれます。CLEARセクションは、プログラムのスタートアップ時にゼロにセット(クリア)
されます。NOCLEAR属性を付けることによって、セクションから、この初期化を免除することができま す。これは、すべてのセクションのデフォルトの状態にもなっています。
SHORT属性が付いたセクションは、(CODEセクションの場合)S1C88のコードメモリの最初の32Kバイト、
(DATAセクションの場合)データメモリの最初の64Kバイト内に割り当てなければなりません。SHORT属性 の付いたセクションがこの領域に割り当てられない場合、ロケータが警告を出します。
JOIN属性を使用すると複数のセクションをグループ化することができます。たとえば、同じデータページ にもっと多くのセクションをロケートしたい場合、この属性を使用することができます。
OVERRAY属性を指定すると、セクションを重ね書き可能にすることができます。重ね書き可能なのは、
DATAセクションのみです。この属性が他の型のセクションと組み合わされている場合、アセンブラがエ ラーを報告します。重ね書きされたセクションをプログラムのスタートアップ時に初期化するのは無意味 であるため(重ね書きされたデータを使用するコードの場合、最初の使用時にそのデータが定義どおりの状 態になっていると見なすことはできない)、OVERRAYが指定された場合、NOCLEAR属性が暗黙的に定義 されます。重ね書き可能なセクション名は、次のように構成されます。
DEFSECT "OVLN@nfunc", DATA, OVERLAY, SHORT
↑ ↑
プール名 関数名
リンカは、セクションを同じプール名で重ね書きします。リンカは、DATAセクションとXDATAセクショ ンのどちらを重ね書きできるか決定するために、呼び出しグラフを構築します。互いに呼び出しあう関数 の場合、それに属するセクションのデータは重ね書きすることができません。コンパイラは、リンカがこ の呼び出しグラフを構築するための情報を持つ擬似命令(CALLS)を生成します。CALLS擬似命令は、(簡略 化すると)次の構文になります。
CALLS 'caller̲name', 'callee̲name'[, 'callee̲name' ]...
関数main()で、近いメモリおよび呼び出しnfunc()に重ね書き可能なデータ割り当てがある場合、次のセ クションと呼び出し情報が生成されます。
DEFSECT "OVLN@nfunc", DATA, OVERLAY, SHORT DEFSECT "OVLN@main", DATA, OVERLAY, SHORT CALLS 'main', 'nfunc'
ATキーワードを使用する宣言でアドレスが指定されている場合、セクションは絶対セクションになりま す。アセンブラは、セクションの内容を指定アドレスに置くようロケータに命令する情報をオブジェクト ファイルに生成します。重ね書き可能なセクションを絶対セクションにすることはできません。ATキーワー ドがOVERLAYセクション属性と組み合わされて使用されている場合、エラーが報告されます。
セクションは、宣言された後、SECT擬似命令によって起動および再起動することができます。
DEFSECT ".STRING", CODE, ROMDATA SECT ".STRING"
_l101: ASCII "hello world"
データまたはコードを生成するすべての命令と疑似命令は、アクティブセクション内になければなりませ ん。セクション定義や起動を行わずにコードやデータを開始すると、警告が出されます。
2.2.3.2 絶対セクション
絶対セクション(つまり開始アドレスを持つDEFSECT擬似命令)は、定義しているモジュールのみで続行す ることができます(継続)。このようなセクションが、他のモジュールで同じ方法によって定義されている 場合、ロケータは、2つのセクションを同じアドレスに置こうとします。そのため、ロケータエラーが発生 します。絶対セクションが複数のモジュールで定義されている場合、セクションをリロケータブルとして 定義し、その開始アドレスをロケータ記述(.dsc)ファイルで定義する必要があります。また、オーバーレ イセクションは、絶対セクションとして定義することができません。
2.2.3.3 グループ化セクション
複数のセクションを1ページ内にグループ化しなければならない場合、JOINセクション属性を使用します。
JOIN属性は、ページサイズを定義するFIT属性と一緒に使用しなければなりません。ある特定のグループ に対するページサイズは、そのグループ内のすべてのセクションで同じになる必要があります。たとえば、
2つのデータセクションを同じ64Kページに置かなければならない場合、以下のように記述することができ ます。
DEFSECT ".data1@group", DATA, JOIN, FIT 10000H SECT ".data1@group"
また2番目のセクションでは、次のようにします。
DEFSECT ".data2@group", DATA, JOIN, FIT 10000H SECT ".data2@group"
セクションは、セクション名に使用されている拡張子ごとにグループ化されます。そのため、定義は次の ようになります。
DEFSECT "sect@group", DATA, JOIN, FIT 10000H
↑ ↑
セクション名 ジョイングループ名