実行ファイル出力と終了処理
実行ファイル出力
ELF形式の情報とコンパイルされた機械語がObj配列に格納されると、Obj配列の内容をファイルに出力します。出力したファイルに |cm 組み込みコマンドで実行属性を付加します。
10860 :--------------------- 10870 : ファイル出力 10880 :--------------------- 10890 !=^BinWrite
12150 :------------------------------------------------- 12160 : 実行ファイル出力 12170 : E : binary 先頭 12180 : P : ファイルサイズ 12190 :------------------------------------------------- 12200 ^BinWrite 12210 +bfz 12220 b=z z=z+256 12230 {=Obj }=Obj+P 12240 b*=X 12250 (*=b : write executable 12260 / "file : " $*=b " " ?=P " bytes " / 12270 f=b f*=" 755 " f=f+% f*=X 12280 |cm*=b 12290 -zfb 12300 ] 12310 :
終了処理
最後にコンパイル結果と経過時間を画面出力します。
10900 :--------------------- 10910 : 終了 10920 :--------------------- 10930 ;=D>0 / "Line" / 10940 ;=D>0 !=^PrintLine 10950 ;=D>0 / "Label" / 10960 ;=D>0 !=^PrintLabel / 10970 ;=R[0]<>R[1] " Pass1 " ?=R[0] / "<> Pass2 " ?=R[1] / 10980 " header size " ?=H['A']-H['B'] / 10990 " library size " ?=F[34]*4 / 11000 " code size " ?=R[1]-(F[34]*4) / 11010 " code starts from 0x" ??=H['B']+(F[34]*4) / 11020 " code ends at 0x" ??=H['B']+R[1]-1 / 11030 " Source Lines " ?=W / 11040 " Source Labels " ?=K / 11050 " File Name " $*=X / 11060 " File Size " ?=P / 11070 " heap size free : " ?=*-R-8 " / " ?=*-& " bytes" / 11080 " To check code, run : " 11090 "objdump -d --start-address=0x" ??=H['B']+(F[34]*4) " " $*=X / 11100 !=^TimerStop 11110 #=-1 11120 :
実行例
rvtl で rvtlc.vtl をコンパイル
インタープリタである rvtl で rvtlc.vtl をコンパイルします。rvtl が実行するスクリプトが rvtlc.vtl、rvtlc.vtl が処理するソースも rvtlc.vtl となります。コンパイル後の実行ファイル名はソースの拡張子を「elf」に変更したものになります。今回は「rvtlc.elf」が実行ファイルとなります。
jm:~/rvtlc$ rvtl rvtlc.vtl - rvtlc.vtl <0415> #=1 read 2219 lines file : rvtlc.elf 46688 bytes Change Permission header size 128 library size 5284 code size 41166 code starts from 0x080494A4 code ends at 0x08053571 Source Lines 2219 Source Labels 163 File Name rvtlc.elf File Size 46688 heap size free : 349828 / 701144 bytes To check code, run : objdump -d --start-address=0x080494A4 rvtlc.elf time:3.894597sec <0415> ~ jm:~/rvtlc$
rvtlc.elf で rvtlc.vtl をコンパイル
インタープリタでコンパイルして得られたrvtlc.elfを使って、rvtlc.vtl をコンパイルします。この場合も rvtlc.elf が出力ファイル名となります。
jm:~/rvtlc$ ./rvtlc.elf rvtlc.vtl read 2219 lines file : rvtlc.elf 46688 bytes header size 128 library size 5284 code size 41166 code starts from 0x080494A4 code ends at 0x08053571 Source Lines 2219 Source Labels 163 File Name rvtlc.elf File Size 46688 heap size free : 429996 / 781312 bytes To check code, run : objdump -d --start-address=0x080494A4 rvtlc.elf time:0.115790sec jm:~/rvtlc$
実行速度を比較すると 3.894597sec/0.115790sec = 33.635003。30倍以上高速化されています。
rvtlc.elfで作成したrvtlc.elfでrvtlc.vtl をコンパイル
さらに実行形式のコンパイラでコンパイルされた rvtlc が正常にコンパイルできることを確認します。
jm:~/rvtlc$ ./rvtlc.elf rvtlc.vtl read 2219 lines file : rvtlc.elf 46688 bytes header size 128 library size 5284 code size 41166 code starts from 0x080494A4 code ends at 0x08053571 Source Lines 2219 Source Labels 163 File Name rvtlc.elf File Size 46688 heap size free : 429996 / 781312 bytes To check code, run : objdump -d --start-address=0x080494A4 rvtlc.elf time:0.114221sec
実行形式のrvtlc.elfでrvtlc.vtlをコンパイルして得られたrvtlc.elfでも正常にコンパイルできることが確認できました。
まとめ
最初 に書いた事を繰り返します。
1) オリジナル言語を考える 今回は rvtl という TINY BASIC言語系の言語です。 2) その言語のインタープリタを作成 アセンブラで rvtl のインタープリタを作成しました。 3) その言語のコンパイラのソースをインタープリタでコンパイル rvtl言語でコンパイラのソースを書いてインタープリタでコンパイルすると rvtl言語コンパイラの実行形式のファイルができます。 4) コンパイルされたコンパイラでコンパイラのソースをコンパイル 実行形式のrvtlコンパイラでコンパイラのソースがコンパイルできることを 確認します。この時点からrvtlコンパイラのソースのコンパイルに rvtlインタープリタは不要になります。 5) コンパイラのソースを改良してコンパイル rvtlコンパイラだけでrvtlコンパイラの改良や言語自身の改良が可能です。
プログラム言語を作成するには、インタプリタやコンパイルを記述するためのプログラム言語が必要となります。「タマゴが先か、ニワトリが先か」という問題と同じです。「ニワトリではない鳥がニワトリのタマゴを産んだ」が答えとなります。
[前] [目次]