はりぼて日記
2007 | 01 | 02 | 03 | 04 | 05 | 07 | 08 | 10
2006 | 11 | 12
10月 12 (金曜日) 2007
23:30
28日目2
 
28日目2〜。

おまたせしました!いよいよ日本語表示だ!

P613
えーっとえっと・・・・
ちょっと込み入ってるけどむずかしくはないな。そして例の構造体に当て込むテクニックね。

P617
これたしか、前回も思ったんだよね。
「え? こんなに簡単でいいの??」
って。

P622
・・・いや、ほんとにこんなに簡単でいいの?? (^^;

P627
うお!!
バグだぁ!
うーん。このバグはおもしろい?よね?
半分しか文字がでない。(全て右側)
ウィンドウを動かすと直る・・・

ちょっと考えてみよう。

うーむ。全てが右側欠けになるわけじゃない。EUCという、
そもそも半角の文字はちゃんと表示しているなぁ。
全角文字だと判断して表示している部分をチェックしてみる・・・

ここかな?P619のputfontの辺り。

・・・ダメだなぁ。おかしい所、特にないなぁ。

putfont8そのものがおかしいのかな?
いや、そらならEUC部分も変になるのでは???

順を追ってみてみよう。


  1. この以上はchklang.cにて起こる
  2. chklang.cで文字を表示するにはapi_putstr0を使っている
  3. api_putstr0は_api_putstr0(P457)を呼び出す
  4. _api_putstr0は機能番号2を使い、INTしている。
  5. これにより、hrb_apiに制御が渡り、cons_putstr0が呼び出される(P422あたり?)
  6. cons_putstr0は内部で文字数分だけcons_putcharを呼び出しているだけ。(P416)
  7. cons_putchar(P398)。普通の文字の表示のためにputfonts8_asc_shtをコールしている
  8. putfonts8_asc_shtは内部でputfonts8_ascをコールしている(P250)
  9. putfonts8_ascは内部でputfonts8をコールしている(P106)
  10. putfonts8でようやくvramに書き込んでいる(P102)


・・・ダメだこりゃ・・・
下から順にソースを追ってみたんだけどわからないや・・・・

半分欠けてしまう原因って・・・・
 
30日を過ぎたBlogにはコメントできません。

Referer  (2)
21:23
28日目
 
28日目〜

P594
なになに? alloca?
んーーーっと・・・・
1000までは  char flag[MAX], s[8] では、
charだから1バイト。それが配列として宣言されるから1000バイト。
1000バイトは1KB弱かぁ。だからOKと。
で、これが10000になっちゃうとええと・・・9.7KB。たしかに4KBを超えてるなぁ。

ちなみにちょっと実験。ほんとに4KBが境目かどうかやってみました。
えっと、4KBってことは1024*4だから、4096bだよね。MAXを4095にして実行!

うほぉ! とまったぞ??? おっかしいなぁ・・・

3500はOK・・・
3900もOK・・・
4000だとおかしくなるけど、なんかちょっと違うぞ??
3950はOK・・・
3960もOK・・・
3970もOK・・・
3980もOK・・・
3990からおかしいな。
3985もダメ。
3984・・・おぉぉ! OKじゃん!!

ふーむ・・・つーことは、3984が実質限界ということかぁ・・・
配列は0からスタートするから個数としては3985。3985バイト・・・

これはなんの数値だろう??
あ” そうか! 同じく配列タイプがもう一個あるな。[8]だから
9個。足し算すると3994。3994バイト・・・。
スタックの限界値は4KBすなわち4096バイト。102バイト足りないけど、これはなにに使われてるんだろう???

まあいいや。とにかく、ほぼ4KBを境におかしくなるのは間違いないようだなぁ・・・

で!! 

とにかくCコンパイラがこの仕様というわけか。(ここまでは理解)
ほんでもって、_allocaがなくてもいいようにmallocでメモリを確保しておいて、それをflagに当て込むと・・・。これも理解。
(つか、おもしろいね。このテクニック・・・(^^  )

で、_allocaを搭載すると。


ところで、スタックに領域を確保するのにESPの引き算って、これ、意味解る?
スタックは積まれていくことを思い出すと理解できるよね?(^^



P601
さていよいよファイルAPIだ!!

おぉぉっと! 予想に反してなんかこれ簡単だぞ!??


P609
コマンドラインの取得ね。・・・うーん。そんなに言うほどややこしくないと思うぞ?
 
30日を過ぎたBlogにはコメントできません。

Referer  (7)
15:44
27日目3
 
P580
にょにょ〜!
まーたKタンの大好きなダイエットかよおぉぉ・・・・(


と思っていたらそうじゃない!
ライブラリとはなにかの解説じゃないですか!これは有用ですよ!?

整理してみると・・・

  1. アプリのサイズがやたらデケー! なんで?
  2. APIとして容易されている関数の全てがアプリに入ってしまっているから。
  3. まてよ! このアプリでは○○○は使うが△△△は使わないじゃん! △△△までは内蔵しなくていいだろ!
  4. だってしょうがないじゃん。全てのAPI関数が一個の.objに内蔵されてるんだもん。これをリンクすりゃ、そりゃ全部はいっちゃうだろうが。
  5. よしわかった! じゃ、全部の関数を一個一個の.objに割っちまえ。それならいるものだけがリンクできるだろ!
  6. いいアイディアだ!そうしよう!
  7. あらこんなにスッキリ!!!!!
  8. ・・・問題発生だ・・・関数が増えて.objが増えてくるととても把握できん!!!!
  9. おっと? .objが粉々な場合、把握なんかしないで全部書いておけばいいと? それならリンク時に、実際に使ったのだけリンクしてくれると? 便利〜!!! じゃあ黙って全部書いておこう!
  10. *.objが多すぎるよぉ〜。なくしたりしたらもうワケワカンネ!
  11. LZHとかみたいに、一個にまとめられね?
  12. そんなわけで誕生! ライブラリ!!!



なんか一見すると最初の全部入りobjに戻ってしまったようにも
見えますがそうじゃないんですよね。ライブラリ&.hファイルに
よって、ようは9番をフルオートでやってくれるようになったと
いう認識ですな。


まあ、理屈的に考えればリンカが賢くなって、使っていない部分は
自動でひっこぬいてくれるようになればライブラリなんていらない?
と言えなくもないかもしれませんが、それはまた別の話というかね。


そんなわけで、27日目終了〜
 
30日を過ぎたBlogにはコメントできません。

Referer  (1)
13:26
27日目2
 
P577

えーっと、まず、GDTをもう一回復習。

GDTはメモリ内の設けられた特別な意味を持つ領域。
(メモリのどこにするかは原則自由。GDTRというレジスタに番地を
設定すればそれでいい。)

たとえばGDTRに、0x10000を設定したとする。すると以降、CPUはここから
8,191までの範囲をGDTとして扱うようになる。
GDTは表。一個(一行?)に各要素があり、次の行へ移る。
(とりあえず1行は8バイト。64ビットある。これ刻みに行が移る)

┌────┬────┬───┬────┬─────┬───┐
│アドレス│GDT番号 │大きさ│開始番地│  属性 │   │
├────┼────┼───┼────┼─────┼───┤
│0x10000 │ 0  │   │    │     │   │
├────┼────┼───┼────┼─────┼───┤
│0x10008 │ 1  │   │    │     │   │
├────┼────┼───┼────┼─────┼───┤
│0x10010 │ 2  │   │    │     │   │
├────┼────┼───┼────┼─────┼───┤
│    │    │   │    │     │   │
  :     :   :    :    :    :
├────┼────┼───┼────┼─────┼───┤
│0x1FFF0 │ 8190 │   │    │     │   │
├────┼────┼───┼────┼─────┼───┤
│0x1FFF8 │ 8191 │   │    │     │   │
└────┴────┴───┴────┴─────┴───┘


これに対して普通にGDTを一個設置したい場合は各項目に書式に
したがってデーアを当て込めばいい。たとえば、
・あるセグメントを0x80000〜0x90000(64kb)として作りたい
・このセグメントはアプリが使う(コード)
・とりあえず0、1はOSで使われているようなので、2番とする。

こうしたい場合、

├────┼────┼───┼────┼─────┼───┤
│0x10010 │ 2  │64kb │0x80000 │アプリ用C │   │
├────┼────┼───┼────┼─────┼───┤


こう設定すればいい。
これでメモリ0x80000〜0x90000がアプリ用のセグメントとして管理
されるようになる。アクセスする場合はセグメント2番として行う。

IDTというのがある。IDTは割り込みが来た時にどの番地にジャンプ
するのかを、同じようにメモリの一部にずらーっと書いてある。
どこからどこまでがIDTなのか?という設定も、同じくレジスタ
に書き込めばいい。IDTLレジスタにIDTのスタート地点としたい
番地を設置してOK。

さてここで問題が生じる。
マルチタスクでは他に、TSSという設定一覧表が必要になる。
TSSはレジスタの退避エリア&タスクの設定が書かれた表である。
この流れで行けば、CPUのどこかにTSSLなんてレジスタがありそう
だがこれはない。
TSSはGDTで設置する。つまり、どこか適当な番号のセグメントを
設置して、そこはメモリとかではなくTSSなんだという属性を
与える。例えば、

・メモリ0xA0000を、あるタスクのTSSとして設置したい。
・TSSはどこにでも設置できるが大きさが決まっている(それ以上いらない)

なんて場合は、

├────┼────┼───┼────┼─────┼───┤
│0x10018 │ 3  │104b │0xA0000 │TSS用   │   │
├────┼────┼───┼────┼─────┼───┤

こうしてあげれば0xA0000〜0xA0103までがTSSになる。

・・・はっはぁ・・・・

こうやって整理してみたら、ちょっとわかってきたぞ??

TSSはGDTのように専用のレジスタを使ってポンと設定できない。
変則的だがGDT内に、「俺はTSSだー!」と設定するわけ。
同じような考え方でLDTを作るわけ。
LDTはGDTとそっくりな構造だけど、「どこからどこまでがLDTか?」
という設定をレジスタではなくGDTセグメントにて設定するわけ。

たとえばLDTを0xB0000に設置したいとする。流れからすると、LDTLなんて
レジスタがCPUにありそうだが違う。TSSと同じく、どこか適当な
GDTに設置する。(空いているところでいいようだ。)
具体的には

├────┼────┼───┼────┼─────┼───┤
│0x10020 │ 4  │15b  │0xB0000 │LDT用   │   │
├────┼────┼───┼────┼─────┼───┤


これで0xB0000から始まる、GDTとそっくりな表が形成される。
大きさを表すパラメータ。(今回は15bとしている)これは最大値(64KB)は決まっているがいくつでも構わない。GDT
の場合は開始番地をレジスタに設置した瞬間、自動的に最大値まで
が確保されるが、LDTは必要な分だけでよい。今回は2個しか
必要じゃないのでこれでいい

この作業を行った後には、

┌────┬────┬───┬────┬─────┬───┐
│アドレス│LDT番号 │大きさ│開始番地│  属性 │   │
├────┼────┼───┼────┼─────┼───┤
│0xB0000 │ 0  │   │    │     │   │
├────┼────┼───┼────┼─────┼───┤
│0xB0008 │ 1  │   │    │     │   │
└────┴────┴───┴────┴─────┴───┘

こんな感じでLDTが作られる。
仮にこのLDTで0xC0000から始まる64KBのセグメントを二つ作るとしよう。


┌────┬────┬───┬────┬─────┬───┐
│アドレス│LDT番号 │大きさ│開始番地│  属性 │   │
├────┼────┼───┼────┼─────┼───┤
│0xB0000 │ 0  │64KB │0xC0000 │アプリ用C │   │
├────┼────┼───┼────┼─────┼───┤
│0xB0008 │ 1  │64KB │0xD0000 │アプリ用D │   │
└────┴────┴───┴────┴─────┴───┘

こうなる。

さて!!!!!!!!!!!!

このLDTで定義されているセグメント(0xC0000〜)を使えるのは
誰か? 誰でも使えるのか?? いやそれでは困る。

そこで、各タスクを管理しているTSSに、このLDTを使ってもいいと
設定をする。このLDTを作っているのはGDTの4番である。
TSS内のldtrに4番と指定を入れると、このLDT(で定義されているセグメントのメモリエリア)(0xC0000〜0xDFFFF)は
このTSSからしかアクセスできなくなる。
(ちょっち言い方が変かな? ldtrを4番と指定されているTSSからしかアクセスできなくなるが正しいかな






こういうことかあぁぁぁぁ!!!!!!!!!!!
 
30日を過ぎたBlogにはコメントできません。

Referer  (44)
12:35
27日目
 
27日目〜

・・・だめだ。わからんかった・・・orz

P569
うっわあぁぁぁ!
なんじゃこれは!?? これはさすがにオイラレベルじゃわからん
よなぁ〜。(こういうことってあるんですねぇ。一番やっかいな
バグのパターンのような気がします。)

P574
黒川合再登場!
(なんだか邪悪さが増してませんか??(笑 )

超余談ですが昔NHKでびっくりかという小学生向けの
教育番組をやっていました。(知ってる人いるかな?)
これ、けっこう斬新な手法で面白かったんですよ。理科の疑問を
普通に放送するんじゃなく、わざと一度、おねぇさんがミスを
おかすんですよ。するとそこにメチャモンというイジワルな
電子妖精?が現れて、おねぇさんのミスや誤認識にツッコミを
入れ、チャカして帰ってゆく。おねぇさんはそれがくやしくて
もう一度調査再開!というパターン。
これでおもしろかったのは、おねぇさんの間違いです。決して
おねぇさんがアホなので間違うのではないということ。間違った
認識をしてしまうことにも「なるほど」と思えるような配慮が
なされていました。この手法だと、最後には正しい答えが出て
きますが、「よくある誤解や間違いはなぜ起こるのか?」という
ことも同時に教えてくれるんですよねぇ。
そういう意味ではこの本の手法とも通じるところがあるなぁと、今ふと思ったと。
・・・いや、この時々登場する黒川合がどんな顔だろうと考えていたら、メチャモンの顔を思い出したと。ただそれだけであるんす・・・。


P576
・・・なっるほどなぁ。
「OSが使うメモリ」には手を出せないけど、「アプリが使うメモリ」には
「アプリが書き込める」から、当然よそのアプリのデータを壊せると・・・。
これはどうやってガードするんだろう?
たとえば、2005セグメント(アプリ1のデータ)は、1005セグメント(アプリ1のコード)から
しかアクセスできないとか、そういうスイッチがあるのかな??

P576
むむむ? LDTとな???

あ”っーーーーーー!!!
思い出したぞこれ!?
たしかこれ、1巡目でわからなかったところじゃなかったっけ!??
クソ! こんどこそ!!!
そんなわけで、ちょっと戻ってチャンと整理してみよう!
 
30日を過ぎたBlogにはコメントできません。

Referer  (6)
11:15
26日目
 
26日目〜

GUIのチューニングですね。
確かにforとかって簡単に書けるんでついなんにも考えずに
使っちゃうんですけど、入れ子にするとすぐに数万回になって
しまう。こういうチューニングは重要です。


メモメモ!
xxx & ~3  というのは、3のビット反転の意味。



うーん・・・4の倍数かぁ。
これはすごく良くわかるんだけど、生意気ながらなんとなく
好みじゃないなぁ。なんかもうすこしうまい方法ないかな・・・。

座標や幅が適当でも同じくらいの効果を上げる方法、ないかな〜?
↑自分で改造する時用のメモですよん。


P553
コンソールの閉じ方。
うん。特に難しいことはないんだけど、なんつーか、いつのまにか
凄く「理屈」が通るようになってますよね?
まずアレして、次にこれし、最後にそれをする。で、閉じるときは
これを逆にしていけばいいと。
あったりまえかもですが、このアタリマエができるようになるまで
ってのは大変でしたよねぇ。
プログラミングにかぎらず、
「あたりまえはすごいことなのだ」
ということを忘れずに日々をすごそうと思う今日この頃・・・(^^

P562
むむむむ?????
最初、このncstの使いどころがよくわからんかったのだが。
あれかな? Linuxとかで使う、 vi & とかと同じことかな?

・・・しかもなんだがバグが出ているぞ?(^^;

また明日〜らしいが、ちょっとコードを読んで考えてみよう。

そんなわけで26日目終了〜
 
30日を過ぎたBlogにはコメントできません。
(1) 

PopnupBlog V3 Denali created by Bluemoon inc.