[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]

[OSASK 1374] Re: for more compact.



  こんばんは、川合です。


MITSUNARI shigeo さんは 2001/01/18 22:58:13 の「[OSASK 1373] Re:
for more compact」で書きました:

>光成@しょうもないつっこみです。
>
>>     EAX = 32; // 5バイト
>
>xor EAX, EAX;
>AL = 32;
>なら4バイトです(笑)。

  ナイスな突っ込みです(笑)。おっしゃる通りです。

  一応フォローしておくと、

    EAX = 0; AL = 32;

で、

    XOR(EAX, EAX); AL = 32;

とコンパイルされます。1バイトすら惜しい時は、光成さんの方法を取
るべきです(笑)。

---

  いっそのこと、もっと小さくしてしまいましょう(笑)。

  ・・・すみません、こういうの好きなんです。僕の職業病だと思って
、軽く流して下さい(笑)。

  今回の改造の方針は、「lib_putnotename.stringのそれぞれの文字コ
ードは、常に0〜255の範囲で収まるから、上位バイトを書き換えない」
という方針です。

  ベースにするのは、1/18バージョンのsworldです。

  まず、関数clear_note_name()は、以下のようにできます。

// clear note name
void near clear_note_name()
{
    WORK *work == DS:0x0800; 
    char *putnotename_string == DS:EDX;

    //  (offset) putnotename_string = work->lib_putnotename.string;
    LEA((offset) putnotename_string, (int) [work->lib_putnotename.string]);

    AL = 32; /* ' ' */
    putnotename_string[ 0] = AL;
    putnotename_string[ 4] = AL;
    putnotename_string[ 8] = AL;
    putnotename_string[12] = AL;
    return;
}

  そんでもって、/* note name table */のところを全てDBに変えてか
ら、以下の変更を施します。

    // set note name
    EAX = p[0];
//  EAX = work->notename[(EAX - 60) * 4];
    EAX = work->notename[EAX * 4 - 240];
    unsigned char *dist == EDX;
    LEA(dist, (int) work->lib_putnotename.string);
    dist[ 0] = AL;
    dist[ 4] = AH;
    (unsigned int) EAX >>= 16;
    dist[ 8] = AL;
    dist[12] = AH;

  ・・・おっと、struct WORKのnotenameのサイズを96バイトにするの
も忘れずにやります。

  これで、どのくらい縮むかな?・・・1,156バイトになりました。

  さて・・・もっと小さくする余地はあるでしょうか、・・・あります
(笑)。

  work->notename[]は、現在96バイトですが、

・第1バイトはかならず'O'。
・第2バイトは数字('0'〜'9')。
・第3バイトは'A'〜'G'。
・第4バイトは' 'か'+'か'-'。

というごく限られた変域をとります。・・・そこで、こんな風にフォー
マットを変更してみます。

・第1バイトの情報は配列に入れない。
・第2バイトの下位4bitと第4バイトの下位4bitを組み合わせて1バイ
  ト。
・第3バイトのデーターは面倒なのでそのまま1バイト。

これなら、work->notename[]は半分の48バイトになります。この「圧縮
データー」を展開するのに必要なプログラムの量が48バイト未満に収ま
れば、トータルでは減量になるはずです。

  以下に、その方針で改良した部分を載せます。

    /* note name table */
    asmout("DB 40H, 'C'"); // x0 : ' '
    asmout("DB 4BH, 'C'"); // x3 : '#'
    asmout("DB 40H, 'D'"); // xB : '+'
    asmout("DB 4BH, 'D'"); // xD : '-'
    asmout("DB 40H, 'E'");
    asmout("DB 40H, 'F'");
    asmout("DB 4BH, 'F'");
    asmout("DB 40H, 'G'");
    asmout("DB 4DH, 'A'");
    asmout("DB 40H, 'A'");
    asmout("DB 4DH, 'B'");
    asmout("DB 40H, 'B'");
    asmout("DB 50H, 'C'");
    asmout("DB 5BH, 'C'");
    asmout("DB 50H, 'D'");
    asmout("DB 5BH, 'D'");
    asmout("DB 50H, 'E'");
    asmout("DB 50H, 'F'");
    asmout("DB 5BH, 'F'");
    asmout("DB 50H, 'G'");
    asmout("DB 5DH, 'A'");
    asmout("DB 50H, 'A'");
    asmout("DB 5DH, 'B'");
    asmout("DB 50H, 'B'");

    // set note name
    EAX = p[0];
//  AX = work->notename[(EAX - 60) * 2];
    AX = work->notename[EAX * 2 - 120];
    unsigned char *dist == EDX;
    LEA(dist, (int) work->lib_putnotename.string);
    dist[ 0] = 0x4f /* 'O' */;
    dist[ 8] = AH;
    AH = AL;
    AH >>= 4;
    AX &= 0x0f0f;
    AX += 0x3020;
    dist[ 4] = AH;
    dist[12] = AL;

  以上の変更で、1,120バイトになります。

  これ以上劇的にはやせられないという訳ではありませんが、これ以上
は説明するのが難しくなりますし、僕の「いたずら心」も収まったので
この辺で今日はおしまいです(笑)。

---

  誤解されると困るので書いておきますが、僕は小さなプログラムが大
好きです。しかし、大きなプログラムだって好きです。ですから、徹底
的にコンパクトにしてからでないとOSASK-MLに投稿できないんじゃない
か、なんて思わないで下さい。一番大切なことは、動くことです。コン
パクトだというのは、ちょっとしたパズルみたいなもので、遊びなんで
す。ですから、なにかプログラムができたら、どんなに大きくても萎縮
せずにご紹介ください。いつでもお待ちしています。


  それでは。

--
    川合 秀実(KAWAI Hidemi)
川合堂社長 / OSASK計画総指揮 / カーネル開発班
E-mail:kawai !Atmark! imasy.or.jp
Homepage http://www.imasy.or.jp/~kawai/