Javaの中間コードの中身

最近は夏休みから抜け出すことができたらしく

良い感じで大学では研究、家では応用情報の勉強のループを回すことができています。

もっともポケモン買ってしまったのでだいぶそれに時間食われてますけども。

なんとか次の日曜は応用情報を制覇したい。

話は変わって、最近Javaを勉強し始めたらしい後輩ちゃん(O君)との会話。

O「先輩、バイトコードってなんですか?」

俺「中間コードだよ。ほら、あれ、.classファイルだよ」

O「う~ん・・・?」

俺「中間コードをJavaVMが読み込んで、インタプリタっぽく・・というかJITコンパイルして実行するんだよ」

O「JIT・・・?」

俺「Just in Timeだよ。中間コード読んで、読みながらコンパイルするからJust in Time。まあJITとかVMは詳しくないから他の人に聞いてよ」

O「中間コードって中身なんなんですか?」

俺「バイナリじゃないかなー」

O「アセンブリコードなんですか?」

俺「流石にCから変換したアセンブリコードとは違うだろうけど、うーん分かんないや」

O「見たことありますか?」

俺「無いわ」

という訳で後輩ちゃんと共に見てみた・・・!

案の定バイナリで読めないわけだけど、ありがたーいサイトが解説してくれてました。

http://d.hatena.ne.jp/Nagise/20100207/1265522562

で、ここを見ながら手元にJavaファイルと中間コードを用意して後輩ちゃんと、どんなもんか調べてました。

例えば以下のようなクラスを作って

[java]
package jp.dip.tsukaby;

public class AAAAA {
 public AAAAA(){
 System.out.println("Hello");
 }

}
[/java]

こいつの.classを見てみるとこんな感じ。

ちなみに上の画像はBZっていうバイナリエディタを使ってるので16進表示してくれてます。左が16進で右がそれをASCIIで表示したものです。

これだけじゃ分からないので上記の解説サイトの通りClass File Editorとやらを使おうと思ったのですが、なぜか使えず。

・・・Class File EditorってEclipse標準装備なのかなー?

仕方なくSourceForgeから取ってきて、さっそく使用。

http://sourceforge.jp/projects/sfnet_classeditor/releases/

起動、.classをオープン、Summaryでそれっぽいのが出た。

Summary for class jp.dip.tsukaby.AAAAA
	----------------------------------------------------------------------
	Java Version Information
	----------------------------------------------------------------------
	Magic number: cafebabe
	Minor version: 0
	Major version: 50
	----------------------------------------------------------------------
	Access flags
	----------------------------------------------------------------------
	public super synchronized
	----------------------------------------------------------------------
	Constant Pool
	----------------------------------------------------------------------
	Constant pool count: 30
		1: CLASS: name=jp/dip/tsukaby/AAAAA
		2: UTF8: string=jp/dip/tsukaby/AAAAA
		3: CLASS: name=java/lang/Object
		4: UTF8: string=java/lang/Object
		5: UTF8: string=
		6: UTF8: string=()V
		7: UTF8: string=Code
		8: METHODREF: class=java/lang/Object, name=, type=()V
		9: NAMEANDTYPE: name=, descriptor=()V
		10: FIELDREF: class=java/lang/System, name=out, type=Ljava/io/PrintStream;
		11: CLASS: name=java/lang/System
		12: UTF8: string=java/lang/System
		13: NAMEANDTYPE: name=out, descriptor=Ljava/io/PrintStream;
		14: UTF8: string=out
		15: UTF8: string=Ljava/io/PrintStream;
		16: STRING: string=Hello
		17: UTF8: string=Hello
		18: METHODREF: class=java/io/PrintStream, name=println, type=(Ljava/lang/String;)V
		19: CLASS: name=java/io/PrintStream
		20: UTF8: string=java/io/PrintStream
		21: NAMEANDTYPE: name=println, descriptor=(Ljava/lang/String;)V
		22: UTF8: string=println
		23: UTF8: string=(Ljava/lang/String;)V
		24: UTF8: string=LineNumberTable
		25: UTF8: string=LocalVariableTable
		26: UTF8: string=this
		27: UTF8: string=Ljp/dip/tsukaby/AAAAA;
		28: UTF8: string=SourceFile
		29: UTF8: string=AAAAA.java
	----------------------------------------------------------------------
	Class Names
	----------------------------------------------------------------------
	This class: jp.dip.tsukaby.AAAAA
	Super class: java.lang.Object
	----------------------------------------------------------------------
	Attributes
	----------------------------------------------------------------------
	Attributes count: 1
		Attribute SourceFile. Source=AAAAA.java
	----------------------------------------------------------------------
	Interfaces
	----------------------------------------------------------------------
	Interfaces count: 0
	----------------------------------------------------------------------
	Fields
	----------------------------------------------------------------------
	Number of fields: 0
	----------------------------------------------------------------------
	Methods
	----------------------------------------------------------------------
	Methods count: 1
		1: public void ()
		{
		----------------------------------------------------------------------
		Attributes
		----------------------------------------------------------------------
		Attributes count: 1
			----------------------------------------------------------------------
			Attributes
			----------------------------------------------------------------------
			Attributes count: 1
				Attribute Code. Length=63
				Max stack: 2				Max locals: 1
					------Begin Bytecode-------
					0 aload_0
					1 invokespecial 8
					4 getstatic 10
					7 ldc 16
					9 invokevirtual 18
					12 return
					------End Bytecode-------
					----------------------------------------------------------------------
					Attributes
					----------------------------------------------------------------------
					Attributes count: 2
						Attribute LineNumberTable. TableLength=3
							Line : Start Program Counter
							4 : 0
							5 : 4
							6 : 12
						Attribute LocalVariableTable. TableLength=1
							Position : Start PC : Length : Descriptor : Name
							0 : 0 : 13 : jp.dip.tsukaby.AAAAA : this
		}

おーおーおー!

Begin Bytecodeとかモロじゃん!

後輩ちゃんと一緒に「なるほど、アセンブリコードだ!」で納得。
(これは.classを解析してニーモニックに変換してくれているので、アセンブリコード)
(.classは機械語)

x86とは命令の粒度が違うけど、とりあえずアセンブリコードっぽい。

実は中間コードはある程度読めるということが判明したし、色々と面白かった。

俺には無縁だと思っていたJavaVMの本ももしかしたら面白いかもしれない。

自分が普段使っている物とかの仕組みが分かるって楽しいですね。多分これが勉強に対するモチベーションって人は多いと思う。

明日も頑張ろう。

[tmkm-amazon]489471356X[/tmkm-amazon]

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です