* acl4のプログラムのページ0004
-(by [[K]], 2026.02.15)

** (1) アセンブラとは?
-ここではあまり深いことは考えずに「以下のようなテキストファイルを、バイナリファイルに変換するツール」をアセンブラであるとします。
-(今回は実CPU向けのアセンブラではなく、仮想CPU向けのものなので。)
 #define c   R00   // 整数レジスタ
 #define lp  L0000 // ラベル
 
   Lod_RI(c, 0x20)
 Lbl_T(lp)
   Dbg_Putc_R(c)
   Add_RI(c, 1)
   Jlt_RIT(c, 0x7f, lp)
   Dbg_Putc_I('\n')
   Dbg_Ret_I(0)
-acl4を使えば自作アセンブラにプリプロセッサを搭載するのは5分でできるので、当然プリプロセッサ機能は付けます(笑)。
-だからアセンブラだけど、 #define とか好きだけ使えます。
-だからアセンブラだけど、 #define とかを好きだけ使えます。

** (2) p0004a.c [36行] : 即興で作ったアセンブラ
 #define a_Version 1
 #include <acl4.c>
 
 void myPut(Preprocessor_Put0 *w, VecChr *lin) // 実はt0013b.cで作ったやつと同じ.
 {
     if (Preprocessor_isDirective(lin->p, lin->p + lin->n) != 0)
         fprintf(stderr, "[err] %.*s", (int) lin->n, lin->p);
     else
         VecChr_puts(w->dst, lin->p, lin->p + lin->n);
 }
 
 int main(int argc, const char **argv)
 {
     if (argc < 2) return 1;
     Preprocessor pp[1]; Preprocessor_ini(pp);                            // プリプロセッサの初期化.
     pp->put = (void *) myPut;                                            // 出力関数の変更.
     Preprocessor_SourceFiles_addFile(pp->sfs, argv[1], strlen(argv[1])); // 入力ファイルを指定.
     Preprocessor_SourceFiles_addFile(pp->sfs, "a4vm-asm-p0004a.h", 17);  // 最初にこれをインクロードさせる.
     VecChr vc[1]; VecChr_ini(vc); pp->put0->dst = vc;                    // 出力先のオブジェクトを指定.
     Preprocessor_main(pp); Preprocessor_din(pp);                         // プリプロセッサ処理. およびメモリ開放.
 
     Token0 t0[1]; Token0_ini1(t0);
     t0->s = vc->p; t0->s1 = vc->p + vc->n;
     Preprocessor_Eval ev[1]; ev->err = 0;
     for (;;) {
         intptr_t i = Preprocessor_eval(ev, t0, 0x7fff); // プリプロセッサの中にある式の評価ルーチンを流用.
         if (ev->err != 0) break;
         printf("%02x ", i);
         Token1_get(t0);
         if (t0->c != ',') break;
     }
     putchar('\n');
     VecChr_din(vc);
     a_malloc_debugList(_arg);
     return 0;
 }
-適当に作った定義ファイル: a4vm-asm-p0004a.h  (内容は仮です。たぶん全部作り直します。)
 #define R00  0
 #define R01  1
 #define R02  2
 #define R03  3
 #define L0000    0
 #define L0001    1
 #define L0002    2
 #define L0003    3
 
 #define _i8(i)    (i)&0xff
 #define _i16(i)   _i8(i),_i8((i)>>8)
 #define _i32(i)   _i16(i),_i16((i)>>16)
 #define _op(i)    _i8(i)
 
 #define Lod_RI(r,i)      _op(0x01),_i8(r),_i32(i),
 #define Lbl_T(t)         _op(0x02),_i32(t),
 #define Add_RR(r,s)      _op(0x03),_i8(r),_i8(s),
 #define Add_RI(r,i)      _op(0x04),_i8(r),_i32(i),
 #define Jle_RIT(r,i,t)   _op(0x05),_i8(r),_i32(i),_i32(t),
 #define Jlt_RIT(r,i,t)   _op(0x06),_i8(r),_i32(i),_i32(t),
 #define Dbg_Ret_R(r)     _op(0x10),_i8(r),
 #define Dbg_Ret_I(i)     _op(0x11),_i32(i),
 #define Dbg_Putc_R(r)    _op(0x12),_i8(r),
 #define Dbg_Putc_I(i)    _op(0x13),_i32(i),
 #define Dbg_PutHex_R(r)  _op(0x14),_i8(r),
 #define Dbg_PutHex_I(i)  _op(0x15),_i32(i),
 #define Dbg_PutDec_R(r)  _op(0x16),_i8(r),
 #define Dbg_PutDec_I(i)  _op(0x17),_i32(i),



** (3) 実行結果

 >p0004a p0004a0.txt
 01 00 20 00 00 00 02 00 00 00 00 12 00 04 00 01 00 00 00 06 00 7f 00 00 00 00 00 00 00 13 0a 00 00 00 11 00 00 00 00

-こんな感じでちゃんと動いています。
-ここでは printf していますが、これをバイナリファイルとして出力するのはもちろん簡単です。
--printfする代わりに配列に入れていって、最後にファイルに出力すればいいだけです。
-設定ファイルを変えれば、仕様を試行錯誤することも簡単です。




** (99) 更新履歴
-2026.02.15(日) 初版

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS