LSI-C86 講座
lcc86
コマンドラインオプション
- -O は -O (最適化有効) か -O0 (最適化無効) の2つだけ
- -B をつけると // がコメントになる (B 言語の B?)
- あとは gcc と大体同じ
lcc86 はプリプロセッサ(cpp)、コンパイラ(cf, cg86)、アセンブラ(r86)の各コマンド群を呼び出すフロントエンド的な役割があるようだ。 lcc86 が呼ぶ cpp は (LSI path)/bin/cpp を期待しているものの、 path の都合で /mingw/bin/cpp が呼び出されてしまう。プリプロセッサの出力内容は全く知らないのだが、どうやら問題ないらしい。
(LSI path)/bin/cpp を呼び出したい場合は lcc86.exe をバイナリファイルで開いて cpp の文字列を無理矢理変えるなどすれば、かなり無茶だが直せる。
r86
コマンドラインオプションは出力ファイルを指定するぐらい。
命令は r86 専用名称になっている場合があり、 8086 の opcode が通らないことがあるのでマニュアルを参照すべし。
C 関数名/変数名はソースで定義した名前の末尾に _ が付加される。C から呼ぶ場合は _ はいらないが、アセンブラからは _ がいるので注意(はまった)。
C の関数の引数の与え方は、かなり複雑なのでまじに使うならマニュアル参照。面倒なので引数、型共に void の C の関数に jmp する命令だけにした。割り込み対応も最低限だけアセンブラで書くようにする。
lld
コマンドラインオプション
- -M -g あたりを出しておくとリンク情報が出る
- -Tsegment address とすると segment のアドレスを指定できる。
- -Fh で ihex, -Fe で exe など出力フォーマットの設定が出来る。
segment は gcc でいう section のこと。標準状態で text, data, bss がある。 text は CSEG (code segment), data と bss は DSEG (data segement) となりどうも CPU のセグメントレジスタと関連しているようだ。ここらへんは動かして様子を見たい。
data, bss に関しては const は使えるものの, rodata がないので ROM に配置すべきデータも data となってしまう。グローバル変数は初期化せずに bss に飛ばして RAM に張るので、 data は実質的に const があってもなくてもかわらないことに...
現時点で data と bss のアドレスをかなり離したのだが stack overflow! とエラーが出てる。そもそも stack は別の segment だよな? よくわからん。
-F オプションでは exe を出してしまって先頭についてるヘッダの 0x200 byte を削り落とせば純粋な ROM 向けバイナリになるようだ。未使用データは 0x00 で埋まっているので実 ROM に焼く場合は 0xff にしたほうが好ましい。*1 今回は FPGA 内蔵 RAM に埋めるので問題ないはず。
*1:うちの安物ライターは 0xff でも書き込みシーケンスをやってるおばかさん。