ぐだぐだ低レベルプログラミング(249)x86(32bit)、MLとWinDbgを使いたい

Joseph Halfmoon

前回、ついに16ビットと32ビットの狭間にあるプロテクト・モードの「ナンヤカンヤ」をひとまず完了、32ビット世界に足を踏み入れる決断をいたしました。16ビット環境ではエミュレータ上のFreeDOSにお世話になってましたが、ここからは「ネイティブx86」環境での実習としたいと思います。さてアセンブラとデバッガはどれ?

※「ぐだぐだ低レベル プログラミング」投稿順indexはこちら

※実機動作確認には以下を使用させていただいております。

    • Windows 11 PC (i5-1235U)
    • Microsoft (R) Macro Assembler Version 14.33.31630.0
    • WinDbg 1.2511.21001.0
以前の動作確認環境と今回からの環境

使用しているパソコンそのものは同じです。Windows 11(64bit)登載機です。しかし、x64の場合x86の32ビットコードを実行するのは「素直に」できますが、昔の16ビットコードの実行はムツカシーです。ましてやプロテクト・モードの「セグメンテーション」部分に手を突っ込むのは大変。そういうことで、前回まではWindows PCの上で、以下のような屋上屋を重ねるOSテンコ盛り状態で実習を行ってました。ヘタレだな、自分。

    •  Windows 11 PC (i5-1235U)
    •  Ubuntu 24.04 LTS on WSL2
    •  QEMU 8.2.2
    •  FreeDOS 1.3
    • DOS4GW(DOSイクステンダの1種)

また開発ツールとしては以下にお世話になっております。あざーす。

    • NASM
    • OpenWatcom C
    • debugx (FreeDOSのデバッガ)

しかし、x86の32ビット世界に踏み込むならば、エミュレータ上でFreeDOSにお世話にならずとも済みます。一瞬、WSL2上のUbuntu環境で、gas / gdb 系での実習も頭をよぎりましたが、ここはネイティブなWindows直で行くことにさせていただきました。

そこで今回からは以下の環境を使わせていただくことにいたします。

    1. Microsoft Visual Studio\2022\BuildTools所蔵のツールチェーン
    2. デバッガはWinDbg、Microsoft Storeからインストールした最新版

1の環境は、大分以前にパソコンを新しくしたところでMSVCのツールチェーンをインストールしたためで2022なんであります。成り行き。この環境での32ビット用アセンブラは、

ML.EXE (Microsoft Macro Assembler) 14.33.31630.0

であります。なお、ホスト64ビット環境用の中の32ビット用アセンブラの方です。

一方、デバッガはMicrosoft Storeからインストールしました。テキトーにアップデートしてくれるんじゃないかと。なお現在のバージョンは以下です。

WinDbg 1.2511.21001.0

まずビルド環境を整える

パソコン内部に既にツールチェーンはインストールしてあったものの、64ビットホスト環境内で64ビットのVCなど扱う向けのセットアップしか見当たりませんでした。ぜんぜん使ってないからの~。今回は32ビットのオブジェクトの演習なので、32ビット用に設定せななりません。

手もとの環境では以下のパスに置かれた VsDevCmd.bat なるバッチファイルがあり、これに引数を与えることで設定可能でした。

cmd.exe /k "C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\Common7\Tools\VsDevCmd.bat" -startdir=none -arch=x86 -host_arch=x64

まあ、上記をベースにコマケーところをチョイ変すればビルド環境はOKね。昔ながらのコマンド・プロンプトからアセンブルしてリンク可能っす。こんな感じ。

ml /c /coff /Zi train000.asm
link /subsystem:windows /entry:start /debug train000.obj user32.lib kernel32.lib

実際にビルドしているところが以下に。build_run

なお、黄色枠の部分は、後でデバッガ使う際に必須のオプションです。

また、テストに使ったアセンブラソース train000.asm が以下に。

; x86(32bit) instructions exercise 000
.386
.model flat, stdcall
option casemap:none

extern ExitProcess@4  : proc
public start

.code
start:
    mov eax, 1
    mov edx, 2
    add eax, edx
    nop
    jmp start

    push 0          ; uExitCode
    call ExitProcess@4
end start

一応、Windows環境のAPIでexitするように書いてますが、上記をみればお分かりのとおり、プログラム自体は無限ループです。デバッガから走らせる前提。

WinDbg起動!

さて、MicroSoft社の強烈なデバッガ WinDbg.exeの起動画面が以下に。winDbg

さて、先ほどビルドしたプログラム train000.exe をデバッガからロードするのは「ファイル」画面より、Launch executableとな。

ここからオブジェクト・ファイルを指定できます。開いたところが以下に(ついでにアセンブラソースも見えるようにしてます。)bpStart

Windows上で「走る」プログラムであるので、なんやらいろいろなモジュールにダイナミック・リンクされとります。デフォでは初期化コードから見えてるみたい。そこでコマンドウインドウに

bp start

と、「演習部分」の先頭番地にブレークポイントを置きます。その後で g とやって走らせれば初期化コードが実行され、start番地にいたったところでブレークがかかります。こんな感じ。step1

すると、右のウインドウ内にはレジスタの値など「いつもの」デバッガ相当の表示が出てまいります。しめしめ。ここで

t

と打てば(traceだと思う、)下に見えている命令が実行されます。こんな感じ。step2

赤枠つけたところが、EAXレジスタへの即値1のロードです。

お次はどうよ。step3

ちゃんとできてるみたい。

そして32ビットのレジスタ同士の足し算。step4

できた、良かった。当たりまえか。

この環境で、次回から32ビットの命令の演習にまい進。ホントか?

ぐだぐだ低レベルプログラミング(248)x86(32bit)、GDTをメモリから覗き見 へ戻る

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です