30日で作るosのソースコードと軽い解説~7日まで (1) Bootstrap

###5日までのまとめ
現在30日で作るosの本を読んでます。それで、今回は7日までで出来上がったソースコードを軽く説明して行きたいと思います。

正直、自分でも全部理解している自信がないので理解できる範囲で説明して行きたいと考えております。

qiitaの投稿も今回がはじめてなので、修正点やアドバイスなどありがたくお待ちしております
#####では、やっていきましょう!!!! 
###osの起動(記憶媒体からメモリにプログラムを書き込む処理)

まず、osをどのようにして、起動するかについて説明しています。
前提条件として、記憶媒体は、フロッピーディスクをこの本では扱っています。
また、アセンブラ？にはnasmと言うソフトを活用しています。

パソコンに、電源が入ってから何をするかを教える必要があります。
これを、Bootstrapといいます。
まず、はじめにパソコンに電源が入るとcpuはBIOS ROMのプログラムにアクセスします。そして、現在使用されているマザーボードにどのような周辺機器が接続されているか確認します。

BIOSのプログラムが最後行う処理は、現在ユーザが起動に使おうとしたディスクのはじめの512バイト(MBR領域とも言います)を読み込みます。
以下のプログラムはそのmbrで読み込まれるソースコードになっています。

```boot.nas
CYLS	EQU		10				; どこまで読み込むか

		ORG		0x7c00			; このプログラムがどこに読み込まれるのか

entry:
		MOV		AX,0			; レジスタ初期化
		MOV		SS,AX
		MOV		SP,0x7c00
		MOV		DS,AX

; ディスクを読む

		MOV		AX,0x0820
		MOV		ES,AX
		MOV		CH,0			; シリンダ0
		MOV		DH,0			; ヘッド0
		MOV		CL,2			; セクタ2
readloop:
		MOV		SI,0			; 失敗回数を数えるレジスタ
retry:
		MOV		AH,0x02			; AH=0x02 : ディスク読み込み
		MOV		AL,1			; 1セクタ
		MOV		BX,0
		MOV		DL,0x00			; Aドライブ
		INT		0x13			; ディスクBIOS呼び出し
		JNC		next			; エラーがおきなければnextへ
		ADD		SI,1			; SIに1を足す
		CMP		SI,5			; SIと5を比較
		JAE		error			; SI >= 5 だったらerrorへ
		MOV		AH,0x00
		MOV		DL,0x00			; Aドライブ
		INT		0x13			; ドライブのリセット
		JMP		retry
next:
		MOV		AX,ES			; アドレスを0x200進める
		ADD		AX,0x0020
		MOV		ES,AX			; ADD ES,0x020 という命令がないのでこうしている
		ADD		CL,1			; CLに1を足す
		CMP		CL,18			; CLと18を比較
		JBE		readloop		; CL <= 18 だったらreadloopへ
		MOV		CL,1
		ADD		DH,1
		CMP		DH,2
		JB		readloop		; DH < 2 だったらreadloopへ
		MOV		DH,0
		ADD		CH,1
		CMP		CH,CYLS
		JB		readloop		; CH < CYLS だったらreadloopへ

; 読み終わったのでharibote.sysを実行だ！

		MOV		[0x0ff0],CH		; IPLがどこまで読んだのかをメモ
		JMP		0xc200

error:
		MOV		SI,msg
putloop:
		MOV		AL,[SI]
		ADD		SI,1			; SIに1を足す
		CMP		AL,0
		JE		fin
		MOV		AH,0x0e			; 一文字表示ファンクション
		MOV		BX,15			; カラーコード
		INT		0x10			; ビデオBIOS呼び出し
		JMP		putloop
fin:
		HLT						; 何かあるまでCPUを停止させる
		JMP		fin				; 無限ループ
msg:
		DB		0x0a, 0x0a		; 改行を2つ
		DB		"load error"
		DB		0x0a			; 改行
		DB		0

		RESB	0x7dfe-$		; 0x7dfeまでを0x00で埋める命令

		DB		0x55, 0xaa
```
アセンブラ言語に慣れていない僕は軽く、吐き気がありますが笑
がんばって説明していきます。
ちなみに、なんですがこの本ではアセンブラ言語は大文字で書かれていましたが小文字でもいいそうです。

```			
		ORG		0x7c00			
entry:
		MOV		AX,0			
		MOV		SS,AX
		MOV		SP,0x7c00
		MOV		DS,AX
```
はじめに、この部分なんですが
ORG     0x7c00
でこのプログラムはメモリ上の0x7c00番地からスタートするという意味があります。
なぜ、もっとはじめのほうの番地を使うことができないかといいます。これより前の番地ではすでにbiosが占領しているため私たちが使うことができないため0x7c00番地からはじまっています。
また、レジスタに変な値が入力されているといけないので初期化を行っています。

