- 作者: 川合秀実
- 出版社/メーカー: 毎日コミュニケーションズ
- 発売日: 2006/03/01
- メディア: 単行本
- 購入: 36人 クリック: 735回
- この商品を含むブログ (299件) を見る
今回の内容
一日目に引き続き、アセンブラで書かれた「Hello World」とだけ表示されるOSのソースコードを読む回。
CPUのレジスタ(記憶するところ)とメモリーの概念が登場し、アセンブラのコードを通じてどのように画面に文字を出力したのかが書かれていた。
変数の代入、メモリの番地指定、条件分岐、goto命令などプログラミングを知っていると理解しやすい雰囲気。
コードの解説・理解
; プログラム本体 entry: MOV AX,0 ; レジスタ初期化 MOV SS,AX MOV SP,0x7c00 MOV DS,AX MOV ES,AX 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 "hello, world" DB 0x0a ; 改行 DB 0 RESB 0x7dfe-$ ; 0x7dfeまでを0x00で埋める命令 DB 0x55, 0xaa
コードはentry/putloop/fin/msgの4種類の要素から成り立っている。
- entryは初期変数の定義
- putloopはmsgでメモリに書き込まれた内容を1文字づつ出力
- finはCPUの停止
- msgは表示する文字情報をメモリに書き込む処理
ブートセクタ
OSイメージはブートセクタと呼ばれる領域が存在する。0x7c00から始まる512バイトのこの領域にOSイメージを作成することでBIOSはOSが存在することが確認でき起動ができる。(より正確には1日目に書かれていたが最後のバイト文字を見ているらしい)
Makefile
すげえ便利。
疑問点
1 00000000 ; hello-os 2 00000000 ; TAB=4 3 00000000 4 ORG 0x7c00 ; このプログラムがどこに読み込まれるのか 5 00007C00 6 00007C00 ; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述 7 00007C00 8 00007C00 EB 4E JMP entry 9 00007C02 90 DB 0x90 10 00007C03 48 45 4C 4C 4F 49 50 4C DB "HELLOIPL" ; ブートセクタの名前を自由に書いてよい(8バイト) 11 00007C0B 0200 DW 512 ; 1セクタの大きさ(512にしなければいけない) 12 00007C0D 01 DB 1 ; クラスタの大きさ(1セクタにしなければいけない) 13 00007C0E 0001 DW 1 ; FATがどこから始まるか(普通は1セクタ目からにする) 14 00007C10 02 DB 2 ; FATの個数(2にしなければいけない) 15 00007C11 00E0 DW 224 ; ルートディレクトリ領域の大きさ(普通は224エントリにする) 16 00007C13 0B40 DW 2880 ; このドライブの大きさ(2880セクタにしなければいけない) 17 00007C15 F0 DB 0xf0 ; メディアのタイプ(0xf0にしなければいけない) 18 00007C16 0009 DW 9 ; FAT領域の長さ(9セクタにしなければいけない) 19 00007C18 0012 DW 18 ; 1トラックにいくつのセクタがあるか(18にしなければいけない) 20 00007C1A 0002 DW 2 ; ヘッドの数(2にしなければいけない) 21 00007C1C 00000000 DD 0 ; パーティションを使ってないのでここは必ず0 22 00007C20 00000B40 DD 2880 ; このドライブ大きさをもう一度書く 23 00007C24 00 00 29 DB 0,0,0x29 ; よくわからないけどこの値にしておくといいらしい 24 00007C27 FFFFFFFF DD 0xffffffff ; たぶんボリュームシリアル番号 25 00007C2B 48 45 4C 4C 4F 2D 4F 53 20 20 DB "HELLO-OS " ; ディスクの名前(11バイト) 00007C35 20 26 00007C36 46 41 54 31 32 20 20 20 DB "FAT12 " ; フォーマットの名前(8バイト) 27 00007C3E 00 00 00 00 00 00 00 00 00 00 RESB 18 ; とりあえず18バイトあけておく 00007C48 00 00 00 00 00 00 00 00 28 00007C50 29 00007C50 ; プログラム本体 30 00007C50 31 00007C50 entry: 32 00007C50 B8 0000 MOV AX,0 ; レジスタ初期化 33 00007C53 8E D0 MOV SS,AX 34 00007C55 BC 7C00 MOV SP,0x7c00 35 00007C58 8E D8 MOV DS,AX 36 00007C5A 8E C0 MOV ES,AX 37 00007C5C 38 00007C5C BE 7C74 MOV SI,msg 39 00007C5F putloop: 40 00007C5F 8A 04 MOV AL,[SI] 41 00007C61 83 C6 01 ADD SI,1 ; SIに1を足す 42 00007C64 3C 00 CMP AL,0 43 00007C66 74 09 JE fin 44 00007C68 B4 0E MOV AH,0x0e ; 一文字表示ファンクション 45 00007C6A BB 000F MOV BX,15 ; カラーコード 46 00007C6D CD 10 INT 0x10 ; ビデオBIOS呼び出し 47 00007C6F EB EE JMP putloop 48 00007C71 fin: 49 00007C71 F4 HLT ; 何かあるまでCPUを停止させる 50 00007C72 EB FD JMP fin ; 無限ループ 51 00007C74 52 00007C74 msg: 53 00007C74 0A 0A DB 0x0a, 0x0a ; 改行を2つ 54 00007C76 68 65 6C 6C 6F 2C 20 77 6F 72 DB "hello, world" 00007C80 6C 64 55 00007C82 0A DB 0x0a ; 改行 56 00007C83 00 DB 0 57 00007C84 58 00007C84 00 00 00 00 00 00 00 00 00 00 RESB 0x7dfe-$ ; 0x7dfeまでを0x00で埋める命令
わかりやすさのためにアセンブラのコードとバイナリを一覧化できるリストファイルが登場した。ここのMOV命令行が複数あるけれど、どこもバイナリコードは別々になっている。MOVを使っている列は全部同じバイナリ始まりになると思ったけどどうやらアセンブラの命令はバイナリ化されず、結果がバイナリとして示されるっぽい。ここの変換方法はどういうロジックなんだろうか?
注意点
- http://community.osdev.info/?(AT)BIOSというURLが掲載されていたが現在は存在しなかった。有志によるサイトでhttp://oswiki.osask.jp/?%28AT%29BIOSが存在したのでこちらを参照する。