では、何もしないプログラムの解説をしましょう。
何もしなくてもとても大切な要素を内包しています。コンパイルが通る事です。
.assembly hello{} .method public static void main() { .entrypoint ret }
逆アセンブルしてもほとんど同じコードになるはずです。どうでも良い事のように思えもしますが、情報の再現性は大事ですからね。それでは説明しましょう。
アセンブリ言語のコードとは違います。おおざっぱに言うと、アセンブリとはILにおけるクラスなどのようなまとまりの事を指す言葉です。
アセンブリはdllやexeをまたぐ.Netの管理のまとまりの一つです。一つのクラスは複数のdllにまたがる事が出来ません。しかし、アセンブリにはそれが出来ます。それによって何が出来るかというと、よくバージョンアップする物と、そうでない物を別のDLLに分ける事が出来ます。これだけでは何が良いのか分かりませんが、そこにセキュリティや、リソースデータが絡んでくると役に立つそうです。
とりあえず、そのために「このコードはこれこれのアセンブリに属しています」という宣言が必要になります。
.assembly アセンブリ名{}
アセンブリ名を適当に埋めてください。どんな文字が使えるかは不明です。情報お待ちしております。
まず一つ目、ファイルはansi(sjis)か、Unicode(BOM自由)で保存しましょう。それ以外ではコンパイルに躓くか、日本語が悲惨な事になります。
重要。これから「名前」をつける機会がいくつかあります。思い出して欲しいのですが、あなたは.Netで日本語の変数名やメソッド名、クラス名が使えた気がしませんか?もちろん使えます。使い方は次の通りです。
.assembly 'アセンブリ名'{}
つまり「'」で囲えばいいわけです。それで更に重要なのが、この中でエスケープシーケンスが使える事です。
暇な時にでも試してみてください。何か傑作な事をやり遂げた方はお知らせください。
C#では全てのメソッドが何かしらのクラスに属す事になっていたと思います。ILではそんな事は一切不要。普通に書くと、ILではグローバルなメソッドになります。ただし、そのアセンブリ内についてグローバルなのでそこに注意。
.method メソッド属性 返り値の型 メソッド名(引数) 実装属性{ 付属情報、コード }
実は、ここら辺ですら私はまだ解析しきれていません(英語のドキュメントはあるのですが、ちょっと量が)。
気を取り直して説明です。「メソッド属性」、privateやpublic、staticなどが主だった物です。今回はpublic staticな物を作成します。
「戻り値の型」ILではあらかじめ、いくつかの型が用意されています。今回は何もないのでvoidです。
「メソッド名」自由に。「引数」なし。「実装属性」今回はなし。
ILでは一定の名前のメソッドがプログラムのスタートになるわけでもなければ、頭から実行される訳でもありません。エントリポイントのメソッドには「.entrypoint」と書きます。
.method public static void hoge(){ .entrypoint//エントリポイント }
上のようになります。このようにすると「hoge」メソッドがエントリポイントになります。
メソッドは必ず制御を返さなければなりません。それを行うのが「ret」です。必ず最後には書きます。
.method public static void hoge(){ .entrypoint ret }
retがなくてもコンパイル時には文句を言われません。ですが、実行時に確実に例外を起こされます。プログラムの最後には必ずつけましょう。
本当はもう少し説明したいのですが、次回という事で。
空白と改行についてです。今までのコードは次のように書く事も出来ます。
.assembly hello{}.method public static void main(){.entrypoint ret}
はい。コンパクトで読みにくいコードです。つまり、最低限区切りが分かればどんなにくっついても離れてもOKです。
C++(C#と同じ)形式のコメントをサポートしています。つまり「/* */」のブロック形式と「//」の1行形式です。
.assembly hello{}/* 別に「hello」でなくても良い*/ .method public static void main(){ .entrypoint//ここから始まるプログラム ret//確実に } /* 色々出来ます。 */
次回からは本格的な解説に入ります。私の頭は本格的な混沌へと突入します