[Atelier Blue アトリエブルー]Homeプログラミング IL(CIL,MSIL)>数字と文字列とコンソール出力

数字と文字列とコンソール出力

それでは、タイトル通り出力をしてみましょう。

数字の出力

とりあえず、サンプルコードです。

.assembly hina{}

.method public static void main(){
    .entrypoint
    ldc.i4 10
    call void [mscorlib]System.Console::WriteLine(int32)
    ret
}

それでは、おさらいと説明を行いましょう。

1行目「.assembly hina{}」はこのコードが「hina」というアセンブリに属している事を示しています。「hina」という文字は自由ですが、これは必須です。含めなくてもコンパイルは通りますが、実行時にエラーがでます。つまり、解決策があるわけですが、今は放っておきましょう。

次は「.method public static void main(){」です。「.method」はここからメソッドの記述をはじめる事を表しています。このメソッド宣言はどこのクラスにも属していないためグローバルなメソッドとなります。「public」はどこからでもアクセス可能な事を表します。「static」はこのメソッドがインスタンスに関係のない物である事を示しています。これからもグローバルなメソッドは「static」が必ずつきます。

残りの「void main()」は普通です。

「.entrypoint」はプログラムのスタート地点を表します。

それでは、本題に入ります。まずは「ldc.i4」についての説明です。ldc.i4はld(ロード)c(numeric constant 数値定数).i(integer)4(4byte)です。繋げると4バイトの数値定数のロードです。実は「ldc」には何個か親戚がいます。それらについてはまた後ほど説明しますので今はldc.i4を覚えてください。使い方はその後に数字を続けるだけです。

    ldc.i4 10
    ldc.i4 -10
    ldc.i4 010
    ldc.i4 0x10

使える範囲は32ビット符号付き整数が扱える範囲です。数で言うと「-2147483648 ~ 2147483647」です。覚えにくい方は「-2~31 ~ 2^31-1」と覚えましょう。まあ、2の補数ですので常識ですね(ちなみに、私は今知りました)。

また、先頭に「0」をつけると8進数に、「0x」をつけると16進数になります。

さて、ILにはBasicのように「print」はついていません。というより、.Netではコンソールですら特別扱いしないのですね。というわけでいきなり正攻法の関数呼び出しです。今回はとりあえず外部のクラスのスタティックメソッドの呼び出し方です。

call 戻り値型 [アセンブリ名]ネームスペース.クラス
        ::スタティックメソッド(引数型1,引数型2,引数型3・・・)
call 戻り値型 [アセンブリ名]ネームスペース.クラス
        ::スタティックメソッド()//引数なしの場合

※折り返しているのはスペースの関係です。

引数なしの場合には「void」と書く必要はないです。

今回呼び出したいメソッドは「mscorlib.dll」の中にあります。このDLLはとても重要なライブラリです。ほとんどの基本的な型がこの中で宣言されています。そのため、このDLLについては他のDLLに必要な煩雑な宣言を飛ばして利用する事が出来ます。というわけで、特に何もしなくてもcall出来るわけです。

call void [mscorlib]System.Console::WriteLine(int32)

今回利用する「WriteLine」というメソッドはコマンドラインへデータを表示し、改行します。ネームスペースは「System」、クラスは「Console」です。あらかじめスタックに積んでおいたint32という型のデータ出力したいため、引数の型はそのように指示します。

このように戻り値と、引数の型を事細かに書くのはメソッドのオーバーロードがあるためです。ちなみに、CLRでは戻り理の型が違うだけのオーバーロードも許しています。そのため、ILでは戻り値の型も書く必要があります。

長々となりましたが、後は「ret」を忘れずにつけてください。

文字列の表示

文字列の表示も同じ要領で出来ます。ではサンプルコード。

.assembly hina{}

.method public static void main(){
    .entrypoint
    ldstr "今日からはじめるIL"
    call void [mscorlib]System.Console::WriteLine(string)
    ret
}

真新しいのは「ldstr」だけでしょう。ILでは効率のためにstring型を言語レベルでサポートしています(CLRでサポートしているという表現の方が適切かも)。ですので、stringには専用命令として「ldstr」があります。ld(load)str(string)の事です。この命令は次に続く2重引用符でくくった文字列をスタックにロードします。二重引用符の中ではエスケープシーケンスが使えます。

あとは、これに合わせてメソッド呼び出しをstringに変えればできあがりです。

応用と注意

今までの応用で、何行かの表示が出来るようになります。

.assembly hina{}

.method public static void main(){
    .entrypoint
    ldstr "今日からはじめるIL"
    call void [mscorlib]System.Console::WriteLine(string)
    ldstr "明日からはじめるIL"
    call void [mscorlib]System.Console::WriteLine(string)
    ldstr "あさってからはじめるIL"
    call void [mscorlib]System.Console::WriteLine(string)
    ret
}

一つ注意をするとすれば、「スタックは空っぽにしてからretする」という事です。空になっていないのにretしているという事は無駄があるという事です。よく確認してみましょう。

「System.InvalidProgramException」という普通C#などでプログラミングしていてはお目にかかれない例外が出た時はプログラムに誤りがあります。1行ずつチェックして見てください。



次回はこれからの事を考えスタックについてちょっと補足説明です。


ページの一番上へ
前のページへ 一覧に戻る 次のページへ
初版2006-8-9 最終更新2006-8-11
[Atelier Blue アトリエブルー]Homeプログラミング IL(CIL,MSIL)>数字と文字列とコンソール出力