LoginSignup
1

More than 1 year has passed since last update.

posted at

updated at

「hello, world」と表示されるだけのなんちゃってOS(ブートセクタ)を作ってみた。1/5時限目

おりょうの寺子屋、教師兼生徒を務めますわたくし、
おりょうが、本日は出張授業ですよ~ なんちゃって。

はじめに

HTC Advent Calendar 2020の7日目を担当します。
ONEJAPAN HACKATHONに参加したチームHTCのメンバー、おりょうです。

今回は私が絶賛挑戦中のOS作成の一部分を切り取ってご紹介しようかなと思います。
OSってみんな知ってるけどいざ作るとなるとなんだかハードルが高く感じますよね?
でも実際ちょっと興味ありません?
少なくともここまでの前説を読んでくれているあなたは、
少なからずOSに興味があるから見に来てくれているのでしょう。

そんなあなただけに今回は!
めちゃくちゃ簡単な「なんちゃってOS(ブートセクタ編)」をご紹介いたします。
合計3回に分けて紹介する予定です。

早速見ていきましょう!

概要

成果物:OS(フロッピーディスクで、フォーマットはFAT12)
アセンブラ:NASK
想定対象読者:OS自作をこれから始めようとしている人。

シラバス

1時限目:アセンブリ言語でソースコードを書こう①(ORG命令~entryラベルまで)
2時限目:アセンブリ言語でソースコードを書こう②(putloopラベル)
3時限目:アセンブリ言語でソースコードを書こう③(finラベル~msgラベルまで)
4時限目:出来たソースコードを機械語にアセンブルしてみよう。
5時限目:PC/ATエミュレータを使ってOSを起動させてみよう。

1時限目:アセンブリ言語でソースコードを書こう①
(ORG命令~entryラベルまで)

まずは講義3回分のソースコードの全容を見てみましょう。

        ORG     0x7c00

; 以下はFAT12フォーマットフロッピーディスクのための記述

        JMP     entry
        DB      0x90
        DB      "HELLOIPL"
        DW      512
        DB      1
        DW      1
        DB      2
        DW      224
        DW      2880
        DB      0xf0
        DW      9
        DW      18
        DW      2
        DD      0
        DD      2880
        DB      0,0,0x29
        DD      0xffffffff
        DB      "HELLO-OS   "
        DB      "FAT12   "
        RESB    18

;ここからブートセクタについて書いていくで!

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
        CMP     AL,0
        JE      fin
        MOV     AH,0x0e
        MOV     BL,13
        INT     0x10
        JMP     putloop
fin:
        HLT
        JMP     fin

msg:
        DB      0x0a, 0x0a
        DB      "hello, world"
        DB      0x0a
        DB      0

        RESB    0x7dfe-$

        DB      0x55, 0xaa

ざっと目を通しましたか?

それではさっそく説明開始!

ORG命令

上から順に行きますと、
まずORG命令が出てきますね。
意味は「メモリの○○番地から読み込んでいくよ~」です。
メモリの番地は16進数で指定してあげてくださいね。

むむ、「なぜ0x7c00なんですか?」って質問が飛んできそうですね。
理由はズバリ、ブートセクタが読み込まれるアドレスが
  0x7c00 ~ 0x7dff
と決まっているからなんです。
なぜそう決まったのかを私に問うのは禁止です。

FAT12

では次に、FAT12フォーマットフロッピーディスクのための記述部分ですが、
ここもほとんどが決まり文句と言いますか、このように記載するルールとなっています。
なのでここはあまり気にせずこの通真似して書いてください。

まあ気軽にいじれるところとしたら下記くらいですかね。
DB "HELLOIPL"   ;任意のブートセクタ名
DB "HELLO-OS "  ;ディスクの名前
バイト数は固定なので、そこだけ注意してくださいね。

entryラベル

ここからが本題のブートセクタ部分です。
ラベルごとに説明していきますね。

今日紹介するのは[entryラベル]。
ここでは、レジスタの初期化を行います。
ここについても順に説明していきますよ。

entry:
        MOV     AX,0
        MOV     SS,AX
        MOV     SP,0x7c00
        MOV     DS,AX
        MOV     ES,AX
        MOV     SI,msg

MOV命令とレジスタ

アセンブリ言語にはMOV命令というものがあって、
「MOV A,B」で「AにBを代入する」といった意味になります。

そしてAX,SS,SP等が何者かと申しますと、レジスタです。
レジスタというのは、CPUにある記憶回路のことで、
ここでは変数のようなものだと思っていただいて結構です。

今の説明を踏まえて上記ソースコードを人間様にわかりやすいように解読すると下記のようになります。

        SS=0
        SP=0x7c00
        DS=0
        ES=0

これだと数学みたいで分かりやすいでしょ?

あとは最終行の「MOV SI,msg」だけですね。
これもMOV命令ですので、結局は上記と同じです。

違いとしては、代入する値がラベル名となっている点ですね。
一見ラベル名を変数に代入なんておかしな話に聞こえますが、
代入される値は結局のところただの数値です。

実は、ここにラベル名を指定することで代入されるのは、
そのラベルが読み込まれるメモリの番地なのです。

つまり、msgラベルが読み込まれる番地(0x7c74)ということです。

そのため、「MOV SI,msg」を書き換えると、
「MOV SI,0x7c74」と書くことができます。

あらためてentryラベル部分を人間様の理解しやすいよう書き換えてみるとこうなります。

        SS=0
        SP=0x7c00
        DS=0
        ES=0
        SI=0x7c74

ここまでで、ブートセクタの下準備は完了です!
次回からは実際に「hello world」と表記させるためのコードを書いていきますよ。

1時限目は以上!休み時間!

参考

oswiki.osask.jp

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
1