* ぐいぐい01に関するメモ-14 -(by [[K]], 2008.12.20) -メモのうち重要な部分をそのうちまとめてまともなページを作る *** (29) 2008.12.20近況 -ここ1週間ほどの開発がここ数年で最高に充実していてかつ面白かったので記念でメモ。 -少し前からOSASK-IRCにneriさんが常駐してくれていて、それでCOM64-GREの改良の話をしました。いろいろと改良してアーカイブ風になったあと、もっとコンパクトの役に立つ仕様にしたいということで、二人でどうしたらいいかを話し合いました。長すぎるシグネチャを短くするべきか、みたいなところが出発点だったと思います。こうしてCOM64plusの開発が始まりました。シグネチャを4バイトにするべきか2バイトにするべきか、そこも悩ましいところでした。 -それでneriさんは「ぐいぐい01」に採用されているテクニックを貪欲に吸収し、起動時に小アプリ一般にとって有利になるようなレジスタ初期値を採用して、なんとhello+.comのサイズが「ぐいぐい01」のhello(このときは27バイト)を下回る25バイトで書けるまでになりました。僕は「負けたあ」とその日はあきらめて寝ました。たしかcharsも負けました。 -しかし寝ているうちにアイデアを大量に思いついたので、それを翌日全部neriさんに聞いてもらって、どう思うか感想をききながら検討しました。それやるくらいならむしろこうしたほうがいいとか、それはいかにもhello専用の仕様過ぎて好ましくないとか、そんな感じの話をしました。そしてneriさんもいろいろとアイデアを出して結局hellok2.g01は22バイトまで行きました。neriさんのhello+.comは21バイトになりました。これは相当に「おかしい」サイズで、DOSの22バイトよりも小さいのです(註:この文脈での「おかしい」は最高の褒め言葉)。これに勝てるのはバッチファイルで"@echo hello, world"の18バイトくらいなものでしょう。文句なくx86世界最小だと思います。 -またchars+.comはついに15バイトにまでなり、でも「ぐいぐい01」もがんばって16バイトまではきました。もとが33バイトだったのに16バイトだなんてもはや半減です。DOS版が17バイトなので、やはりこれもneriさんは世界記録保持者だと思います。 -その後さらにもう一段僕が改良し(これはneriさんには応用しにくい改良)、helloは何とかneriさんに追いつきました。これで世界記録タイです。charsは追いつけませんでした。またechoも作りました。neriさんは作ってないので比べられません。 -(12.21追記)neriさんは起動時のECX初期値をコンパクトに設定できる形式を導入して1バイトの削減に成功。これでほぼ全てのアプリが1バイト以上小さくなることに。僕も負けじと考えて出現頻度の非常に高いパラメータを省略できるように改良。これで多くのアプリが1バイト以上小さくなることに。 -(12.22追記)昨日neriさんがオプションでCALL(EBP);をコードに追加する機能を付けるべきなんじゃないかと提案しました。この機能を付けるべきかいろいろ試行錯誤した結果、確かに付けたほうがいいと僕は判断しました(.g01の場合は先頭に付ける、COM64plusの場合は末尾に付ける)。またコマンドライン取得APIの仕様が勘違いで間違っていたことに気付いて修正したところ、このAPIが更に使いやすくなりました。これでまたサイズがかなり減っています。なおneriさん自身はまだCALL(EBP);の自動付加オプションをやるという決断にはいたっていないようです(でもきっとあとでやるとは思う)。helloが18バイトで書けるということは、ついにバッチファイルともタイだということです。ちなみにechoの13バイトはバッチファイルで"@echo %1 %2 %3"って書くだけで14バイトなので、すでにバッチファイルにも十分に勝っていると思います。 -(12.24追記)CALL(EBP);をやめてCALL([ESI]);にすることにしました。これだとEBPがあくので好きなことができます。アセンブラ版のバイト数は変わりません。でもC言語版のバイト数は1バイトくらい減らせそうです。・・・さらにCOM64plusのマネをしてレジスタの初期値ロード機能をオプションでつけました。これでcharsが16から14になりました。COM64plusに追いついた! -以下にここまでの成果(多分これが限界でもあると思う)を書いておきます。[2008.12.24更新] | |hello |hello-c |chars |echo |echo-c | |abcdw006用 |RIGHT:27 |RIGHT:86 |RIGHT:33 |RIGHT:? |RIGHT:156 | |abcdw007用 |RIGHT:''18''|RIGHT:''69''|RIGHT:''14''|RIGHT:''13''|RIGHT:''71''| |COM64plus用|RIGHT:20 |検討中? |RIGHT:''14''|RIGHT:? |RIGHT:? | |DOS用 |RIGHT:22 |RIGHT:? |RIGHT:17 |RIGHT:19 |RIGHT:? | --(註)echoはargv[0]が見えても見えなくてもよい。 --echoはもちろんジャンクAPIで実現しているが、ジャンクAPIはジャンクであるというマークがついている分だけ実行ファイルが長くなる傾向がある。もし他の部分は一切変えずに本仕様に昇格させれば、それだけでechoもecho-cも2バイトは縮むだろう。 -abcdw006→abcdw007の仕様変更はかなり大きなもので、基本的にバイナリ互換はありません。ソース互換すらほどほどしかありません。大規模改造なので僕も非常に苦労しています(アプリの移植はそれほどでもないけど、efg01の改造が大変)。 -これはまさに「乾いた雑巾を絞る」レベルの改良で、その中にあってcharsが半減したり、echo-cが半減したりと、ちょっとありえない劇的な進歩になっています。それもこれもみんなneriさんの協力のおかげです。・・・neriさんなしで一人でやっていたらこの設計に到達するまでに1年間はかかったと思います(その後の改良のペースもすごいのでトータルで2年分くらいは進んでいる気がする)。あとやっぱりabcdw006までで小さいアプリをたくさん作ってきて、ボトルネックというか、「こんな仕様だったらいいのに」を実感していたのもあると思います。 -それにhello-cも static char s[18] = "\x35\x01\x24\x8d" "hello, world\n" "\x23"; なんていういかにも「うさんくさい」「こんなの普通書くわけない」といった方法での86バイトだったのが、 g01_putstr0("hello, world"); という普通の書き方で69バイトになるようになっています(12.24:バイト数更新)。汚く書いたらもう少し小さくなるかもしれませんがまああまり変わらないでしょう。 -という劇的な大進歩なので、互換性がちょっと不足気味だったりリリースにてこずったりしても、どうか大目にみてください。 -「こんな互換性に問題の出るバージョンアップが繰り返されたら安心してアプリを作れないじゃないか!」というのはもっともです。「いったいいつになったら落ち着くんだ?」といいたくなるでしょう。しかしこれは永遠に続くわけではないのです。というのはたとえばhelloは文字列だけで13バイトあって、しかも.g01のシグネチャだけで2バイトあるのですから、これだけでも最低15バイトは必要です。これより小さくなることはありえません(一般的なAPIとして不適切な設計にしない限り)。もちろんテキストファイルじゃないので他にも書かなければいけない何らかの情報やプログラムがあるわけですから、本当の限界はもっと大きい値でしょう。どのアプリもAPIを改良すればどこまでも小さくなるわけではないのです。限界があるのです。その限界に達してしまえば、それ以上どんなにいじってもより小さくなることはないので、仕様のバージョンアップが起きることはないはずです。 -現状を見てください。なんかもうひどく限界に近い気がしませんか?まあ僕だってabcdw006の段階で既に限界だと思っていました。だからそういう「感じ」が必ずしもあてになるわけではないのですが、しかし大いに参考になる目安だとは思います。・・・早く限界に近づかせる方法は、サイズを追求する人がさらに増えて、この分野の研究が進むことしかないでしょう。 -以下にabcdw006との比較を書いておきます(全部C言語のみ)。[2008.12.24更新] | |pi |calc |cpy |makefont |bim2hrb |sjisconv |gas2nask |nask |obj2bim |bim2g01 |bin2obj | |abcdw006用|RIGHT:241|RIGHT:1583|RIGHT:612|RIGHT:691|RIGHT:987|RIGHT:912|RIGHT:(5114) |RIGHT:23314|RIGHT:7211|RIGHT:1956|RIGHT:983| |abcdw007用|RIGHT:205|RIGHT:1521|RIGHT:386|RIGHT:439|RIGHT:766|RIGHT:644|RIGHT:5001|RIGHT:23040|RIGHT:6903|RIGHT:1792|RIGHT:732| --(註)piは.hrb版の229バイトに対して逆転に成功。参考までに書いておくとcalc.hrbは1668バイト。 --calcはこのサイズより小さくCで書く方法がないということではない。オリジナルのhrb版のソースにできるだけ近いソースを使わなければいけないという制約を自ら科しているためにこのサイズに留まっている(コマンドラインバッファをより長くすることだけは許される)。 * こめんと欄 - 現在abcdw007の今週中のリリースを目指してがんばり中。 -- [[K]] &new{2008-12-22 (月) 20:33:28}; #comment