モニタおよびユーザープログラムのリンクは若干複雑である。これについて解説する。
モニタがコンパイルされる際にリンカに渡されるパラメータを下にしめす。
h8300-hms-ld romcrt0.o monitor.o int.o ... eep_srec.o cmd_eeprom.o -lm -lc -lgcc -o monitor.coff
説明を簡単にする為に幾つかのオプションは省略している。
他の多くのツールと異なり、リンカに与えるパラメータの順序には意味がある。
最初にmonitor.oやint.oなどのオブジェクトファイルが指定されている。これらのオブジェクトファイルはこの順に処理され、monitor.coffに出力される。
その後にライブラリの指定が続く。ここで注意するべきことは、この時点で未定義のシンボルのみがライブラリのアーカイブから取り込まれるということだ。
ライブラリは多くのオブジェクトファイルのアーカイブであり、取り込みはオブジェクトファイル単位で行なわれる。
オブジェクトファイルの前にライブラリを指定しても、ライブラリからは何も取り込まれない。
C言語(少なくともGCC)では、標準ライブラリ内の関数をユーザーの関数で置き換えることが出来る。
あまり一般的に使われている用語では無い気がするが、これをインターポジショニングと呼ぶ(らしい)。
H8monitorではこの機能を利用して標準関数をH8で使えるようにしている。
printf等の出力関数は最末端で_writeという関数を呼び出している。モニタに含まれているwrite.cは標準ライブラリに含まれている同名のファイルをインターポジショニングし、シリアルコンソールへの出力が行なわれるように変更している。
標準ライブラリがリンクされる時_write関数は定義済みであるので、標準ライブラリに含まれるwrite.oは取り込まれず、標準ライブラリに含まれる他の関数(printf等)もユーザーが定義した_write関数を呼び出すようになる。
モニタに含まれるsyscalls.cおよびsbrk.cもwrite.cと同様に標準ライブラリの関数をインターポジショニングするものである。
ユーザープログラムがコンパイルされる際にリンカに渡されるパラメータを下にしめす。
/usr/local/bin/h8300-hms-ld crt0.o main.o service.o --just-symbols=../../monitor-1.2-3069/monitor.coff -lm -lc -lgcc ... -o sample.coff
途中に--just-symbols=../../monitor-1.2-3069/monitor.coffなる節がある。
これは、monitor.coffとリンクを行ないながらも出力にmonitor.coffは含まれないことを示す。
モニタはユーザープログラムが実行されるより先にROM上にあるから、出力にmonitor.coffを含む必要はない。
この後にライブラリのリンクが続くが、monitor.coffが先にリンクされているのでmonitor.coffに含まれているオブジェクトが改めて取り込まれることはない。
つまり、ユーザープログラムはモニタとともにROMに焼き込まれている標準ライブラリを優先的に使用するので、ユーザープログラムが標準ライブラリによって肥大化することを抑制できる。
モニタにはfunctions.listなるファイルが含まれ、sin,printf等の、モニタで使用されていないがユーザープログラムでの利用頻度が高いと思われる関数が列挙されている。
functions.listはリンカスクリプト(ldscript/3069.x)からincludeされるファイルであり、ここで列挙されたシンボルは未定義として扱われて標準ライブラリから取り込まれてmonitor.coffに出力される。
H8の内蔵フラッシュROMにはかなり余裕があるので、必要な関数があればfunctions.listに追加すると良い.