第九回 翻訳は金になる(コンパイラ作成のための準備体操)

コンパイラとは何だろうか?経験を積んだプログラマでさえ、案外盲点になっている。

法律用語では、敵国の言語(何が敵国やねん...)を使うのはご法度だからして、コンパイルと言わずに「翻訳」と言う。よって、コンパイラとは、「翻訳家」である。逆コンパイラなら、「逆翻訳家」である。よくゲームのCDに書いてあるのは、

この小型読込専用記憶装置における電子遊戯の処理手順の一部ないしは全部を複写あるいは逆集合家および逆翻訳家にて解析、逆開発することは法律で禁じられており...

うおおおおお!!なんのこっちゃ!!そんなこと書いてないって!!
ごめんごめん。軽いジョーク。本気にした人、ホントごめん。

コンパイラとは、主に高級言語のソースコード、要はプレーンテキストをターゲットマシンのマシンコードに自動的に変換してくれる、夢のようなプログラムである。(どうでもいいが、プレーンヨーグルトと言えば砂糖なしのヨーグルトだからして、プレーンテキストというと砂糖なしのテキストだと思ってしまうのは、私だけなんだろうか?おまけに、ソースというと、オリバーソースを思い出しては、あのオリバーソースのCMのおっさんを思い出して、笑い出しそうになる。あぶないあぶない←お前の頭がアブナイだけやろ?)

実際のところ、コンパイル技術が確立され、公のものにされたのは、Naurが1960年にAlgol 60に関する論文を完成させたあたりまで遡る。それまでは、本当に夢のような話だったのである。いまとなっては、コンパイラがあまりにも当たり前になりすぎて、それがいかに魔法じみた品物であるか誰も気づいていないが。

ある言語を別の言語に変換する。日本語から英語に変換する。これは翻訳作業である。これを完全に自動的に出来るなら、翻訳家はすべて廃業である。しかし、専門分野などの翻訳を除けば、完全な自動翻訳なんて出来ていないのが実情である。それから考えれば、C言語という、人工言語で記述されたプログラムが、完全に自動的にターゲットマシンのコードに変換されるというミラクルについてもっと注意深く考えなければならないのではなかろうか...?


第A回 ゲーム作成講座はいつんなったら始まるねん!(一読者の不満)

「ゲーム作成講座はいつんなったら始まるねん!」そんな声が聞こえてきた。

お前はアホか!ゲーム作成講座は、第一回から始まっとんねん!ゲーム作成のために必要なのは、プログラムや。プログラムを作るために必要なんは、コンパイラや。コンパイラは、言うてみれば、調理器具や。調理器具なしに料理が作れるんけ?お前、作ってみろよ!やねうらおは声を小にして言いたい。(小..?なんで小やねん!?大にして言えよ!)

さて。いま現在、あるCPUのコードを別のCPUのコードに自動的に変換するもの(トランスレータ)は、あまり有名ではない。コード変換は行なわずに、インタプリタ的に実行するエミュレータ系は数多くあるが、もとのCPUの1/10程度の速度になってしまうので、昔のアーケードゲームの移植とかならともかく、一般的なプログラムに対して有効な手段ではない。

トランスレータは、エミュレータよりよっぽどCOOL!なのだが、その知名度が低い。そもそも効率の良いコードに変換するのは容易ではない。なぜなら、あるCPUコードが別のCPUコードと一対一に対応するわけではないからである。68Kのようにレジスタの多いものがあれば、6809のように少ないものもある。RISCのように直交性に優れたものから、Z80や8086のようなしおしおなものまで、様々である。すべてのアーキテクチャでスタックフレームがあるとは限らないし、すべての環境でレジスタなるものがあるとも限らないのである。

変換が一対一対応でないということは、意味的に等価な変換を、一定の文脈を利用した最適化を施しつつ行なわなければならないということである。要するに、そのCPUに合った安くてうまいコードに変換せえ!っちゅーことなのだが、最適化技術の進歩には目覚しいものがあり、めちゃんこ奥が深いのである。GNU Cの最適化ロジックを聞きかじったぐらいで最適化のすべてを理解したかのように雄弁に語る馬鹿もいるが、この分野そんな薄っぺたいものではないのである。

