Yabu.log

ITなどの雑記

30日OS自作本4日目

今日はこの辺までできた。

画面描画周りの色々

day3から引き続き、ビデオモード設定の0x13モードを使っている

320*200*8bitカラー、パックドピクセル

らしい。

で結局画素の位置との対応は?

画面の左上が0xa0000から始まってそこから320x200=64000各番地の1バイトが1ドットに対応している

VRAMは0xa0000~0xaffffの64KBです。厳密に言うと、320x200=64000なので、62.5KBですが。1ドット==1バイトですので、がしがしライトしてください。リードもOKです。たるいBIOSで1点ずつ描いていく必要はありません。以上!

http://oswiki.osask.jp/?%28AT%29BIOS

気になったのは320x200=64000分色を書き込むなら スタート地点の0xa0000から64000(0xfa00)ぶんまでのメモリ、つまり0xafa00まで書き込めば十分だと思ったのだが、本では0xaffffまで書き込んでいる。

これの理由はよくわからない(かつこの本の著者ならこれは無駄だ!とか言いそうだけど特に触れてないのも謎。)。以下の2つのコードからは同じ出力が得られる

for (i = 0xa0000; i <= 0xaffff; i++) {
  write_mem8(i, 12); /* MOV BYTE [i],12 */
}
for (i = 0xa0000; i <= 0xafa00; i++) {
  write_mem8(i, 12); /* MOV BYTE [i],12 */
}

  • 12のデフォルトカラーは朱色?のようだ。この色にしたのは適当。白(15)だと見にくいと思っただけで特に深い意味はない。
  • macのウインドウは四隅が丸まっているせいで一番右下の場所へのドットの書き込みは確認できなかった。
  • MOV BYTE [i],12はIの番地に12を書け(データ長はバイト)という意味。ループで0xa0000~0xaffff番地に対して行う

配列とポインタ

  • ポインタの*pがp[0]と同じものを指す。
    • イメージ的にはp[0]*(p+0)
  • C言語の理解があやふやだとここでビビると思う。
  • 4年前までC言語書いてたけどこんなのあったっけ?
int num = 1;
int *p = &num;

/*いか全て1を出力*/
printf("%d\n",num);
printf("%d\n",*p);
printf("%d\n",p[0]);

以下のように配列をポインタを使って順次参照することもできる

//配列の宣言
int array[5] = {0,1,2,3,4};

for(int i=0;i<5;i++){
  printf("%d\n",array[i]);//01234
}

//上記のループと全く同じ出力結果になる
int *p = &array[0];
for(int i=0;i<5;i++){
  printf("%d\n",*(p+i));//01234
}

配列のインデックスはアドレスの加算として表現されている

C言語ではarray[index]とindex[array]は同じ。

int array[5] = {0,1,2,3,4};

printf("%d\n",array[2]);//普通の配列アクセス
printf("%d\n",2[array]);//なんじゃこりゃ~😱

なぜこのような不自然なことが起こるのでしょうか。 それはarray[i]*(array +i)の糖衣構文だからです。

int array[5] = {0,1,2,3,4};

/*全て2が出力される*/
printf("%d\n",array[2]);
printf("%d\n",*(array+2));
printf("%d\n",*(2+array));
printf("%d\n",2[array]);

C言語でなんでもできるわけではない

もう言わなくても察しはついていると思いますが、C言語にはIN命令やOUT命令に相当する命令がないので、私たちがアセンブラで作ってやらないといけないわけです。

C言語ってなんでもできる言語ってイメージがあるけど特殊なレジスタとか触れないし、ディバイスとかも触れない(らしい)。C言語でできないことはアセンブリ言語で定義した関数をC言語から呼び出すことで解決する。

おまけ(失敗)

uchan.hateblo.jp

やって見た

バイナリを打ち込んで。。。

起動ディスクの選択画面まではいけたが、その先が真っ黒で特にhelloworldしなかった。 打ち間違いがあったのかな?時間が無くなったので今日はこの辺でおしまい。*1

一応ハードとハッシュ(sha256を貼っておきます)

$shasum -a 256 BOOTX64.EFI 
263de38f271fe6c495f10cdbb914b6ee694545ba3b0527e6842892fe4d0ebed8  BOOTX64.EFI

感想

大学時代にOSの授業を受けていたけど、資源やプロセスの管理(セマフォ)とか割り込みとかの話が中心で、 コーディングはなぜかソケット通信をひたすら書いていた覚えがある。 GUIを作ろう、というのは一切なかった気がするが、ビジュアル的に冴えるものは学ぶモチベーションになるので良いと思う。

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

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

*1:qemuとかでやればできるのかな。