```step2		
tuzuki:
		MOV		AX,0x0820
		MOV		ES,AX
		MOV		CH,0			; シリンダ0
		MOV		DH,0			; ヘッド0
		MOV		CL,2			; セクタ2
readloop:
		MOV		SI,0			; 失敗回数を数えるレジスタ
retry:
		MOV		AH,0x02			; AH=0x02 : ディスク読み込み
		MOV		AL,1			; 1セクタ
		MOV		BX,0
		MOV		DL,0x00			; Aドライブ
		INT		0x13			; ディスクBIOS呼び出し
		JNC		next			; エラーがおきなければnextへ
		ADD		SI,1			; SIに1を足す
		CMP		SI,5			; SIと5を比較
		JAE		error			; SI >= 5 だったらerrorへ
		MOV		AH,0x00
		MOV		DL,0x00			; Aドライブ
		INT		0x13			; ドライブのリセット
		JMP		retry
```
はじめに、esレジスタに番地を入力しているのは、そこに今度プログラムを書き込みますよーという意味です。ですので、今からフロッピーディスクからデータを読み込んでメモリに記述するのですが、そのメモリの始まりの番地を記述しています。
ここでは、フロッピーディスクから次のプログラムをよみこんでいます。
プロッピーディスクからメモリにプログラムを読み込むには、割り込みを使ってフロッピーディスクからプログラムを読み込む必要があります。
inc 13h

と記述することでcpu割り込みを行いフロッピディスクを読み込むのですが。
そのほかにも、フロッピーディスクのどこから読み込みのか？どれだけ読み込むのかをデータとして送らなければいけないのですがそのときにレジスタを使って情報を受け渡しています。
具体には、
alが何セクタ読み込むか
chは何番目のシリンダか
clは何番目のセクタから読み込むか
dhはheadの何番目か
dlはdriveの何番目か
そして、これらの情報をレジスタに渡したあとに、
int  0x13
と割り込みをかけてフロッピーディスクに情報を読み込みにいく。
また、以下ではフロッピーディスクにデータを読みこんでできなかった場合同じことを繰り返すプログラムが実装されています。

```step4
readloop:
		MOV		SI,0			; 失敗回数を数えるレジスタ
retry:
		MOV		AH,0x02			; AH=0x02 : ディスク読み込み
		MOV		AL,1			; 1セクタ
		MOV		BX,0
		MOV		DL,0x00			; Aドライブ
		INT		0x13			; ディスクBIOS呼び出し
		JNC		next			; エラーがおきなければnextへ
		ADD		SI,1			; SIに1を足す
		CMP		SI,5			; SIと5を比較
		JAE		error			; SI >= 5 だったらerrorへ
		MOV		AH,0x00
		MOV		DL,0x00			; Aドライブ
		INT		0x13			; ドライブのリセット
		JMP		retry
next:
		MOV		AX,ES			; アドレスを0x200進める
		ADD		AX,0x0020
		MOV		ES,AX			; ADD ES,0x020 という命令がないのでこうしている
		ADD		CL,1			; CLに1を足す
		CMP		CL,18			; CLと18を比較
		JBE		readloop		; CL <= 18 だったらreadloopへ
		MOV		CL,1
		ADD		DH,1
		CMP		DH,2
		JB		readloop		; DH < 2 だったらreadloopへ
		MOV		DH,0
		ADD		CH,1
		CMP		CH,CYLS
		JB		readloop		; CH < CYLS だったらreadloopへ

; 読み終わったのでharibote.sysを実行だ！

		MOV		[0x0ff0],CH		; IPLがどこまで読んだのかをメモ
		JMP		0xc200

error:
		MOV		SI,msg
putloop:
		MOV		AL,[SI]
		ADD		SI,1			; SIに1を足す
		CMP		AL,0
		JE		fin
		MOV		AH,0x0e			; 一文字表示ファンクション
		MOV		BX,15			; カラーコード
		INT		0x10			; ビデオBIOS呼び出し
		JMP		putloop
fin:
		HLT						; 何かあるまでCPUを停止させる
		JMP		fin				; 無限ループ
msg:
		DB		0x0a, 0x0a		; 改行を2つ
		DB		"load error"
		DB		0x0a			; 改行
		DB		0

		RESB	0x7dfe-$		; 0x7dfeまでを0x00で埋める命令

		DB		0x55, 0xaa
```
そして、最後に

MOV		[0x0ff0],CH	
JMP		0xc200
0xc200にとびます。
これは、いろいろとコンパイルを行った結果
メイン処理の部分がそのアドレスの場所になったからそこにとんだと書いてありました。
詳しいことが、ちょっとわからなかったです。
まあ、今日はこの辺で。