「OSを作れる」「仕組みが学べる」という言葉に惹かれて、プログラミング軽くかじった程度の私が、OSを自作しようと思い立ちました。

2019年の目標の一つは『OS自作入門でOSを作る』です。

目標を次のように設定。

「2019年3月31日までに、完読してわからないなりにもOSを自作してみよう。」

 

・・・・・

『本書』で言うところの、Chapter4(4日目)に入りました。

この項目から、CD-ROMに入っているFileフォルダの番号(haribxxx)と学習内容が一致するので、何をしているのかがわかりやすくなってきました。

本項目では、画面表示をいろいろいじれるようです。

ようやく暗闇から抜け出せる(かな)

 

◆ harib01a(C言語からメモリに書き込む)

C言語には直接メモリの番地を指定して書き込むための命令がないとのこと。

そのための関数を作るために、naskfanc.nasに書き足し。

write_mem8(0x1234, 0x56) :動作としては、MOV BYTE[0x1234], 0x56。addrはaddressの略で番地。

C言語でwrite_mem8が使われると、write_mem8にジャンプ。指定された数字はメモリにメモされていて、それぞれ

  • 1番目のもの:[ESP+ 4]
  • 2番目のもの:[ESP+ 8]
  • 3番目のもの:[ESP+12]
  • 4番目のもの:[ESP+16]
    (以下略)

に書いてある。

C言語で自由に使ってよいレジスタは、EAX, ECX, EDXの3つ。他のレジスタは値は使えるが変更できない。

 

「INSTRSET命令」:このプログラムは486用のものです。とnaskに教えている。

486はPCのCPU。

8086 → 80186 → 286 → 386 → 486 → Pentium → PentiumPro → PentiumⅡ → PentiumⅢ → PentiumⅣ → ・・・(286までは16ビットCPU。386以降は32ビットCPU)

 

C言語の改造。

「for構文」:{}でくくった範囲を繰り返す。{}の中は、繰り返しに関する条件などを書く。条件は、;で分けられていて、
・最初が初期設定 iにOxa0000という値を代入する。
・次に、「i <= 0xaffff」は繰り返し条件。この条件が満たされているかチェックして、満たされていなければ{}の範囲の繰り返しを打ち切り。
・最後は、「i++」i = i + 1の省略形。{}の中の実行が1回終わるごとにiに1が加算される。

「for構文」で3つの条件を省略した場合は、
・初期設定、何もしない。
・繰り返し条件、常に成立。
・{}の実行が終わったあとの処理も何もしない。
⇒ 無限ループ。

VRAM全部に15を書き込んだので15番目の色:白になりました。

ついでに数字を3に変えてみたら、水色(シアン)になりました。

 

◆ harib01b(しましま模様)

bootpack.cの中身を変更。

write_mem8の中身を番地は変えず、書き込む値を i & 0x0fに変更。

&は&演算

 

・オア(OR)演算:A OR Bを計算するとき、それぞれの桁についてAかBのどちらかが1だったら、結果も1にする。そうでなければ0にする。

0100 OR 0010 → 0110
1010 OR 0010 → 1010

・アンド(AND)演算:AAND Bを計算するとき、それぞれの桁についてAかBの両方で1だったら、結果も1にする。そうでなければ0にする。

0100 AND 1101 → 0100
1010 AND 1101 → 1000

・排他的オア(XOR)演算:それぞれの桁についてAとBの値が違えば結果を1にする。そうでなければ0にする。

0100 XOR 0010 → 0110
1010 XOR 0010 → 1000

 

今回は番地の値(i)に0x0fをANDするので、

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00 01 02 03 04 05 06 07 08 ・・・・

繰り返し。

 

◆ hari01C (ポインタについて)

「C言語には直接メモリの番地を指定して書き込むための命令がない」

⇒ 代わりの表現がある。

write_mem8 (i, i & 0x0f);

*i = i & 0x0f;

 

実際には、i(=[i])が、BYTEなのかWORDなのかDWORDなのかわからないので、

char *p;  /* これはpという変数がメモリ番地専用変数だという意味 */

という変数を宣言して、

*p = i & 0x0f;

とする。

char *p;   /* BYTE用番地の場合 */
short *p;  /* WORD用番地の場合 */
int *p;      /* DWORD用番地の場合 */

 

しかし、このままでは、警告があがるので、

p = (char *) i;

とする。

この記述を使うと、write_mem8は不要になる。

 

ポインタについては、本稿にて非常に詳しく説明されているが、初心者の私には「こう書くのか」にとどめておきます。わからなくなったら、またここに帰ってきますね。

 

◆ harib01d (ポインタの応用(1))

こんな書き方もできる。

 

 

◆ harib01e (ポインタの応用(2))

こんな書き方もできる。

ということで、画面をいじることができました。

『ポインタ』は、今後も要注意項目としてチェックします。

 

以上。

スポンサーリンク