一応、この分野に疎い人のために説明しておくが、最適化というのは、婉曲語である。すなわち、最適化とは、最適にすることではない。えっ?わけわかんない?つまり、最適なんかにはならないのである。最適に近づけるべく、少しずつコードをシェイプアップすることを最適化というのである。

そんなこんなで、最適化について考えることは時間の無駄なので、蟻地獄にハマって一生抜けられなくなっても良いという人以外は避けるべきである。(ちなみに、やねうらおは、幼少のころから蟻地獄にハマってます。もう一生抜けられません。誰か助けて〜!)

まあ、やねうらお的には、トランスレータなんて、いらねぇ、こちとら江戸っ子でい!んなもん、アセンブラのソースからC言語のソースに変換するコンバータを書いちまいな!あとは、ターゲットCPU用のCコンパイラでコンパイルすればいいじゃねぇか!最適化なんてうざってぇことCコンパイラに任せちゃいな!イッツ、トレンディ!イッツ、クール!よっ!やねうらお!オットコマエだねぇ〜!である。(やねうらおは壊れてません。壊れてませんからね...)

市販のゲームの移植も、その手の手法によるものが多い。あとは、機種依存部分だけ専用のクラスを用意する。うまくやれば一週間程度で移植が完了するので、結構、お手軽である。すなわち、ゲームの移植作業のメインはトランスレーション(=翻訳)であって、この技術そのものが金に直結するわけである。少しはコンパイラに興味を持ってくれたかな?


第B回 やねうらおからの挑戦状!(80862C)

スーパープログラマーを目指す人たちに挑戦状!

8086のコードをC言語のコードに変換するプログラムを10分以内に作成しなさい。
(ただし、データ部分を入力する時間は考慮に入れません。細かい仕様も問いません)
一応、開発言語はC or C++。MFCの利用は可。

解答は、やねうらおまでメールでどうぞ。

優秀作には、呪いのワラ人形を一年分プレゼント。(誰もいらんわ、そんなん!)
うそうそ。びっくる特製Tシャツをプレゼント。


第C回 インタ〜ミッション!(Replacer)

今日(10/9)、会社から帰りの電車でLispの本を読んでいるおっちゃん(50ぐらい?)を見かけた。ご丁寧にまぁ、1ページ目からじっくりと読んでらっしゃる。仕事で必要なのか何なのかは知らないが、50にもなって何が悲しいか、いまさら1から(あるいは0から?)Lispを勉強しなくてはならないという状況に、何か痛ましいものを感じた。

これから書く内容は、残念なことに、そのおっちゃんでは死ぬまでには辿りつけないかも知れない程度に高度な内容である。思い起こせば、やねうらおがLispにハマっていたのは、ちょうど、エスパー魔美とかいうアニメが流行っていたころである。当時、やねうらおは、「リスパー魔美」とかわけのわからんペンネームで、Lispについて京大の院生と毎日のようにメールの交換に明け暮れていた。まあ、そういう甘酸っぱい年頃もあったということである。(かなりの阿呆やな。賢いのか阿呆なんかようわからんやっちゃ!)

まず、Lispの特徴(重要となる概念)は、recursion(再帰)とソーステキスト自身がfirst class objectであるということである。その他、λ計算や、その特殊なデータ構造なども問題になることが多いので順を追って説明したいところだが、やねうらおには、役に立ちそうなことは説明しない(自分で調べろ!)というわけのわからんポリシーがあるため、とりあえず、C++のOOP(オブジェクト指向)の欠点について考察するのに、どうしても必要な「ソーステキスト自身がfirst class objectである」についてのみ述べよう。

