そういえば、命令の説明をしてきませんでした。そこで、命令を説明したいのですが…。私にもよく分かりません。最初から読み進めてもらえば分かると思いますが、この記事群はリファレンスではなく「解析」です。ですから、解析していきましょう。
そうはいった物の、あまりに分からなさすぎるのも困るので、今の時点で分かっていること説明します。
MSILにはレジスタがないと思われます。計算は全てスタックを返して行われます。Javaと同じですね。このようなマシンはスタックマシン
スタックマシンについて少し説明します。スタックマシンでは主にスタックを返して処理が行われます。1+2をしたいとします。このときはまず「1」と「2」をスタックに積みます。そして足し算を行います。するとスタックの先頭から2つの数字を取り出し足しあわせた結果をスタックの先頭に戻してくれるのです。とりあえずそのような動きでスタックマシンは動きます。
空A
空B
空C
1と2をプッシュ
2
1
空A
空B
空C
足し算を実行
3
空A
空B
空C
結果が先頭に書き込まれる。
利都はjavaの処理系もCLRの処理系も未だに完全に理解できていないのでここの記述は間違っている可能性があります。
というわけで文字列を表示させていたソースコードは次の動作をしていたわけです。
.assembly extern mscorlib {} /*入れても入れなくても良い。*/ .assembly hello {} .method static public void main() cil managed { .entrypoint ldstr "Hello world!" //スタックに文字列を積む call void [mscorlib]System.Console:: WriteLine(class System.String) //関数をコール ret //終了 }
中間コードならではの文字列の扱い方ですね。文字列を標準で扱えるとは。
とりあえず今回のことから「ld」というのがスタックに何かを積むための命令であることが分かりました。では、いよいよ数字を表示させましょう。
今回はとりあえず「0」を表示させましょう。
.assembly extern mscorlib {} .assembly outnum {} .method static public void main () cil managed { .entrypoint ldc.i4.0 call void [mscorlib]System.Console::WriteLine(int32) ret }
新しい命令がありますね。「ldc.i4.0」です。どうやら、「ldc.i4」で「int32」の数をプッシュするらしいです。残りの「0」はプッシュする数ですね。では、この「ldc.i4.~」はどの程度の種類があるのでしょうか?正解は次の通りです。
まあ、簡単ですね。「i4」はつまり「integer4バイト」ということらしいです。ちなみに「ldc.i4.s」を使えば、-128~127までの範囲なら少ないバイト数で行うことが出来ます。.Netでも即値を使う場合はなるべくこれらの数を使うようにすると良さそうです。
次回は今回の知識を応用して計算をしてみたいと思います。