30日OS自作入門-1〜2日目-
前回までで環境構築を終わらせましたので、早速作業に入りたいと思います。
今回やっていく内容
- 1日目の部分
- 2日目の部分
1日目部分
やったことは以下の通り
- おもむろにバイナリエディタを起動し、hexを写経(鬼w
- テキストエディタを起動し、DB命令を使ってhexを記述(18万4314行の¥x00を打ち込む必要がある。これも鬼w)
- アセンブリ命令を少しづつ加えながら、hex自体で書く量を減らしていく
主にhexを写経していくような作業。結構しんどいけど、「0x〜」を打鍵するスピードが上がった気がします
命令
DB(data byte)
- ファイルに1byteのデータを直接書く命令
- DB命令のオペランドはカンマで区切ると複数指定可能?(本では8バイト分)
- ファイルに書くデータの大きさによって以下のような命令がある
- DW(data word) : 2byteのデータを書き込む
- DD(data double-word) : 4byteのデータを書き込む
- DB命令については、オペランドに文字列を指定可能
RESB(reserve byte)
- 指定したバイト数だけ0x00を書き込む
んで、RESBに関連する部分で$マークを使い余り部分を0書きするという部分がありました。
RESB 0x1fe - $
ここでの$は「先頭行から何バイト目か」を教えてくれる変数として機能します。なので、例として$マークの部分が先頭から0x1f0行目だったとしましょう。そうすると、
0x1fe - 0x1f0 = 0x00e
となるため、RESB命令部分は
RESB 0x00e
となり、ファイル内のアドレス0x1f0から14byte分0を書き込みます。
。。。という感じなのですが、私の環境(linux+nasm)では$のままだとアセンブルできないので(エラーが出る)、linux+nasmでやっている方であればこの部分のコードを以下のように変更します。
RESB 0x1fe - ($-$$)
これについては、以下の記事を参考にしました。
tsurugidake.hatenablog.jp
この2つの命令を使ってnasファイルにコードを打ち込みアセンブルしてimgファイルを作成し、それをqemuで実行します。
nasm helloos1.nas -o helloos1.img
qemuでの実行
qemu-system-i386 helloos1.img
そうすると、こんな感じで画面が出てきます。
実際に起動して、ちゃんとhello worldの文字が見えるとやはり感動しますね。
まぁ、1日目については主に今後の作業の流れを掴むような作業でしょうか。
2日目部分
2日目から少しずつアセンブリ命令とレジスタなどを使って処理を書いていきます。
命令
ORG(origin)
- 記述した機械語をメモリ上のどのアドレスに読み込ませるか指定する命令
- ORG命令を使ってメモリ上のアドレスを指定した場合、$マークの意味も「読み込まれるメモリ上のアドレス」になる(nasmを使う場合は注意)
- コードの先頭部分でまずは以下のように指定を行う
ORG 0x7c00
INT(interrupt)
- ソフトウェア割り込み命令(詳細は後日)
HLT(halt)
- CPUを待機状態にする命令
- 外部で変化があればCPUがプログラムの続きを実行
(節電したいのであれば、使うべき?)
レジスタ関連
レジスタについては、今の所16bitのものが出てきますが、そのうちAX, BX, CX, DXについてはそれぞれ8bitレジスタとしても使える(AXはAHとALとして指定することも可能)というところは覚えておく必要あり(あとで出てくるので)。
バイトオーダー
MOVなどの転送命令でメモリ上にデータを格納する場合には、データの下位バイトからメモリに格納される点に注意。このような、メモリ上にデータを格納する方式のことをバイトオーダーと言い、こん秋のようにデータの下位バイト(桁のくらいが小さい方)からメモリ上に格納していく方式をリトルエンディアン。
(ビッグエンディアンはデータの上位バイトから格納していく方式。直感的にはこっちの方がわかりやすいかも)
エラー、警告関連
記述したアセンブリコード(nasファイル)をnasmでアセンブルするたびに以下の警告が吐かれていました。
warning : uninitialized space declared in .text section: zeroing
ひとまず警告は出ていたとしてもimgは起動できたので置いておいたのですが、気になったので解決法を調べてみたところ、同じような環境でやっている方がブログに書いておりました。有難や。
d.hatena.ne.jp
tsurugidake.hatenablog.jp
基本的にはRESB命令をTIMES命令に書き換えて、格納する値を定義してやるという感じですね
TIMES <繰り返す回数> DB(データの大きさ) 値
書き換えることによって、上記の警告は出なくなりました。