8086版V6のa.outはマジックナンバーで識別することにしました。PDP-11のマジックナンバーはブランチ命令に由来します。
0407(0x107) | br 020(0x10) | .textと.dataは同じセグメントで連続 |
0410(0x108) | br 022(0x12) | .textと.dataは別セグメントに分離 |
0411(0x109) | br 024(0x14) | .textと.dataは別メモリ空間に分離 |
8086で相当する命令をマジックナンバーとしました。
0xeb 0x0e | jmp short 0x10 |
0xeb 0x10 | jmp short 0x12 |
0xeb 0x12 | jmp short 0x14 |
ちなみにV7/x86は32bit化されているため、V7(V6と同じ)のヘッダの各項目を単純に32bit化したフォーマットで、マジックナンバーはPDP-11と同じです。
cv
ACKではUNIX V7(PDP-11)がサポートされています。具体的にはリンク後にcvコマンドによりバイナリフォーマットを変換します。cvコマンドに手を入れて、上で決めたマジックナンバーを出力するように改造しました。
使用例
ACKで8086版V6のバイナリを出力して、改造したツールで処理してみます。
write.s
mov ax, #1 int 7 .data1 4 .data2 hello, 6 mov ax, #0 int 7 .data1 1 .sect .data hello: .ascii "hello\n"
$ m2cc -c write.s $ m2ld write.o -o write.ack $ 8086v6-cv write.ack write $ v6nm write 000000t 000020d 000020d 000026b 000020d hello $ v6strip write $ file write write: DOS executable (COM) $ od -tx1z -Ax write 000000 eb 0e 10 00 06 00 00 00 00 00 00 00 00 00 01 00 >................< 000010 b8 01 00 cd 07 04 10 00 06 00 b8 00 00 cd 07 01 >................< 000020 68 65 6c 6c 6f 0a >hello.< 000026 $ 7run write hello $ 7run -d write 0000: b80100 mov ax, 0001 0003: cd07 int 7 0005: 04 ; sys write 0006: 1000 ; arg 0008: 0600 ; arg 000a: b80000 mov ax, 0000 000d: cd07 int 7 000f: 01 ; sys exit
※ v6nmで表示されている名前のないシンボルは、セクションの始まりを示しているようです。
libc
現時点ではアセンブラしか使えません。C言語を使うにはlibcを整備する必要があります。V6付属のコンパイラを移植する予定のため、ACKの整備はそれほど重視していません。ですがコンパイラの移植に失敗した時の担保として、ある程度はACKも整備しておきたいと思います。
※ V7/x86は32bitのためACKやlibcを流用できません。
libcはアセンブラで書かれています。手動で変換するとアセンブラを変えた時に文法の対応が必要となり二度手間です。アセンブリを変換するトランスレータを作って、出力文法を切り替えられるようにすることが望ましいです。
そのためV6移植ハッカソンではトランスレータから着手する計画です。