30日でできる!OS自作入門2日目
何をやるか
一日目のアセンブラプログラムの理解の続きとmakeファイル入門。Hello worldを出力するOSプログラムを改良して何をやっているのかを理解する、アセンブラプログラムをイメージファイルに変換するバッチファイルやイメージファイルを用いてqemuでエミュレートするバッチファイルなどをまとめてMakefileに書く。
新しく出たアセンブラの命令
新しく出てきた命令などについて書く。- ORG命令 プログラムがメモリーのどこから格納されるかを設定するために使う。
- JMP命令 指定されたアドレスに飛ぶ。
- MOV命令 代入を表す。CPUの記憶装置やメモリーにアドレスや値を代入するために使う。
- INT命令 ソフトウェア命令割込み。
- CMP命令 比較を行う命令。
- JE命令 比較の結果が等しければ指定したアドレスにジャンプする。
- ラベル 変数名;と書くとラベルの宣言がかける。命令のアドレスを分かるために宣言する。
プログラムを読んで
- 最初のORG命令でPCのメモリーにプログラムを読み込ませる番地を0x7c00と書く理由は決まり事で、0x0000とかはBIOSが使うことがあるのでだめらしい。
- ディスプレイに"Hello world"を出力するために、メモリーに格納されている文字をCPUのALレジスタに一文字ずつ代入していることが、putloop:のところのMOV AL,[SI] ADD SI 1 でわかる。SIレジスタは文字列の書き込み命令が書かれているmsgの番地が代入されている。ORG命令のところでADD msg 0x7c00されてmsgのメモリーからの絶対番地は既に計算されているのかな?
- putloopのところでALレジスタに代入された文字を出力するために、MOV AH,0x0e MOV BX,15 INT 0x10とBIOSのビデオ関係の制御をしている。INT命令について後々わかればいいな。
; hello-os ; TAB=4 ORG 0x7c00 ; このプログラムがどこに読み込まれるのか ; 以下は標準的なFAT12フォーマットフロッピーディスクのための記述 JMP entry DB 0x90 ; プログラム本体 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
Makefileを書いて出力されたエラー
- ../z_tools/・・・の命令の所で先頭にタブ文字を挿入していないと"Makefile:2: *** missing separator. Stop."とエラーがでた
ipl.bin :ipl.nas Makefile ../z_tools/nask.exe ipl.nas ipl.bin ipl.lst
- cygwinを導入していると最後のMakafileのcleanが実行できなくて"process_begin: CreateProcess((null), del ipl.bin, ...) failed.make (e=2): 指定されたファイルが見つかりません。..\z_tools\make.exe: [clean] Error 2 (ignored) del ipl.lst"とエラーが出る。 faq/makeを読むと以下のように書き換えたらよいらしい。
clean : cmd.exe /C del ipl.bin cmd.exe /C del ipl.lst