【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

ACKメモ

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は各種アーキテクチャをサポートするため、中間コードからネイティブコードに変換して、リンク後にネイティブフォーマットに変換します。

リンクまでは8086で行って、最後の変換をPDP-11(UNIX V7)形式で行うことで、V7のa.out形式の8086バイナリを生成するようなことが可能です。

プログラミングモデル

簡単なプログラムが-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命令)が変化しています。