はりぼて日記
12月 22 (金曜日) 2006 | ||
17:24
|
五日目2
|
|
五日目 〜2。
うーむ。構造体そのものはそんなわけで解っている。structを使って定義し、HariMain内で宣言して使えるようにすると・・・ struct BOOTINFO *binfo; ・・・え”? *binfo? binfoじゃなくて? *? え〜???? ひええぇぇぇ!!! わっかんね〜!!(泣 ・ ・ ・ ・・・ぁ〜 あ〜 あぁ〜!なるほどそういうことか! 前後の読み込みが足りなかった。なるほど。これは、「俗にいう変数宣言」じゃないんだ。極論すれば、「メモリのアドレスに名前をつけて扱いやすくしたい」というだけのことなのか!。勘違いしてた。 ええと、まず、一個前のソースでやってるよね。つまり、 binfo_scrnx = (short *) 0x0ff4; とか。これはどういう意味かって言うと、書き方が特殊なので「あれれ?」と思ったけどなんのことはない。 「メモリ番地 0x0ff4〜0x0ff5(2バイト分)を、binfo_scrnxっていう名前でアクセスできるようにしてくれ」 ってだけのことじゃマイカ。例の「型キャスト&省略」タイプの書き方なのでわからんかった。キャストや省略を無視して書けば、 short *binfo_scrnx; binfo_scrnx = 0x0ff4; と、こうしているだけなんですなぁ。なるほどなるほど。 で!!!! 同じようなことを構造体で一まとめにしてやっちゃおうってわけね。なるほど〜。 ちょっと変則的だけど、私はこんなふうに理解してみた。 たとえば、 struct BOOTINFO binfo; と普通に「binfo構造体」を定義する。その場合、定義どおりに、あるどこかのメモリ番地にbinfo用のエリアが予約される。(これはたぶん、毎回不定のはず。)じゃ、たとえば解りやすく、0x1000に割り当てられたとしよう。そうすると、 0x1000 char cyls 0x1001 char leds 0x1002 char vmode 0x1003 char reserve 0x1004 shor scrnx 0x1005 〃 0x1006 shor scrny 0x1007 〃 0x1008 char *vram (ポインタすなわちメモリアドレス用なので4バイト) 0x1009 〃 0x1010 〃 0x1011 〃 っとまあ、こういう感じになるわけだ。 ・・・・・で!!!!! この、毎回ちがうアドレスに設定される binfo構造体の開始アドレスを、0x0ff0 に強制的に設定したいわけ。(0x0ff0〜12バイトの部分には、asmhead.nasによってグラフィック関係の値がすでにセットされているので)そのための方法が、 struct BOOTINFO binfo; じゃなくて、 struct BOOTINFO *binfo; binfo = 0x0ff0; になるわけだ!(例によって型キャストとかはちょっと省略してある)なるほどなるほど〜!!! シンプルに分解したら、やっと解ったぞ! |
||
16:13
|
五日目
|
|
五日目〜。
うは! しょっぱなからむずかしいなぁ。構造体かぁ。 ええと、構造体そのものは幸い解る。ようするにこれは、配列だ。 たとえば、一年間の気温を記録したいとする。1〜12までと、数は決まっている。また、記録するデータも全部気温で同じようなものだから、12個の変数全ての型は同じでよい。そういう場合に、 int month[11]; とかやれば、12個のint型変数を用意してもらえる。 データを格納する時も取り出す時も、 a[8] みたいにすればいい。 しかし、もし、使いたいデータがみんな型がバラバラな場合どうしたらいいだろう? たとえば、「生徒の特徴」とか。 人の特徴だから、配列内に収めるデータは型がバラバラになる。 生徒「よしお君」 ┬─ 身長(int型) ├─ 体重(int型) ├─ 出身地(char型) └─ 年齢(Doble型) C言語では、変数は宣言時に型を決める。なので、上記のような場合、当然 int yoshio[3] ; とかやっちゃうと、出身地や年齢を格納できなくなってしまう。 int yoshio[3], ただし[2]はchar型,[3]だけSoble型; こんなことはできないだろうか? ま、それこそが構造体ということになるわけ。 構造体はさらに、こんな便利な要素もある。各変数を[2]とか[3]じゃなく、名前をつけて管理できる。これなら、「あれ? ええと、体重って[1]だっけ?いや、[2]だったっけ?」なんてことが起きないようになると。つまり、上記のような配列を作りたい場合、 struct 生徒データ { int 身長; int 体重; char 出身地; Double 年齢; } なんて宣言しておくと、「生徒データ」型の変数の配列を新しく定義できるわけ。「新しい変数型の定義」だから、以降は int a; int型の a という変数を宣言 char b; char型の b という変数の宣言 struct 生徒データ 義男; 生徒データ型の 義男 という変数を宣言 って感じで使えるようになると。こういうわけ。 配列内部へのアクセスも、普通の配列だと int a[11]; 配列の宣言 a[0] = 12; 一月の気温をセット a[1] = 14; 二月の気温をセット と、こういう感じになるけど、構造体の場合は struct 生徒データ 義男; 構造体「義男」を宣言 義男.身長 = 153; 義男の身長をセット 義男.体重 = 43; 義男の体重をセット と、こういう感じでできるようになるわけです。 (一応念のため書いとくけど、変数名等には実際は日本語は使えません) |
||
06:33
|
四日目3
|
|
四日目 終了〜。
やっべぇ!「OSっぽい」画面だ! う〜。いじりてー! まてまてまて。ここはグっと我慢。まだ先は長いんだから(汗 さて、この四日目で一番私が大事だと感じたのが、例の「アセンブラでCの関数を作っちゃう!」ってこと。 実は以前、私はOSの実験と学習のためにアセンブラで小さなブートプログラム(hideyOS 0.1)なんてのを作っていたことがあります。だんだん規模が大きくなってきて最後は収集がつかなくなって放置になってしまったのですが。 で、これに取り掛かる前、GCC(MinGW)でいろいろいじくっていた時のこと。どうしてもキーボードからの信号を受け取る方法がわからず、「こりゃ、アセンブラでやらないといけない部分だな」と判断して、GCC内でアセンブラを扱える「インライン アセンブラ」という機能を使おうとしたんです。 ・・・挫折・・・ いや、単に私の英語力や理解力が低いだけなんでしょうが、いくら調べても「チョコチョコ! パッ!」っとできる例や説明が見つからなかったんです。 当時の私は、「だめだ!インラインアセンブラは高機能なぶん、猛烈に複雑でかえってわからない!」と感じました。 その証拠に、その後、naskで書き始めたら数週間で目的を達成できたのです。(アセンブラそのものも勉強しながらプログラムしてた) しかし、やっぱりアセンブラ。プログラムしていくうち、漠然とではありますが、どんどん「・・・この調子じゃ、俺の頭が追いつかない・・・」になって来ました。 「naskでCの関数が作れたらなぁ・・・」 当時、そう思ったものです。 この四日目では、そのための方法と実例がばっちり書かれています。これを応用すればいろいろなことができるはず。 なんだか楽しみになってきました。 |
||
05:46
|
四日目2
|
|
四日目 〜5 まで終了〜。
うむむ・・・。ここがうわさのポインタ部分か。さらっと読むつもりだったけど、つい何回か読み直してしまった。 正直、ちょっと私の現在の理解はあやしいなぁ。でもとりあえず良しとしておくか。(進まないから) 現在の私の理解(まちがってたりたりなかったりの可能性大) ・メモリに直接値を書く必要がないなら、ポインタなんていらない! ・たぶん、ほとんどの普通のプログラムはポインタなんか使わなくても書ける。 ・OSなので、メモリに直接アクセスする必要がある。 ・Kタンがnaskfunkで作ったような関数があればポインタなんていらない ・しかしC言語ではそんな関数はない ・なので、ポインタというものを使う ・・・と、こんな感じ。で、さらに、 ●たとえばC言語に、<< アドレス番地 >> なんて命令があれば、*pなんてわけわからない書き方せんでもいい。 あるメモリに12を代入したいとする。(じゃ、たとえば0032番地とする。 アセンブラなら、 MOV BYTE[0x0032],12 私の「妄想C言語」なら、 <<0x0032>> = 12; で、実際のC言語の場合なら、 char *p; p = 0x0032; *p = 12; こう書かなくてはいけないと。そういうことみたいだな。キャストや演算( *(p+1)とかそういうの )は、便利に使うため。一旦忘れる!ってのが、理解を深めるのに役立ちそうかも?? ま、とりあえずこのくらいにしておこうっと。(こりゃ、早くも二順三順決定っぽいなぁ(^^; ) |
||
(1)  |
PopnupBlog V3 Denali created by Bluemoon inc. |