この連載のなかで、幾度にも及び、ソーステキストとターゲットマシンのコードとの意味的な差異や、その差異がゆえに生じる変換にまつわる話を延々としてきたが、もし言語がインタプリタでソーステキストが仮想的にターゲットコードであるとみなせる環境であるなら話は、一変する。ここのところ、よく考えて欲しい。さらに、ソースコードがfirst class object(=第一種オブジェクトと訳するより、一番扱いやすいクラスオブジェクトと訳したほうがいいと思う。要は、C言語で言えば、intとかcharとか標準でインプリメントされているオブジェクトタイプみたいなもの)で記述されているとしよう。

そうすると、ある関数そのものを変数に代入することが出来たりする。これを、function enclosure(関数閉包)と呼ぶ。関数も文字列だからして、文字列変数に代入できるとか、そういう感覚で捕らえると良い。仮に変数Tに代入したら、そのTを持ち歩くことが出来るのである。持ち歩くというのは、別の関数に渡したり、データとしてストアしたり出来るということである。仮に、他の関数にTを引数として渡すと、そのTを引数として渡された関数内で、関数Tを実行できるのである。これだけなら、Cでも関数ポインタを渡せば、それぐらい出来るじゃんって思うかも知れないが、まったく意味合いが違うのである。

まず、Tという<データ>変数が<実行>できるということ。「ソーステキスト自身がfirst class objectである」からこそ、こういう芸当が可能なのであるが、ある意味、データ=プログラムとも言える。これについては、後述する(しなければならない)。そして、Tがfirst class objectなので、Tと同じく関数閉包されたSを結合して新たな関数閉包されたUを作るようなことが出来る。また、Tの中身をスキャンして、特定の文字列を別の文字列に置き換えたり出来る。すなわち、実行時に、関数の仕様変更が利くのである。もうすでに脳みそバ〜ン!ってなってる人もいるかと思うので、そのへんの詳しい内容は控えよう。

さて。前回の挑戦状は、易しすぎたかなと思っていたのだが、10分以内って部分がどうも理解できない人が多いようである。そこで簡単にヒントを差し上げたい。10分でプログラムするなら、せいぜい50行入力できれば良いところ...それだけの行数で何が書けるのか?時間制限がなければ、例外処理の塊(if文の塊とも言う)のような醜悪なプログラムも可能なのだが、そこはスーパープログラマーを目指す選ばれた(誰にやねん)人たちを対象としているので、いっちょ奮発して例外処理のないエレガントなプログラムを書いて欲しいと思ったわけである。そのための<貴重な>10分なのである。もちろんプログラムをコンバータとして完全なものにする必要はない。こんな仕様ですよ、という説明文をつけてもらえればあとはそれを見て判断する。この手のプログラムは、たぶん、リプレーサ(置き換えプログラム)に分類される。今回は実行速度はどうでも良い。基本的に、手作業で置換するより速ければ、それで実用になるのだから...。

ただ問題は、プログラム本体に例外処理を書かずにデータとしてどれだけ追い出すことが出来るかという部分である。ここまで来れば、さきほどのデータ=プログラムということがどれだけ大きな意味を持ち得るのか理解できるだろう。いわゆるOOP(オブジェクト指向プログラミング)で言うところのオブジェクトとは、データおよびメソッド(PASCALで言えばprocedureやfunctionね!)を内包するが、そのクラスオブジェクトの定義はプログラム内でコンパイル前に記述しなければならない。つまり実行時に拡張していくような機構はC++のOOPではサポートされていないのである。よって、データの拡充された概念であるはずのオブジェクトとは、結局はデータのはずなのにプログラマにstaticかつearlyに(コンパイル前に)定義することを余儀なくしているのである。んなアホなー!!んな閉じていて閉鎖的なオブジェクトなんか、他の人が使えんだがやー!!だからして、この手のOOPはある規模で確実な破綻を迎え、そのアンチテーゼとしてActiveXという技術が提起されたのである。いや、そんな話は、いまはどうでも良いのだが、このように、なるべくプログラム本体では記述せずにデータとして逃がし、データの側で将来的な拡張に対応できるようなものを設計しようと考えたとき、「ソーステキスト自身がfirst class objectである」のでなければ、どうしても逃がしきれない部分というのが出てきてしまう。それは、データがそもそもデータであって、オブジェクトではないからである。もっと平たく言えば、<データ>を<実行>できないことに問題があるのである。

