(register vs. stack) machine


先週頼んでいた「計算機プログラミングの基礎概念」が、昨日届いたので、
読み始めた。本の帯には、「ちょっと高価だけど、ずっと役に立つ」とあった。

31章あるから、1日に1章やるとして、1月で終わる。SICPみたいに長丁場で挫折する事も
なかろう。MIPSは素直な石で、すいすいと理解出来る。レジスターが32本、アセンブラー
上から使う場合、どういう風にレジスターを使おうが勝手だが、使い方をある程度決めて
おいた方が楽でしょうと言う事で、レジスターに別名(spim上の事ですが)が付けられて
いる。これが、最初頭に入りませんでしたね。
さーと、読み進めて、19章の所で、末尾再帰の話が出てきたのには、ちょいとびっくり
しました。

32本のレジスターのうち0番目のレジスターのみは、読み出すと常にZEROが出てくると
いうのが面白い。(当然、書き込んでも反映されない)
また、普通のCPUでは、演算とかすると、結果がフラグレジスターに反映されるんだけど
MIPSは、フラグレジスターそのものが無いみたい。(全部読み終わってないので、誤解が
あるかも知れませんが)
その変わりに、足し算とかした時に溢れが発生した場合、割り込みを発生させる/させない
という動きをさせる命令が、別々に用意されている。
C言語では整数の足し算で溢れが生じても、感知せずって仕様なので、CをMIPSのアセンブラ
に翻訳するには、割り込みを発生させない方の命令を使えって、盛んに説明してあり
ました。
フラグレジスターを設けない理由は、パイプラインを単純にする為だそうで、珍しい
石なんだなあと思いましたよ。単純と言えば、命令の語長も4バイト固定である。
単純にしてスピードを上げようという方針が如実に現れているなあ。

今、20章の文字列の説明の所を読んでいるけど、まだ、フレームポインターの有効な
使い方が出てきませんねえ。どの章で出てくるか、ちょっと楽しみ。
全章に目を通したら、spimで遊んでみるかな。

それまでは、JVMという、スタックマシンに目を向けておこう。
スタックマシンって、昔、forth とか、Solarisのメンテナンスモードで、ちょいと
遊んだやつですね。

JVMは、プログラムカウンター(PC)、Stack,ガベコレの対象になるHeap(メモリー)から
成っている。この分類は、ハード屋さんから見た場合のものであり、昔富士通がIC上に
構築したJVMや大学の実習でFPGA上に作る、JVMで必須とされる。
勿論、これだけでJVMが実現出来る訳ではなく、整数や浮動小数点演算を実現するユニットが
必要になる事は言うまでもない。
ソフト的には、命令列を格納しておく、メソッドエリア、実行時の定数(文字列等)を
格納するエリア、メソッドの呼び出し順を素直に実現するための、メソッド用スタック,
フレーム(局所変数用、オペランド用)等に分類できる。
命令は、1バイトで表現され、命令によっては、操作対象(データ)がその後に続く。
すなわち、1命令の長さは、可変長である。
なお、データの並び順は、big-endian(the high bytes come first) である。

JVM Spec の、3.11.1には、例として
For instance, the iload instruction loads the contents of a local variable,
which must be an int, onto the operand stack. なんて風に書いてある。
命令を覚えるには、命名方法の規則を覚えてしまうのが、早道だ。

For the majority of typed instructions, the instruction type is represented 
explicitly in the opcode mnemonic by a letter: 

i for an int operation, 
l for long,
s for short,
b for byte, 
c for char, 
f for float, 
d for double, and
a for reference

勿論、これから外れる命名法が存在する訳で、そのあんちょことして、JVM仮想マシンを
見ちゃうのがいいだろう。

ついでなので、*.classファイルのフォーマットがどうなってるかも見てみよう。
4章の冒頭には、C風の構造体で

    ClassFile {
    	u4 magic;
    	u2 minor_version;
    	u2 major_version;
    	u2 constant_pool_count;
    	cp_info constant_pool[constant_pool_count-1];
    	u2 access_flags;
    	u2 this_class;
    	u2 super_class;
    	u2 interfaces_count;
    	u2 interfaces[interfaces_count];
    	u2 fields_count;
    	field_info fields[fields_count];
    	u2 methods_count;
    	method_info methods[methods_count];
    	u2 attributes_count;
    	attribute_info attributes[attributes_count];
    }

と、説明されている。
つらつら見ていくと、このファイルの正体を表わす、magic は、0xCAFEBABE とか、
16進数だけで構成してる所にもこだわりを感じるぞ。
Javaだから、コーヒー、babe って、赤ちゃんとの事だから、Sunの人って、お茶目
だなあ。で、真の意味は、ファイルのままじゃ、何も出来ない赤ちゃん。JVMにロード
されて、縦横無尽に働くのね。
16進数のアナグラムで有名なのに、DEADBEEF なんてのがありますね。このmagicは
牛さんマークのコンピュータメーカーは絶対に使わんでしょう。
(注 at 3/30
Sunは、この手の語呂合わせが好きみたい。でも、間違っても、0xABADCAEE  a bad caee
とは、しないでしょう /注)

そうそう、お茶目と言えば、まだあった。
Javaのガベコレの説明の所に、エデンってのが出てくるんだけど、最初なんじゃらほいと
思っていた。でも、エデンって、アダムとイブが生まれた、あのエデンの園って
思いをめぐらせた時、はたと思いあたりましたね。
エデン領域は、初めてオブジェクトが生まれる場所って事ですね。