[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/