30日でできる!OS自作入門3日目

何をやるか

  • ブートセクターにフロッピーをロードするIPLを作成する。
  • アセンブラ言語だけではなくC言語でプログラムを書くための準備をする。

新しく出たアセンブラ言語の命令など

  • JC キャリーフラグが1なら指定先にジャンプする。キャリーフラグは読み込みエラーが起こったときに1が出力される。
  • JNC キャリーフラグが0なら指定先にジャンプする。つまり読み込みエラーがなければ指定先にジャンプするということである。
  • JBE CMP命令で比較して値が小さいかもしくは等しければジャンプする。
  • EQU 命令じゃないだけどC言語の#defineみたいなもの。CYLS EQU 10はCYLSは10ですよという意味である。

フロッピーディスクについて

  • フロッピーは0~79の円形のシリンダーで構成されている。シリンダーはヘッダーを切り替えることによって表と裏の読みこみできる
  • シリンダーは1~18のセクター(512KB)で構成されている。シリンダーとセクターは0-indexで統一しない理由はなんでなのか少し気になるな。
  • シリンダーの読み込み方が一つのシリンダーの表と裏を読んだら、次のシリンダーを読むようになっている。

プログラムを読んで

  • MOV [678] 123みたいなメモリーに値を代入する命令はないが、恐らくretryの処理のところのINT 0x13命令で読み込んだ値がメモリーに格納されている。メモリーに読み込んだ値を格納する番地(バッファアドレス)の指定方法はESレジスタやBXレジスタに値を導入することによって計算される。
  • 多分、INT命令の所でmov [ES:BX] 読み込んだ値 が命令されているのだろう。 ES:BXはES×16+BXで計算され、ESやBXはそれぞれ16ビットのため最大表現でできる数は0xffffであるため、ES:BXで最大表現できる数は1,113,095バイト(1MB)である。
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へ

C言語導入

C言語のプログラムでHLT命令を扱えるようにするために以下のことをする。(かなりはしょっている気がするが。。。)

  • アセンブラのプログラムで32ビットの機械語を扱うモードを設定し、HLTを扱う関数をGLOBALで定義する。そしてオブジェクトファイルに変換する
  • C言語のプログラムは、アセンブラ言語で定義したHLTを扱う関数を用いる。そしてオブジェクトファイルに変換する。
  • 最後に生成された二つのオブジェクトファイルをくっつける。

感想

C言語を導入するための、アセンブラの方での設定や変換についてはあまり理解できていないと思う。
書くのが億劫で3日目をまとめるのに少し時間がかかった。プログラムを読んだり実行するだけしかしていないので、せめてまとめることは続けたい。4日目からはC言語を扱うということなので少し楽しみだ。