なんか、息抜きのつもりで書き始めたら、とんでもないことになって、脱落組がわんさか出そうな内容になってしまったが、今回はこれでおしまい。So much for Today.


第D回 ニューロファジーは炊飯器用テクノロジーか!(話題スリカエ編)

なんか、前回の話が、ちとややこしかったためか、脱落者がわんさか出た模様。ここの内容がまったくわからなくとも、あまり気にせず、ほんの息抜きのつもりで読んでいただきたい。こっちも、気楽に書いているので。

なんでコンパイラの話からいきなりニューロの話に飛ぶかと言うと、これがまた、第27回に向けての伏線なわけだ。(うそ) 技術的内容ばかりで疲れてきたので、ちょっと息抜きに軽くニューラルネットワークの話をする。

近年、ニューラルネットを研究している大学の研究室が多いが、どうも、それが間違った方向であるような気がしている。ちょっとそのことを説明するために、簡単にニューラルネットの利用法について説明しよう。多変数を入出力に持つ関数があって、入力と出力はだいたいわかってんねんけど、その肝心の関数はどんなやねん?ってのがわからないときに、ニューラルネットを使う。簡単に言えば、それだけである。

たとえば文字認識。それぞれのピクセルを入力に持ち、出力として漢字コードを吐き出す関数が欲しければ、ニューラルネットを組んで学習させれば良い。(ただし、その手の学習は一筋縄ではいかないのだが...)

ここで学習の基本となるのは、BP法(逆伝播法)。このへんは、その手の参考書に譲るとして、やね的な結論だけ言うと、BP法を支えているのは、シグモイド関数であって、こいつの導関数が自己相似形になることからBP法が完成し、多段ニューラルネットワークにおける学習メソッドが完成したわけやね。GA(遺伝的アルゴリズム)も本質的には、似たようなもんであるからして、あえて言及しない。

ニューラルネットは非常に便利なものである。かくいうやねうらおも、その手の関数のチューニングが面倒になったときには、思わずニューラルネットを使ってしまう。(関数の形が想像つけば、係数だけ最小二乗法で決定するほうがあとあと実用的なのに!)

まあ、入力と出力はだいたいわかってんねんけど、中身がまったく想像つかんなんてものは世のなかにはいっぱいあるわけで、人間自身もそういったブラックボックス的なものに該当するわけだが、それゆえ、ニューラルネットの適応範囲は実に広い。それだけに、「これこれ、こういう分野で、ニューラルネットが使えました。大きな成果をあげました」的論文や研究が盛んになるわけである。何せお手軽だし、理論について考えなくて済むから、ダメもとで試してみれば良いだけの話である。数学的な基礎もなーんもいりやしねぇ!下手すれば、人様の作ったニューラルネットライブラリをそのまま援用して、入出力データだけ集めてうまくいくかどうか試すだけの奴なんかもいる。ハナクソがうまく丸くなる条件についてニューラルネットを使って調べましたとか。(うそ) いずれにせよ、小学生でも出来るような内容をなんで院生や博士課程の奴がするんかねー?それで恥ずかしくないの?そんなんで単位が出る大学も大学だと思うし、なんか日本のコンピュータ教育そのものが腐ってるとゆーか、非常に低いレベルにあるのでないかと思う。(工学部ってのは、理論を研究する機関ではない!とかいう話もなくはないが...”応用”が基礎理論より<優れた>ものであるとか勘違いしている馬鹿教授もいる。それは単にフェイズの違いに過ぎないのに....)

