今まで、データは全てスタック上で扱っていました。しかし、それではいつかは限界が来ます。C#で書いたコードの変数が全てスタックに直されて扱われているわけではありません。そこで今回はローカル変数について学びましょう。
ローカル変数は宣言しなければ使う事が出来ません。そこで、宣言します。
.assembly hina{} .method public static void main(){ .entrypoint .locals(int32 num,string str)//ここがローカル変数の宣言 ret }
構造は至って単純、「.locals」と書き、「( )」の中に型名と名前を並べて書くだけです。複数の時にはカンマで区切ります。
.locals(型名 名前,型名 名前,・・・,型名 名前)
このようにすると、C#と同じく「型名」に従った変数が出来ます。
変数は次のようにすると、0初期化されるようになります。
.locals init(型名 名前,型名 名前,・・・,型名 名前)
覚えておくと便利です。
それではスタックからデータをロードします。
.assembly hina{} .method public static void main(){ .entrypoint .maxstack 1 .locals (int32 num,string str) //各自「init」有りも試してみてください。 ldloc num call void [mscorlib]System.Console::WriteLine(int32) ldloc str call void [mscorlib]System.Console::WriteLine(string) ret }
命令は「ldloc 変数名」です。ld(load)loc(local variable)、ローカル変数からロード。これを使うと、変数名のデータがスタックの一番上にロードされます。
変数を、initなしで実行すると、変な値が出てくると思います。
それでは変数へスタックから変数へストアしてみましょう。
.assembly hina{} .method public static void main(){ .entrypoint .maxstack 1 .locals (int32 num,string str)//ここがローカル変数の宣言 ldc.i4 60 stloc num ldstr "ためして、IL!" stloc str ldloc numa call void [mscorlib]System.Console::WriteLine(int32) ldloc str call void [mscorlib]System.Console::WriteLine(string) ldloc num call void [mscorlib]System.Console::WriteLine(int32) ldloc str call void [mscorlib]System.Console::WriteLine(string) ret }
利点を実感して貰うために、二回出力しています。
命令は「stloc 変数名」です。st(store)loc(local variable)、ローカル変数へストア。これを使うと、変数名の場所へスタックの一番上のデータが書き込まれます。
書き込んだデータは何回読み込んでも消えません。
いくつか、説明し足したい事もありますが、また今度。次回はILのスタックの型と、ローカル変数の型について触れます。