ソフトな忘却力(50) FreeDOS、wlink、wdis、HDDイメージマウント

Joseph Halfmoon

前回はOpenWatcomの「ビジュアルなデバッガ」wdが使えるのに悦に入りました。しかし元をたどればNASMアセンブラだけではDOSのEXE実行形式を生成できないのでリンカをゲットするためのOpenWatcomです。今回はwlinkを使ってみます。ついでにDOSのHDDイメージのマウントとファイルアクセスもね。

※「 ソフトな忘却力」投稿順 Index はこちら

※実機動作確認には以下を使用しております。

    •  Raspberry Pi 4 model B、Cortex-A72コア(ARMv8-A)
    •  Raspberry Pi OS (64bit) bullseye
    •  QEMU 5.2.0
    •  FreeDOS 1.3
DOS上で走る16bit EXE形式のアセンブル

第47回にてFreeDOS上にインストールのNASMは、16ビットから64ビットまでx86のほぼ全てをアセンブルできる強力なアセンブラです。しかしパッケージにはリンカが不在。アセンブラ単体で作成可能な、DOSのオブジェクト形式の中でもっとも簡単な .COM 形式のオブジェクトを作ってお茶を濁しました。.COMはセグメントなし、64Kオフセットだけのバイナリオブジェクトね。

第48回にてOpenWatcom C/C++ コンパイラをインストール。これによりCのソースをコンパイルできるようになっただけでなく開発に必要な各種ツール一式をGetしました。

第49回では、コンパイラパッケージ付属の「ビジュアルな」デバッガなど使い、OpenWatcomサイコーなどと呟いてます。。。

今回はようやく第47回の問題に立ち戻り、x86の16ビット・セグメンテーションを使用した「昔懐かしい」EXEファイルをアセンブル、リンクしてみたいと思います。アセンブルしてみる例題ソースは以下の「EXE版吉例Hello world.」です。

segment code

..start:
        mov     ax, data
        mov     ds, ax
        mov     ax, stack
        mov     ss, ax
        mov     sp, stacktop
        mov     dx, hello
        mov     ah, 9
        int     0x21
        mov     ax, 0x4c00
        int     0x21

segment data
hello:  db      'Hello world.', 13, 10, '$'

segment stack   class=STACK
        resb    1024
stacktop:

上記は、微妙にインテルASM86のソースとも、マイクロソフトMASMのソースとも異なるNASM形式です。でもx86に慣れたお兄様お姉さま方には何の障害もないでしょう。ホントか?

さてNASMによるアセンブルは以下で行えます。

> nasm -f obj testexe.asm

第47回との違いが、フォーマット指定を -f obj としていることです。これにより、testexe.obj なるオブジェクトファイルが生成されます。MS-DOS伝統のオブジェクト形式のハズ。

wlinkでリンク

OpenWatcom付属のリンカ wlink は各種環境向けのオブジェクトをリンクできる強力なリンカです。ただし、コマンドラインは、ちょいクセ強です(個人の感想です。)上記のオブジェクトからEXEファイルを得るためのコマンドラインが以下に。

> wlink name test.exe format dos file testexe.obj
    • name text.exe という部分でEXEファイルの名前を指定
    • format dos という部分で、生成するファイルのフォーマットを指定。 DOSとするとDOS用のEXEが生成されます。 他にもWINDOWS, WINDOWS NT,  OS2そしてDOSイクステンダ用など切替指定が可能らしいです。
    • file testexe.obj という部分で、リンクするファイル名を指定してます。ここではファイルが1個だけですが、複数ある場合は、「,」区切りでファイルを列挙するみたい。
以下はリンクして実行したところ。

wlink_exeリンク完了、ちゃんとHello world.しておるみたい。

ディスアセンブラ wdis

行き掛けの駄賃、ということで OpenWatcom付属のディスアセンブラ wdis も動かしてみましたぞ。

> wdis testexe.obj

こんな感じ。wdis_disassembler_EXE

 

先ほどNASMでアセンブルしたオブジェクト、8086のセグメンテーションなオブジェクトになっておるようで、わしゃ嬉しいよ。

FreeDOSのディスクイメージへのアクセス

まず FreeDOS を(QEMU上で)実行している最中であれば、忘れずに

shutdown (エイリアスだけれども)

を実行しておきます。これにより、FreeDOSのディスクイメージファイルはクローズされます。クローズせずにアクセスするときっと酷いことになるのでしょう。やってないけど。

さてFreeDOSをシャットダウンして Linuxのプロンプト(QEMUをLinuxから起動していたので)にもどったら、FreeDOSのディスクイメージファイルをマウントしてFreeDOSのファイルシステムにLinuxからアクセスが可能です。

こんな感じ。mountFreeDosEC

上記では、先ほど作成したサンプルプログラムのファイルをLinux側にコピーしています。

マウントの方法は以下のWikiページで語られてます。

https://en.wikibooks.org/wiki/QEMU/FreeDOS

ちょっとMS-DOSのHDDイメージのマウントは「普通のマウント」よりクセ強なのでメモっておきます。

sudo mount -t msdos -o loop,offset=32256 freedos300.img /mnt/freedos

まず、-t で設定するファイルシステムのタイプは msdos です。ここは「あたり前」か。その後 -o でオプションをつけてます。

loop、Linuxのファイルシステム上のファイルをデバイスファイルを経由してループバック接続するためのオプションのようです。本来mountは「デバイス」をマウントするものだけれども、ここではファイル上に書き込んだハードディスクイメージなので必須だと思います。なおデバイス名を指定していないので、テキトーなお名前で「よきに計らって」くれているみたい。

offset=32256、この部分はMS-DOSのFAT16のマジックナンバーなんだと思います。セクタ512バイトで63セクタ分のオフセットのところにファイルシステムアクセスのキモがおかれておるみたいです。ファイルシステム素人老人は調べる気力もなく。Wikiに書かれていた数字を鵜呑みにしてアクセスするのみ。

freedos300.imgは、FreeDOSのディスクイメージを格納してあるファイル名です。

/mnt/freedosは、事前に mkdir して作ってある マウントポイントです。

これによりFreeDOSのファイルシステムが/mnt/freedos配下でLinuxから操作できます。

終了したら忘れずに

sudo umount /mnt/freedos

大分QEMU上のFreeDOSの操作に慣れた気がする。そんな錯覚がするだけなのよ。

ソフトな忘却力(49) FreeDOS、Open Watcomの深みにハマる へ戻る

ソフトな忘却力(51) FreeDOS、人生いろいろ、アセンブラもいろいろ へ進む