しかし、BP法の限界は、簡単な実験をやってみれば、すぐに露呈するわけで多段では学習が非常遅いのである。それはネットワークそのものがstaticであるために来る限界でもある。このへん、やねうらおは早い時期に気付いて、dynamicに変化するニューラルネットワークについて日夜研究していた。不幸にも、やねうらおは、当時、大学受験を控えていて、毎日現実逃避のためにゲーセンで深夜遅くまで遊び呆けていたがために、まったくもって研究は進まなかったのだが...。その数年後、東大の甘利教授(日本でニューラルネットをまともに研究してるんて、この人だけとちゃうかな...)が、その手の研究をされていることを知った。う〜ん。やねうらおの方が、2,3年は前を行ってたはずなのに〜。とか言っても、研究するだけの力(金と時間と頭。特に3番目の奴が重要!やねうらおには一番欠けているはずだ)がないやねうらおが言ったところで、負け惜しみにしか聞こえないだろう。そうなんだよ〜。負け惜しみなんだよ〜。だから言わせてくれよ〜。<馬鹿

なんか、まったくもって息抜きになってない気もするが、気分転換にはなったでしょ。(とか言う奴)


第E回 OOPに不真面目に取り組む(退廃的プログラミング論)

前回は、Lispの話をしたが、やねうらおがLisp君とお友達になったのは、小学生の5年生ぐらいのときである。そのころは、オールアセンブラでのプログラミングに飽き飽きし、何か刺激を求めていたころでもある。だからして、Lisp君とはすぐさま仲良しさんになった。Lispの基礎は再帰にあると早々と悟ったものの、再帰的プログラミングの難しさに、毎日のように夜中になると、うお〜うお〜とうなり続けていた。これが本当のサイキックうお〜である。(何、アホなことゆうてんねん!>俺)

Lispと一口に言っても、その実、さまざまである。Lispの方言は何百とあるとさえ言われている。実際のところLisp程度の言語を実装できない人間は、Lispを使う資格は無いという話もあるぐらいで、たぶん、いまではCOMMON LISPかschemeあたりが標準的だとは思うが、ある程度のレベルのLisper(リスパー/Lispを使う人のこと)なら、たいてい自分専用のLispを自作していたりする。極論すれば、記号処理専用アセンブラみたいなものだから、言語情報処理とかに不向きな人が使いこなせるシロモノではないのかも知れない。

Lispという言語を泥団子であると言った外人がいたが、それは言い得て妙である。第C回でも述べたが、「ソーステキスト自身がfirst class objectである」し、Lisp自体、記号処理言語として記号処理用の命令が備わっているので、新しい機能拡張が非常に容易なのである。アセンブラプログラマで、実行速度の遅いプログラムと洗練されていないソースをこの上なく嫌うやねうらおが、Lispに強い反発を感じながらもついぞ最後まで嫌いになり切れなかったのはその部分なのである。Lispでなら、C言語の3倍は早くプログラムのプロトタイプが完成するだろう。ただし、実行速度は30倍ぐらい遅いかも知れないが...。あと、ソースが括弧ばかりで汚いのである。括弧ばかりでカッコイイ〜などと言う人もいたが、慣れていてもちょっと他人のソースを見ようなんて気にはなれないのである。その2点が、泥団子(いくらでもベタベタと追加できるが、非常に汚い言語!)と言われる所以である。

ともかく。いま、お題であるOOP(オブジェクト指向プログラミング)について考えてみよう。

