はりぼて日記
10月 11 (木曜日) 2007 | ||
17:58
|
24日目
|
|
24日目〜
どどどど〜っと、ウィンドゥ関係の改造〜。 ちょっと読むのが大変だったけど、とりあえず引っかかるところは なさそうだぞ。 P507 タイマー関係もOK。 進む〜♪ そんなわけで、24日目終了〜 |
||
10:38
|
23日目
|
|
23日目〜。
おは〜 (笑 メモリの確保かぁ・・・ P471
かぁ・・・。えっと。これはどこでやってるのかな?? あったあった。 P460の一覧表。そしてそれをP461のconsole.cで解析して、セグメント等の設定とメモリ確保をしているね。 他のコード。 大体意味はわかるな。 P474 点を書くAPI。 うむ!これは簡単だ! これまでの応用or一部手直しでいけてるよね。 うーん。線を描く「隠し味」をもうすこし検証したいんだけど、 今回はこのまま。 あとは難しいところない〜♪ そんなわけで、23日目終了〜 |
||
10月 10 (水曜日) 2007 | ||
22:57
|
22日目3
|
|
さてそんなわけで、だいたいなにをやってるかがやっと理解できました。
P467 なるなる〜。 内容はちがえど、これまでと同じ手法ですねぇ〜。 そんなわけで、22日目終了〜 |
||
20:50
|
22日目2
|
|
------------約1時間後-----------------
・・・あーー! なるほどなるほど! そういうことかぁ! P439の_asm_hrb_api。ここを見てみてやっとわかった! 例えばだけど、現在のスタックの番地(ESPの値)が仮に0x1234だと過程する。この状態でPUSHADを二回行うと・・・
こういう状態の後、C言語であるhrb_apiに渡される。 関数hrb_apiは各引数を、順にESP+4の倍数としてスタックから受け取る。つまり、0x11F8から int ediを、0x11FBから int esiを・・・・0x1214から int eaxを。こうして受け取っている。 ・・・ここで、
という命令を行うと、ポインタである*regには引数である int eaxのお隣、すなわち0x1218が設定される。 (*regをint型で宣言しているため、4バイト刻みになる。なので、+1するということは4バイト先ということになる) hrb_apiの後ろのほうで、
という処理をしている。これは配列という意味ではなく、*regから7個お隣と言う意味として使われている。 すなわち、0x1234番地にshtの値が書き込まれたわけである。 この処理の後、hrb_apiはreturn命令で戻る。どこへ戻るのかといえば、自分を呼び出したasm_hrb_api(アセンブラプログラム)に戻ってゆく。 処理が戻ってきたasm_hrb_apiはアプリ終了かそうでないかを判断した後、
という処理をする。これはどういうことかというと、 本来ならPOPADを二回行うはずである。(だってPUSHADを二回やってるから。そうしないとつじつまが合わない) しかし、当たり前だがPOPADはレジスタの値を書き換える。二回目にPUSHADした値はC言語実行の後だし意味がない。まるごと戻す必要がないのだ。 そこで、POPADはするがレジスタは書き換えない。そのため、ADD ESP,32を行う。これで、ESPの値すなわちスタックの番地が0x11F8から0x1228になる。 この状態でPOPAD! レジスタには、0x1228〜0x1234の値が書き込まれ、元の状態に戻る。 (ただし、本当に元の状態ではない。0x1234の値は書き換えられている。) これでIRETDを行い、処理を割り込み前のapi_openwinに戻す! アセンブラプログラムであるapi_openwinは後処理をし、呼び出し元に戻る。 api_openwinを呼び出したのはC言語であるwinhelo.cである。 処理が終わると変数winに現在のEAXの値を代入して処理を終える。 ・・・・ぷっはあぁぁぁぁ! やっとこさ整理できたーー! ・・・うーむ。ここいらへんはアセンブラやCを行ったり来たりなのでややこしいなぁ〜・・・ |
||
13:26
|
22日目
|
|
22日目〜。
さらにOSを守る。 P446 ふーむ・・・ IN・OUT命令はアプリからは使えないと。(使えるようにすることもできなくはないよう・・・) そう考えると、ドライバなどはどう考えたらいいのかな? ドライバはアプリとすることは出来ない。(上記の理由で) ということは、ドライバはOS側ということになるのかな。 Win等の市販のOS(サードパーティーがドライバを提供するのが 当たり前になっているOS)ではどう考えているんだろう??? P449 黒川合退散〜 (笑 アプリ作成再開! P451 ・・・むむむ!?? あれれ? これけっこう重要and知らなかったかも? C言語で配列を宣言した場合、それはメモリではなくスタック内に設定される(まあスタックも、メモリっちゃあメモリだけどそこは分けて考える) っていう理解でいいのかな??? 普通の int a; とかはどうなんだろう? こっちはメモリなのかな??? P453 うーむ。おもしろいなぁ。 割り込み発生時に各レジスタの値も表示すると・・・ (今思うと、OSASKのバグ表示もこれだったのかな) P458 ・・・あれれれ? 例の6バイトのことだ。あっれーー? なんか見落としてる? ちょっと戻って整理してみよう。
・・・ふむ!! とりあえずこんな理解でいいのかな。 で!!!
・・・こんなところかな???・・・・・・ P459 ふむ・・・・このあたりから、.hrb(実行ファイル)の内部構造が 解説されてるね。 なるほどなぁ。実行ファイルって、ただ最初からベターっと プログラムが書かれているわけじゃないんだね。 また、なんのためにそういう仕組みになっているのかもこれを 読むと良くわかる。 ついでに、なぜ、先の6バイトで0x1bをコールしているのかも ここで解説されとりますね。 P463 へえぇぇ。 .textと.dataかぁ。なんかややこしいですねぇ。 (まあ紛らわしいってのはもう、しょうがないんでしょうね。) P465 へえぇぇぇ! こりゃおもしろい! PUSHとPOPって別に絶対的なことじゃないんですねぇ。 ん??? あれぇ? P466のwinhelo.cのソースでapi_openwinからの戻り値を取ってる。(int win) ここには何の数値が入る?。どこでその処理をしてる??? もしかしてCとアセンブラの連携だったっけ?。ちょっとメモを見よう・・・ えーーーっと! Cからアセンブラの関数を呼んだ場合、パラメータが左から順に、 [ESP+4]、[ESP+8]、[ESP+12]・・・と格納されると。 さらに、アセンブラ内ではEAX・ECX・EDXしか使えないと。 (P466のa_nask.nas内では使っているが、やっぱり本来は使っちゃいけないレジスタなので、EDI・ESI・EBXをスタックに退避させ、API割り込み呼び出し後にPOPして復元してから終了してるわけ) ・・・あ”こっちかぁ。 P465のconsole.cのほうかぁ。 あーーー! なんかちょっと読み飛ばしてたみたいだ! P464でちゃんと、EAXに戻り値が設定されて帰ってくるってことにしてるんじゃん!
えっと。これを踏まえて・・・ |
||
11:58
|
21日目
|
|
21日目〜。
P422 あったり〜。 (^^ P423 さーていよいよC言語に突入だぁ〜。 ふむふむ。これも重要だよね。アセンブラとのリンクのやり方。 ・・・あれ? んーーと? 先頭の6バイトのことはもう少しあとだっけ??? P427 OSの保護とな? うーむ。理屈はわかるぞ! P432 了解〜。ご指南どおり、とりあえず軽〜く流します〜(汗 (とはいえ、なんとなく、なにをしているのかはわかるぞ。とにかく、各コードが動く時にレジスタを調整し、アプリ実行時とOS側の動作時にレジスタやセグメントが混ざらないように徹底的に分離しているわけか。) P440 たははは・・・。軽く流しておいてよかった。全部自動でできるじゃん!!(^^ P441 0x40を、アプリ側から呼んでも構わないという設定にするのね。 (ふと思ったが、他の空いている割り込みはどうなんだろ?。この時点での ことはともかく、最終的には全部それなりに設定しておくべき なのかな? それとも??) 他のソースはわかるよね。 ようするに、各コードのお尻に終了用のAPIをコールさせると・・・。 うーむ。コードはけっこう難しかったけど、わりとよくわかったなぁ。 そんなわけで、21日目終了〜 |
||
11:16
|
20日目2
|
|
20日目2〜。
さて例の呼び出し先の番地の問題。 ・・・おぉぉ! なるほど。割り込みを使うのか! P410 お? ここ重要かも。(後で忘れてハマりそうな悪寒・・・) CPUは割り込みが発生すると自動でCLI命令を実行し、以降割り込みが禁止される。なのでこれが必要ない場合は呼び出された割り込み命令 の先頭でSTI命令を発効しておく なお、この処理は本来はIDT登録の折、パラメータかなにかで 設定が可能&本来はそうするべきらしい。 P415 ・・・むむむ? わかるけど素朴な疑問。 なんでこの処理でECXレジスタの値が壊れちゃうんだろ?? 今はとりあえずそういうものだということにして後でよく考えて みよう。 ここは棚上げ〜 P418 いえいえ〜。Kタンだけじゃなくてオイラも読みやすいっす。(^^ このあたり。つまり機能番号で分岐するように多段化したわけですね。しごくごもっとも! ・・・でも失敗・・・ んんんん?? なんでだろう? 次に進む前にすこし自分で考えand思い出してみる。 ・・・セグメントじゃないかな・・・ だって、一文字表示は文字コードをレジスタで渡しているけど、 文字列表示の場合、渡されるのは文字列が格納されている番地 (ポインタ)でしょ? 呼んだ者(アプリ)と呼ばれた者(OS内のAPI)ではセグメントが 違うから、うまくいかないんじゃないかな・・・ さてさて??? そんなわけで20日目終了〜 |
||
10月 09 (火曜日) 2007 | ||
18:19
|
20日目
|
|
20日目〜。
ひさしぶりのソース整理の後は、いよいよAPIだ! ・・・ふむ・・・ APIはいわば関数の塊だよね。これをアプリからコールする。 そのためにはコールするための場所がわからないといけない。 また、レジスタ内に保持したパラメータ(この場合は文字コード) はCとの関数のやりとりで壊れてしまうので、スタックに積むと。 コールする場所だけどその場所を記憶しておくところを作る。 (0x0fec)。なぜこんなことをしないといけないのか。 関数consの場所はプログラムを書き換えたりするとすぐにコロコロ 動いてしまう。なので、コンパイルして実行したときに初めて consの実際の場所が確定できるわけね。 なので、実行時に実際のconsのアドレスを調査して、それを0x0fecに書き込んでおくというわけ。 P403の_asm_cons_putchar関数はなにをやっているかというと、
・・・と、しかしこの完璧な構想にはエラーが・・・(^^; これはもう、すぐにピンとくるよね。そう。セグメントが違うじゃんということ!! P405 予想通り〜。 そんなわけでCALLとRETをfar対応にすればOK〜。 P407 わははは! まだコールする場所を手作業でやっているため こんなことが起こるんですねぇ〜。 いずれこれも自動化されるはず! |
||
17:44
|
19日目
|
|
19日目〜。
なんだかエライペースで進んでますなぁ (^^; まあオイラの場合、一回読んでるので。 その時ちゃんと理解できたものはもう、ただの復習なので早いのです! ・・・うーん。こまった。特にわからないところも ないしなぁ・・・ そんなわけで19日目終了〜 |
||
17:18
|
18日目
|
|
18日目〜。
わはは! カーソル点滅おもしろ〜い! スクロールもエンターキー対応もおもしろ〜い! コマンド搭載&追加もおもしろーーーーーーい! おっとぉ! P371。いよいよdirコマンド! これこれ! 構造体をポインタで定義して、そこにアドレスを当て込んじゃって しまえば、メモリの規則正しい配列はそのまま構造体の要素と して読めちゃうっていうテクニック! しびれる〜! さーて。そんなわけで18日目終了〜 (・・・やべー・・・はやく改造してーー!) |
||
1 (2) 3 »  |
PopnupBlog V3 Denali created by Bluemoon inc. |