「30日でできる！OS自作入門」一日目(helloos0〜helloos2)をUbuntu18.04/NASMで作る

#はじめに
こちらの本 
[30日でできる! OS自作入門](https://www.amazon.co.jp/30%E6%97%A5%E3%81%A7%E3%81%A7%E3%81%8D%E3%82%8B-OS%E8%87%AA%E4%BD%9C%E5%85%A5%E9%96%80-%E5%B7%9D%E5%90%88-%E7%A7%80%E5%AE%9F/dp/4839919844/)
を最初はそのままWindows上で進めていましたが、naskのような著者の独自ツールが使われており情報が少ないのと、普段Ubuntuを使っているのでその上で実行できるといいなと思ったので、
できるだけLinuxで標準的なツールを使って進めていきます。
これも既にやっている方がたくさんいますが、何番煎じでも気にせずやってきます。

#環境
```bash
$ uname -a
Linux furble 5.3.0-42-generic #34~18.04.1-Ubuntu SMP Fri Feb 28 13:42:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
$ nasm -v
NASM version 2.13.02
$ qemu-system-i386 --version
QEMU emulator version 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.23)
Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers
```
#必要なツールのインストール
##QEMU
```bash
$ sudo apt install qemu-kvm qemu 
```
qemu-kvmは別にいらなかったかもしれない。

##NASM
```bash
$ sudo apt install nasm
```
#helloos0をQEMU上で実行
```bash
$ qemu-system-i386 helloos.img
WARNING: Image format was not specified for 'helloos.img' and probing guessed raw.
         Automatically detecting the format is dangerous for raw images, write operations on block 0 will be restricted.
         Specify the 'raw' format explicitly to remove the restrictions.
```
でウィンドウが出現し、「hello, world」と表示されたので、うまくいったようです。
このままでも問題無いですが、警告が気になるので、

```bash
$ qemu-system-i386 -drive file=helloos.img,format=raw,if=floppy
```
とすることで消すことができました。以降はこちらを使っていきます。

#helloos1を実行
```bash
$ nasm helloos.nas -o helloos.img
helloos.nas:9: warning: uninitialized space declared in .text section: zeroing
helloos.nas:17: warning: uninitialized space declared in .text section: zeroing
helloos.nas:20: warning: uninitialized space declared in .text section: zeroing
helloos.nas:22: warning: uninitialized space declared in .text section: zeroing
$ qemu-system-i386 -drive file=helloos.img,format=raw,if=flopp
```
nasmが警告を出していますが、問題なく実行できました。
調べると、RESB命令で警告が出ており、代わりにTIMES命令を使うことで消せます。

helloos.nas(nask用)をhelloos.asm(nasm用)に書き換えます。

```diff
$ diff -u projects/01_day/helloos1/helloos.nas tolset/helloos1/helloos.asm
--- projects/01_day/helloos1/helloos.nas	2020-03-25 17:15:30.927931338 +0900
+++ tolset/helloos1/helloos.asm	2020-03-28 12:33:54.545613281 +0900
@@ -6,7 +6,7 @@
 	DB	0xff, 0xff, 0xff, 0x48, 0x45, 0x4c, 0x4c, 0x4f
 	DB	0x2d, 0x4f, 0x53, 0x20, 0x20, 0x20, 0x46, 0x41
 	DB	0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x00, 0x00
-	RESB	16
+	TIMES	16 DB 0x00
 	DB	0xb8, 0x00, 0x00, 0x8e, 0xd0, 0xbc, 0x00, 0x7c
 	DB	0x8e, 0xd8, 0x8e, 0xc0, 0xbe, 0x74, 0x7c, 0x8a
 	DB	0x04, 0x83, 0xc6, 0x01, 0x3c, 0x00, 0x74, 0x09
@@ -14,9 +14,9 @@
 	DB	0xee, 0xf4, 0xeb, 0xfd, 0x0a, 0x0a, 0x68, 0x65
 	DB	0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72
 	DB	0x6c, 0x64, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00
-	RESB	368
+	TIMES	368 DB 0x00
 	DB	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xaa
 	DB	0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
-	RESB	4600
+	TIMES	4600 DB 0x00
 	DB	0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
-	RESB	1469432
+	TIMES	1469432 DB 0x00
```
RESB xxx は TIMES xxx DB 0 と同じです。

#helloos2を実行
RESBをTIMES命令に書き換えます。

```bash
$ nasm helloos.asm -o helloos.img
helloos.asm:41: error: non-constant argument supplied to TIMES
```
TIMES   0x1fe-$ DB 0 
の行でエラーが出ています。

[nasmマニュアル(英語)](https://www.nasm.us/xdoc/2.13.01/nasmdoc.pdf) section 3.5より
>\$ evaluates to the assembly position at the beginning of the line containing the expression; so you can code an infinite loop using JMP \$. 
\$\$ evaluates to the beginning of the current section; so you can tell how far into the section you are by using (\$−\$$).

\$はその行の最初の式（この場合TIMES）のアドレス、$$は現在のセクションの最初のアドレスを表す、とあります。セクションとは後で出てくる.textや.dataなどのことです(多分)。
今回はセクション分けはされてないので、\$$はファイルの先頭アドレスを指すものと考えられます。よって、($-\$$)はセクションの先頭(今回はファイルの先頭)から($-\$$)の記述のある行の先頭までのバイト数となり、naskにおける\$と同じ意味になるということです(多分)。

```diff
$ diff -u projects/01_day/helloos2/helloos.nas tolset/helloos2/helloos.asm | nkf -Sw 
--- projects/01_day/helloos2/helloos.nas	2020-03-25 17:15:30.927931338 +0900
+++ tolset/helloos2/helloos.asm	2020-03-29 11:37:16.045372158 +0900
@@ -21,7 +21,7 @@
 		DD		0xffffffff		; たぶんボリュームシリアル番号
 		DB		"HELLO-OS   "	; ディスクの名前（11バイト）
 		DB		"FAT12   "		; フォーマットの名前（8バイト）
-		RESB	18				; とりあえず18バイトあけておく
+		TIMES	18	DB 0			; とりあえず18バイトあけておく
 
 ; プログラム本体
 
@@ -38,13 +38,13 @@
 		DB		0x0a			; 改行
 		DB		0
 
-		RESB	0x1fe-$			; 0x001feまでを0x00で埋める命令
+		TIMES	0x1fe-($-$$)	DB 0		; 0x001feまでを0x00で埋める命令
 
 		DB		0x55, 0xaa
 
 ; 以下はブートセクタ以外の部分の記述
 		DB		0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
-		RESB	4600
+		TIMES	4600 DB 0
 		DB		0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
-		RESB	1469432
+		TIMES	1469432 DB 0
```

```bash
$ nasm helloos.asm -o helloos.img -l helloos.lst
$ qemu-system-i386 -drive file=helloos.img,format=raw,if=floppy
```
これで成功です。