C++的なOOPの基本は、カプセル化とinheritance、polymorphismだ。詳しいことは、その手の入門書に譲るとして、カプセル化ではクラスのプライベートメンバを外部から隠蔽することがその目的としてあり、ソフトウェア工学の世界で、モジュラリティ(モジュール性)を高めるための手法である。では、どうやってオブジェクトのプライベートメンバにアクセスするかというと、オブジェクトに用意されたインターフェースを介して行なう。C++的には、それがメンバ関数なのであるが、これはあまりわかりやすいOOPの姿ではない気がする。たぶん、Small Talk風にオブジェクトに対して、メッセージを送り、そのメッセージをオブジェクト側で解析して、正しいアクションを行なうのが、真の姿であるように思う。それがメンバ関数の呼び出しで置き換えてあると、第C回で述べたように「staticかつearlyに(コンパイル前に)定義」しなければならず、それがクラスの拡張を自己閉塞的なものにしているというのが、やねうらおの考えであった。ただし、ごっちゃにして欲しくないのは、他人が自由にオブジェクト内部をいじれて良いということではない。それはOOPの基本理念に反するし、機能レベルで完結していないオブジェクトは使いものにならない。あのとき僕が言いたかったのは、「モジュールは必ずしも閉じていなければならないものではない」ということである。逆もまたギャグなり。必ずしも真ではない。(なんのこっちゃ...) その閉塞性を補わんとして苦しまぎれに作られたのが、仮想関数なんてものなのだ。

「そんなにオブジェクトに拡張性が必要なら、Java風interfaceにしてしまえば?」という意見もあるが、ここには、C++の仮想関数と同じような問題が潜む。それは、インターフェースを「staticかつearlyに(コンパイル前に)定義」しなければならないことである。しかも、ドラえもんのポケットのような変数タイプ(VBのvariantか、あるいはLispのリスト構造のようなもの)が一般に許されるわけではないので、あらかじめ、関数名、関数の数、それらの引数の数、引数のタイプを決定しておかなければならない。これでは柔軟な設計が出来ない。特に、ここらへんが重要なことなのだが、そのクラスで実現しようとしている機能が明確でないようなオブジェクトデザインを行なう場合、引数タイプを設計段階で決定できない。それが、LispでならCの3倍はプロトタイプの完成が早いと言われる所以でもある。

実装上の問題、規格上の問題、そして、それに対応するツールの完備されているかなど、さまざまなファクターが入り乱れて、どうも話の見通しが悪いので、この話は、結論も曖昧にしたまま、このへんで打ちきることにする。


第F回 ATLとMicrosoftの戦略について(もーそんなん金とんなや的現実)

やねうらお宅は、パソコン関連の書籍もかなりの数にのぼる。ついでに言えば、将棋の本も優にプロ棋士を超えるほどそろっているだろう。何せ、考えるのがめんどくさくなってくると、資料がない〜だの言うのを理由に本をとりあえずジュンク堂に行く。将棋で負けると、研究が足りん〜とか言って紀伊国屋まで走る。「この一冊で3時間分の作業が減るなら安い買い物だ。俺は金で時間を買えるのだ。なんたる至福。なんたる満足感。メンバーだけに許された特権。違いのわかる男のジュンク堂」などとまたもわけのわからんことをつぶやきながら、とりあえずは本を買う。だいたい月額、5万〜15万になるだろう。その8割は買ったまま、一ページも読んではいない。やねうらおとは、そういう奴なのだからして。

さて。「ATLプログラミング」(TomArmstrong著/富田孝訳)なのだが、ATLの基礎的な話は紹介程度で、あとはCOMの実装がメインなのである。だ、騙された!!あのな〜。そんな閉ざされた技術のためにこんな高い本、こーてるんとちゃうど〜!!Winプログラムのことなんか俺は知りたないねんど〜。おんどれらいてもうたろか〜コラァ〜!!と電車のなかで叫んだとか、叫ばないとか。(買う前に気付けよ!)

でもATL自体はおもしろい。たとえば、C++でどのクラスに対しても動作するstack構造を実装することは、非常に困難であったが、ATLでならこれが可能である。何回も述べてきた、「staticかつearlyに(コンパイル前に)定義」しなければならない問題に対して、プリプロセッサ的なパスを導入することでいくらか緩和する。

そもそもプリプロセッサというのは、ソース言語自体を対象とするのだから、その記述はメタ記述的である。メタ記述というのが想像を絶するほどのポテンシャルを持っているのだが、それについて語る気はない。(語り切る自信もない) ただATLを見ればその威力のほどは理解できるのではないかと思う。それでもATLだけで万事オッケーというわけではなく、やっぱりある程度、Windowsにベッタリな大規模ソフト開発にはMFCのほうが楽チンだったりはするんだけど、いまからMFCをやるぐらいなら、頭のおかしくならんうちにATLにしなさいと胸を張ってお勧めできる。(ただし、Windowsでのプログラミング開発はまったくお勧めできないが...)

