せっかくだから俺はこの OS を作るぜ

https://book.mynavi.jp/ec/products/detail/id=22078

を読み始めた。

Windows 11 環境でうまくできるかなーと不安だったけど、Hyper-V で意外と普通に起動はできた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616231/61511797-b030-efcb-6f45-64bd642a3bfe.png)

## やったこと

### helloos.img ファイルの作成

vscode の Hex Editor (`ms-vscode.hexeditor`) で既存のファイル サイズを超える書き込みを行う方法がわからなかった。

なので、とりあえずフロッピー サイズの空ファイルを用意してそれを編集、という謎の方法をとった。

```powershell
fsutil.exe file createnew helloos.img 1474560
```

で、お手本をみながらぽちぽち入力した (本当にした)、、、のだが、作成したファイルとお手本を比較するやり方がわからなかった。そんなわけで結局は Stirling を使った。

- あたたかみのある手書きバイナリ

どっちが自分で作ったやつか、この画像だとわかんないけど。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616231/eff7d695-27a1-b747-2d30-65f924f0f768.png)
> 違いはありません。

### 拡張子を vfd に変更

Hyper-V で適当に仮想マシンを作成して、作ったファイルから起動を試みた。

ところが、仮想フロッピーは `.vfd` 形式で用意する必要があったみたい、、、？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616231/548aeddc-fe8f-37bc-b277-077d18566f06.png)

めんどくせー、、、と思いきや、拡張子を img -> vfd に変更するだけで普通に認識してくれた。img は嫌か？

そんな感じでまだ 1 日目。

## NASM あれこれ

難しかったのでメモ。

アセンブラは何がいいのかわからなかったのだけど、ググったら出てきた NASM というのを使ってみることにした。

https://www.nasm.us/

同じところでハマった同志が複数観測されたが、`helloos.nas` をそのままアセンブルしようとするとエラーとなった。
(やんごとなき事情により拡張子は `.nasm` としている (`.nas` だとシンタックス ハイライトが効かなかった、、))

```powershell
> nasm .\helloos.nasm
.\helloos.nasm:43: error: attempt to reserve non-constant quantity of BSS space
```

結論としては以下で動くのだけど、理屈はわかったようなわからないような。。。

```diff
-		RESB	0x1fe-$
+		RESB	0x1fe-($-$$)
```

NASM では `$` で現在行の始点 (?) のアドレス、`$$` で現在のセクションの始点のアドレスを参照できるらしいのだけど、`$` 単体では `non-constant` と言われちゃっており、絶対的なアドレスがわかんないんですけど、、、的な意味なんだろうか？
で、現在のセクションの開始位置を差し引いた差分だったら `non-constant` ではない、、、ということ？
でもセクションなんてなんも意識してなかったんだけどなぁ。。。

上記の修正を加えてアセンブルすると以下の警告が出たので、`.text` セクションと解釈されているのかしらん？

```powershell
> nasm .\helloos.nasm
.\helloos.nasm:24: warning: uninitialized space declared in .text section: zeroing [-w+zeroing]
.\helloos.nasm:41: warning: uninitialized space declared in .text section: zeroing [-w+zeroing]
.\helloos.nasm:48: warning: uninitialized space declared in .text section: zeroing [-w+zeroing]
.\helloos.nasm:50: warning: uninitialized space declared in .text section: zeroing [-w+zeroing]
```

`.bss` は関係なかったの？ `.data` は？ていうか `.text` でいいの？？

わからない :rolling_eyes: 。

:::note info
NASM の critical expression について
:::

調べたのでメモ。

https://www.nasm.us/xdoc/2.16.01/html/nasmdoc3.html#section-3.8

> ### 3.8 Critical Expressions

> Although NASM has an optional multi-pass optimizer, there are some expressions which must be resolvable on the first pass. These are called Critical Expressions.
> 
> The first pass is used to determine the size of all the assembled code and data, so that the second pass, when generating all the code, knows all the symbol addresses the code refers to. So one thing NASM can't handle is code whose size depends on the value of a symbol declared after the code in question. For example,
> 
> ```nasm
>         times (label-$) db 0 
> label:  db      'Where am I?'
> ```
> 
> The argument to TIMES in this case could equally legally evaluate to anything at all; NASM will reject this example because it cannot tell the size of the TIMES line when it first sees it. It will just as firmly reject the slightly paradoxical code
> 
> ```nasm
>         times (label-$+1) db 0 
> label:  db      'NOW where am I?'
> ```
> 
> in which any value for the TIMES argument is by definition wrong!
> 
> NASM rejects these examples by means of a concept called a critical expression, which is defined to be an expression whose value is required to be computable in the first pass, and which must therefore depend only on symbols defined before it. The argument to the TIMES prefix is a critical expression.



ここで、first pass で具体的な値を求められるようになってないといけない式を Critical Expressions と呼ぶらしい。
TIMES の引数や RESB のオペランドは Critical Expressions なんだってさ。

https://www.nasm.us/xdoc/2.16.01/html/nasmdoc3.html#section-3.2.2

> ### 3.2.2 RESB and Friends: Declaring Uninitialized Data
> 
>  The operand to a RESB–type pseudo-instruction would be a critical expression (see section 3.8)

`-Ov` オプションで実行されたパスの数を出力してみたら、`1+2+2` って出てた。

```powershell
> nasm -Ov .\helloos.nasm
.\helloos.nasm:24: warning: uninitialized space declared in .text section: zeroing [-w+zeroing]
.\helloos.nasm:41: warning: uninitialized space declared in .text section: zeroing [-w+zeroing]
.\helloos.nasm:48: warning: uninitialized space declared in .text section: zeroing [-w+zeroing]
.\helloos.nasm:50: warning: uninitialized space declared in .text section: zeroing [-w+zeroing]
.\helloos.nasm: info: assembly required 1+2+2 passes
```

https://nasm.us/xdoc/2.14.01rc5/html/nasmdoc2.html#section-2.1.23

> ### 2.1.23 The -O Option: Specifying Multipass Optimization
> 
> - -Ov: At the end of assembly, print the number of passes actually executed.