8086(16bitのx86)をサポートするコンパイラとしてACKが使えるようになりました。
ACK自体の移植ではなく、MINIX用のバイナリを8086インタプリタ上で動かします。使用方法は以下を参照してください。
ACKに関するメモです。
呼び出されるコマンド
cc a.cとしたときにccから呼び出されるコマンドは以下の通りです。
/usr/lib/ncpp -D_EM_WSIZE=2 -D_EM_PSIZE=2 -D_EM_SSIZE=2 -D_EM_LSIZE=4 -D_EM_FSIZE=4 -D_EM_DSIZE=8 -D__ACK__ -D__minix -D__i86 a.c /usr/lib/irrel /tmp/cc000000.i /usr/lib/ncem -L /tmp/cc000000.i /tmp/cc000000.k /usr/lib/nopt < /tmp/cc000000.k > /tmp/cc000000.m /usr/lib/ncg /tmp/cc000000.m /tmp/cc000000.s /usr/lib/as - /tmp/cc000000.s -o a.o /usr/lib/ld -i -o /tmp/cc000000.out /usr/lib/ncrtso.o a.o /usr/lib/libd.a /usr/lib/libc.a /usr/lib/libfp.a /usr/lib/libe.a /usr/lib/end.a /usr/lib/cv /tmp/cc000000.out a.out
※一時ファイル名cc000000の数字部分はpidによって変化します。
ACKはステップごとにコマンドを呼び出している:cc→ncpp(プリプロセッサ)→irrel(未使用コードの削除)→ncem(中間コードを生成)→nopt(最適化)→ncg(中間コードからアセンブリを生成)→as→ld→cv(バイナリフォーマット変換)
バイナリフォーマット
ACKは各種アーキテクチャをサポートするため、中間コードからネイティブコードに変換して、リンク後にネイティブフォーマットに変換します。
リンクまでは8086で行って、最後の変換をPDP-11(UNIX V7)形式で行うことで、V7のa.out形式の8086バイナリを生成するようなことが可能です。
プログラミングモデル
ACKは8086のセグメントに特化した機能がないので、far/hugeポインタは使えない。ldで-iを指定すればI/D分離ができるので、TinyとSmallをサポートしていると言える。DOSやWin16の開発をするわけではないので、特に問題ない。
簡単なプログラムが-iの有無でどう変化するかを見ます。
write.s
sub sp, #20 mov ax, #1 mov bx, sp mov cx, #3 mov 2(bx), #4 mov 4(bx), #1 mov 10(bx), #hello mov 6(bx), #6 int 0x20 mov ax, #0 mov bx, sp mov cx, #3 mov 2(bx), #1 mov 4(bx), #0 int 0x20 .sect .data hello: .ascii "hello\n"
-iなし(Tiny)
$ m2cc -c write.s $ m2ld -o write.ack write.o $ m2cv write.ack write $ 7run -d write 0000: 83ec14 sub sp, 14 0003: b80100 mov ax, 0001 0006: 89e3 mov bx, sp 0008: b90300 mov cx, 0003 000b: c747020400 mov [bx+2], 0004 0010: c747040100 mov [bx+4], 0001 0015: c7470a3600 mov [bx+a], 0036 001a: c747060600 mov [bx+6], 0006 001f: cd20 int 20 0021: b80000 mov ax, 0000 0024: 89e3 mov bx, sp 0026: b90300 mov cx, 0003 0029: c747020100 mov [bx+2], 0001 002e: c747040000 mov [bx+4], 0000 0033: cd20 int 20
-iあり(Small)
$ m2cc -c write.s $ m2ld -i -o write.ack write.o $ m2cv write.ack write $ 7run -d write 0000: 83ec14 sub sp, 14 0003: b80100 mov ax, 0001 0006: 89e3 mov bx, sp 0008: b90300 mov cx, 0003 000b: c747020400 mov [bx+2], 0004 0010: c747040100 mov [bx+4], 0001 0015: c7470a0000 mov [bx+a], 0000 001a: c747060600 mov [bx+6], 0006 001f: cd20 int 20 0021: b80000 mov ax, 0000 0024: 89e3 mov bx, sp 0026: b90300 mov cx, 0003 0029: c747020100 mov [bx+2], 0001 002e: c747040000 mov [bx+4], 0000 0033: cd20 int 20
helloを参照しているアドレス(0015のmov命令)が変化しています。