あと、COMの実装についても述べておかなければならない。OLEもCOMもActiveXも対象とする集合が少し違うだけでほとんど重なり合う。COMが提供するインターフェースは、仕様がきっちり規定されていて、VBからでもVCやVJで開発したプログラムの関数を呼び出すことが出来るというものである。やねうらおのBMRも、インターフェースをCOMで実装すれば、Windowsのどの言語からでも呼び出し、あるいは拡張が可能なものに仕上がるだろう。こうすれば、馬鹿みたいにコンパイラの実装(もちろん386用ネイティブコンパイラで、最適化も実装する)からはじめなくても良かったのである。このことに早々と気付いていたのだが、ここに潜む問題もある。

1.Windows上でしかCOMが実装できない(?)
2.BMRをカスタマイズするのにWindows用開発ツールが必要となる

のである。1.は、コモンプラットホーム構想(第4回)に反するし、2.はカスタマイズするデザイナーの負担となる。そもそも、カスタマイズするためだけにバカ高いVisualStudio等を購入して、それを覚えようだなんて、狂気の沙汰としか思えない。

ちゅ〜か、これがCOMオブジェクトに対する僕の現実的な批判だ。いくら他のMicrosoft系ツールから呼び出せると言っても、それはWindowsの話に限られるし、おまけにバカ高いWindows用の開発ツールが必要とあっては、Javaのinterfaceにも劣るのである。んだんだ。んなもんいらねえべ!天下のMicrosoftだと思って、わしら百姓のことを馬鹿にしくさって!(誰が百姓やねん!)


第10回 DPMIて、食いもんすか(バビロンの野望崩壊篇)

旧友の庄井さんが遊びに来て、「もうぼくちん、外国に行くんでXlibのプログラミングマニュアルをあげまちゅ」とか何とか言って、一冊1万円近くする本を4冊もくださった。これは、やねうらおにWinを捨てろという神の啓示かも知れないと真剣思ったねぇ〜。それと、もうひとつ。BMR用のコンパイラを開発していて、とんでもない誤謬を自分が犯していることに気付いた。

それも、ミステイクというよりは、386アセンブラをいかに自分が理解していないかをまざまざと見せ付けられた思いがした。386って、確かその昔、本で読んだ限りでは16ビットレジスタAXがEAXとか32ビット化してて、その他は別に何も変わっていなかったような..って、いまにして思えばそれは紹介記事的なものだったのだが、その印象が強烈すぎて、複雑なページングやら何やらの機構がそなわっていることをいまのいままで忘れていたのだ。

つまり、386ネイティブコンパイラを作成したとしても、そのネイティブコードをdynamicに読みこんで、そいつを実行するには、DPMIを熟知していないといけないのであった。んなもんのために、また多大な時間を裂く気にもなれず、そこでDLLを吐くネイティブコンパイラを作る手もあるが、DLLもその仕様って、謎だし(どこかに載ってた覚えはある)、そんなんもうええわ〜!Winベッタリなコードなんか、うざいんじゃボケ〜!!とか適当にその場はごまかし、RISCライクなスタック構造を備えた命令セットを持つ仮想CPUに対するコードを吐くコンパイラと、それを非常に高速にインタプリットして実行するC言語で書かれたエミュレーションカーネルの制作をすることに急遽変更した。大幅に方向転換&軌道修正である。こんなことしてるから、10/15とか言ってたBMRの公開予定日が1ヶ月ほどズレ込んだりするわけだ。

しかし、そのおかげで、エミュレーションカーネル自体はCで記述しているので汎用性が保たれているわけで、コモンプラットホーム構想にまた一歩近づいたわけだ。うひょう!


戻る