無限遠まで突撃中

ネット日記書きの徒然。

「30日でできる!OS自作入門」を今更ながらやってみる - 2日目

今日もやるぞOSやるぞ

1日目は こちら

2日目 - アセンブラ学習とMakefile入門

1 - まずはテキストエディタの紹介

TeraPad…ではなくvimを用いました。

2 - さて開発再開

また新たな命令が出てきました。

  1. ORG : 機械語が実行時にメモリのどの番地にロードされるか
    例: ORG 0x7c000x7c00 番地からスタート
    GAS(GNU Assembly)なんかだと ORG 命令がないのでリンカスクリプトで指定してあげます。
    こんな感じ↓
SECTIONS {
    . = 0x7c00; //「.」は現在の番地を表します。
}
  1. JMP : JMP 0x3cf5 とか JMP loop みたいな感じで使う
    メモリの番地かラベルまでジャンプする

  2. MOV : MOV SS,AXSS = AX と同等の作用(SSにAXを代入)

ゆかいなレジスタたち

16ビットレジスタくんたちです。

  • AX : アキュムレータ(累積計算機という意味)
    各種演算に使うと効率がいい
  • CX : カウンタ
    回数を数えるときに使うと効率がいい
  • DX : データ
  • BX : ベース
    メモリの番地計算の起点に使うと効率がいい
  • SP : スタックポインタ
  • BP : ベースポインタ
  • SI : ソースインデックス(読み込みインデックス)
  • DI : ディスティネーションインデックス(書き込みインデックス)

レジスタには上のような役割があるらしい。何も書いていないものは今はわからないものです。分かり次第追記します。

次は8ビットレジスタくんたちです。

  • AL : アキュムレータロウ
  • CL : カウンタロウ
  • DL : データロウ
  • BL : ベースロウ
  • AH : アキュムレータハイ
  • CH : カウンタハイ
  • DH : データハイ
  • BH : ベースハイ

16ビットレジスタに名前が似ているのは、たとえば AX = 0x3c21 だった場合、 AL = 0x21 , AH = 0x3c のように、 AX の下位8ビットが AL に、 AX の上位8ビットが AH に入るらしいです。
ところで8ビットの各種演算の時は ALAH のどちらを使うとより効率がいいのでしょうかね?わかったら追記します。
32ビットレジスタとセグメントレジスタの解説についてはまた今度。

メモリは[]で囲もう

NASKではメモリの番地を指定したい場合は次のように書きます。

MOV SI,0x21
MOV AL,[SI]

これは レジスタ AL に、メモリ SI 番地に保存されている値を書き込みなさい という意味です。今回の場合は 0x21 番地に保存されているデータが AL に代入されます。
メモリは[]で囲むと良さそうです。

トルエンディアンで行こう

本によるとどうやらメモリには8ビットずつの塊でデータが保存されるらしいです。ここで問題なのがその保存方式です。こんな感じで保存されます↓

https://upload.wikimedia.org/wikipedia/commons/thumb/3/3c/Little-Endian-ja.svg/280px-Little-Endian-ja.svg.png (Wikipediaより)

これはつまり、 MOV [678],0x007f8400 みたいにすると、 678 番地に 0x8400 が、 679 番地に 0x007f がそれぞれ保存される 、ということです。
この保存方式を巷では「リトルエンディアン方式」なんて言うみたいです。詳しく解説はしないので気になった人はググってください。

INT命令とBIOS

新たな命令です。

  • INT : ソフトウェア割り込み命令のこと

これだけだと何がなんだかわかりませんが、今のところはBIOSの関数呼び出しの一種だと思っておけばいいらしいです。
BIOSというのは「basic input output system」の略です。いかにも画面に文字表示したりキーボード入力できそうな雰囲気ですね。これを用いてハロワを表示させていたんですね〜

一文字を表示させるためには以下のように設定すればよいそうです。

  • AH = 0x0a
  • AL = キャラクタコード
  • BH = 0
  • BL = カラーコード
  • 戻り値: なし
  • 注: ビープ、バックスペース、CR、LFは制御コードとして認識される

以上を設定して INT 0x10 とすると文字が出ます。

出たよ0x7c00

ここのプログラムでは ORG 0x7c00 と設定していますが、これは
0x7c00 ~ 0x7dff が、ブートセクタが読み込まれるアドレス
だからです。
なんで 0x7c00 なのかは この記事 に詳しく書いてあります。

3 - ブートセクタだけを作るように整理

コードを分割するだけなので略!!!

4 - 今後のためにMakefile導入

とくに難しいことはないので省略!!!(一般生成規則などややこしいものが出てきたら解説入れます)

今日はここまで

お疲れ様でした。また明日!
3日目は こちら