『自作エミュレータで学ぶx86アーキテクチャ』をManjaro（Linux）で学ぶ

# はじめに

『自作エミュレータで学ぶx86アーキテクチャ』という書籍を購入しました．このサンプルコードのMakefileは同梱されているツールチェーン（gcc等）を参照しており，そのツールがWindows向けでした．信仰上の理由でWindows上での開発を良しとしない私は，普段使っているManjaro（Archlinux系のLinux環境です）でx86エミュレータを開発することにしました．

この記事ではManjaro向けに改変したサンプルコードの使い方と改変した箇所について説明します．

# 学習環境の準備

※以降はManjaroでエミュレータを開発することを前提に説明しますが，他のLinux Distributionでも同様に開発が出来ると思います．

## 必要なツール（gcc, nasm, objdump, qemu）のインストール

```
$ sudo pacman -S git gcc nasm binutils qemu
```

## サンプルコードのダウンロード

```
$ git clone https://github.com/Kenta11/x86-emulator-book-Manjaro
```

# サンプルコードの改変

公式に配布されているサンプルコードとの差分は以下の通りです．

- Makefileが参照するツールを，先程インストールしたものに置き換え
- "4.5 PBRを見てみよう"で使用するbootsをフルスクラッチで開発
- "4.6 実機で動かしてみよう"をQEMUで出来るようにMakefileを追加
- Windows向けのツールチェーンを削除

## Makefileが参照するツールを，先程インストールしたものに置き換え

配布されているサンプルコードでは，gcc等を同梱しそれらを参照していました．

- Before (tolset_p86/emu4.2/Makefileより)

```
TARGET = px86.exe                                                                                                                               
OBJS = main.o emulator_function.o instruction.o modrm.o io.o bios.o
Z_TOOLS = ../z_tools

CC = $(Z_TOOLS)/mingw32-gcc/bin/gcc
CFLAGS += -Wall

.PHONY: all 
all :
    make $(TARGET)

%.o : %.c Makefile
    $(CC) $(CFLAGS) -c $<

$(TARGET) : $(OBJS) Makefile
    $(CC) -o $@ $(OBJS)
```

参照しているツールを`pacman`でインストールしたものに置き換え，さらに便利そうだと思ったルールを追記しました．

- After ([chapter4/section2/Makefile](https://github.com/Kenta11/x86-emulator-book-Manjaro/blob/master/chapter4/section2/Makefile)より)

```
TARGET = px86                                                                                                                                   
PROGRAM = subroutine32.bin
OBJS = main.o emulator_function.o instruction.o modrm.o io.o bios.o

CC = gcc 
ASM = nasm
CFLAGS += -O2 -Wall -Wextra

.PHONY: all run clean
all : $(TARGET) $(PROGRAM)

run : $(TARGET) $(PROGRAM)
        ./$(TARGET) -q $(PROGRAM)

$(TARGET) : $(OBJS)
        $(CC) -o $@ $(OBJS)

%.o : %.c 
        $(CC) $(CFLAGS) -c $<

%.bin : %.asm
        $(ASM) -f bin -o $@ $<

clean :
        rm -f $(TARGET) $(PROGRAM) $(OBJS)
```

このMakefileの場合は，runとcleanを追記しました．runはエミュレータでテストプログラムを実行します．またcleanは生成物（オブジェクトファイル，エミュレータのバイナリ，テストプログラム）を削除します．

## "4.5 PBRを見てみよう"で使用するbootsをフルスクラッチで開発

bootsももれなくWindows向けのバイナリでしたので，私がオリジナルに似た処理をするプログラムを作成しました（[chapter4/section5](https://github.com/Kenta11/x86-emulator-book-Manjaro/tree/master/chapter4/section5)）．書籍ではFAT16の内容を表示していますが，私の周りにあったUSBメモリは全てFAT32でフォーマットされていました．そこでFAT32も表示できるようにしています．（オリジナルのbootsはFAT32も見られるのかな...後で確認します）

## "4.6 実機で動かしてみよう"をQEMUで出来るようにMakefileを追加

書籍ではbootsで出力したアセンブリプログラムに変更を加えて，文字列を表示するプログラムを実機で動かします．しかしながらアセンブリプログラムに間違いを残してパソコンが壊れた，なんてアクシデントがあると怖いので，QEMU（エミュレータ）で代わりにやってみました．[chapter4/section6](https://github.com/Kenta11/x86-emulator-book-Manjaro/tree/master/chapter4/section6)にアセンブリプログラムpbr.asmを置き，`make`を実行すると，QEMUがpbr.binを読んで実機と同じような結果を表示してくれます．

- [chapter4/section6/Makefile](https://github.com/Kenta11/x86-emulator-book-Manjaro/blob/master/chapter4/section6/Makefile)より

```
TARGET = pbr.bin
ASM = nasm
QEMU = qemu-system-x86_64

.PHONY: all clean
all : $(TARGET)
	$(QEMU) $<

%.bin : %.asm
	nasm $< -o $@

clean :
	rm -f $(TARGET)
```

※Manjaro以外のLinux Distributionを使っていて，QEMUのファイル名が`qemu-system-x86_64`でない場合は，Makefileの`TARGET`の部分を修正して下さい

## Windows向けのツールチェーンを削除

同梱されているgccやbootsはWindows向けであり，Manjaroには不要なので削除しました．ファイルサイズが小さくなるので嬉しいですね．

# まとめ

『自作エミュレータで学ぶx86アーキテクチャ』をManjaroで取り組んでみました．ページを読み進めるにつれて80386のエミュレータがインクリメンタルに出来上がっていく面白さは，他の書籍（特に日本語の書籍！）では味わえないと思います．x86のアーキテクチャは一見複雑そうですが，この本を読み終わった後は複雑に思えます:P もちろん歴史的な経緯からこんなことになっちゃっているのですが，読み進めていくうちにその理由も体感できました．コンピュータの仕組みに興味がある人に是非オススメしたいです．

サンプルコードのMakefileが参照するツールをManjaroのパッケージマネージャでインストール出来るものに置き換えたことで，元のサンプルコードZIPファイルよりサイズを小さくしつつ，Linux環境で再利用しやすくなりました．もしこの本の内容をLinuxで取り組みたい方がいらっしゃいましたら，是非，GitHubにアップロードしたサンプルコードもご活用下さい．

# リンク

- 自作エミュレータで学ぶx86アーキテクチャ 商品ホームページ：[https://book.mynavi.jp/ec/products/detail/id=41347](https://book.mynavi.jp/ec/products/detail/id=41347)
    - なんとこのページだとPDF版も購入できるようだ．この記事を投稿する直前まで気が付かなかった．
- Manjaro向けサンプルコード：[https://github.com/Kenta11/x86-emulator-book-Manjaro](https://github.com/Kenta11/x86-emulator-book-Manjaro)