ClassFile {
          u4 magic;
          u2 minor_version;
          u2 major_version;
          u2 constant_pool_count;
          cp_info constant_pool[constant_pool_count-1];
        u2 access_flags;
        u2 this_class;
        u2 super_class;
        u2 interfaces_count;
        u2 interfaces[interfaces_count];
        u2 fields_count;
        field_info fields[fields_count];
        u2 methods_count;
        method_info methods[methods_count];
        u2 attributes_count;
        attribute_info attributes[attributes_count];
    }

 

構造体の形を見る限りこのような構成になっている

となっているから、interfaces countまでは2バイトづつとっていけば良いだろう。

 

Interface Fieldsともにカウントがゼロで、メソッドが二つだった。

    method_info {
         u2 access_flags;
         u2 name_index;
         u2 descriptor_index;
         u2 attributes_count;
         attribute_info attributes[attributes_count];
    }
    attribute_info {
         u2 attribute_name_index;
         u4 attribute_length;
         u1 info[attribute_length];
    }
 
 

 

これに前回の表をあてはめていく

No

tag

Index

 

 

 

1

0A

0006

0014

 

 

2

09

0015

0016

 

 

3

08

0017

 

 

 

4

0A

0018

0019

 

 

5

07

001A

 

 

 

6

07

001B

 

 

 

7

01

 

 

<init>

 

8

01

 

 

()V

 

9

01

 

 

Code

 

01

 

 

LineNumberTable

 

01

 

 

LocalVariableTable

 

01

 

 

This

 

01

 

 

Ltest/test;

 

01

 

 

Main

 

01

 

 

([Ljava/lang/String;)V

 

10

01

 

 

Args

 

11

01

 

 

[Ljava/lang/String;

 

12

01

 

 

SourceFile

 

13

0C

0007

0008

 

 

14

07

001C

 

 

 

15

0C

001D

001E

 

 

16

01

 

 

test.java

 

17

07

001F

 

 

 

18

0C

0020

0021

 

 

19

01

 

 

ABCDEFG

 

1A

01

 

 

test/test

 

1B

01

 

 

java/lang/Object

 

1C

01

 

 

java/lang/System

 

1D

01

 

 

Out

 

1E

01

 

 

Ljava/io/PrintStream;

 

1F

01

 

 

java/io/PrintStream

 

20

01

 

 

Println

 

21

01

 

 

(Ljava/lang/String;)V

 

 

 

 

 

 

 

No

tag

Index

 

 

 

1

0A

0006

0014

 class_index java/lang/Object  name_and_type_index <init> ()V

CONSTANT_Methodref_info

2

09

0015

0016

 class_index Lout LJava/io/Printstream  name_and_type_index test.java

CONSTANT_Fieldref_inf

3

08

0017

 

 string_index java/io/printstream

 CONSTANT_String_info

4

0A

0018

0019

 class_index java/io/printstream name_and_type_index ABCDEFG

CONSTANT_Methodref_info

5

07

001A

 

 Test/test

 CONSTANT_Class_info

6

07

001B

 

 Java/lang/Object

 CONSTANT_Class_info

13

0C

0007

0008

 name_index <init> descriptor_index ()V

CONSTANT_NameAndType_info

14

07

001C

 

 Java/lang/System

 CONSTANT_Class_info

15

0C

001D

001E

 name_index LOut. descriptor_index Ljava/io/PrintStream

CONSTANT_NameAndType_info

17

07

001F

 

 Java/io/PrintStream

 CONSTANT_Class_info

18

0C

0020

0021

 name_index Println. descriptor_index (Ljava/lang/String)

CONSTANT_NameAndType_info

 

 

 

Attributeの意味はおいといて、CODEというのがわれわれが捜し求めていたいとしいしと、バイトコードであると推測できる。Init 33バイト・Main37バイトのコードを利用している。それぞれのAttributeも仕様が明示されていてCODEも構造が書いてあった。

    Code_attribute {
         u2 attribute_name_index;
         u4 attribute_length;
         u2 max_stack;
         u2 max_locals;
         u4 code_length;
         u1 code[code_length];
         u2 exception_table_length;
         {       u2 start_pc;
                 u2 end_pc;
                 u2  handler_pc;
                 u2  catch_type;
         }       exception_table[exception_table_length];
         u2 attributes_count;
         attribute_info attributes[attributes_count];
    }

 

この構造をあてはめると以下のようになる

 

ようやく5バイトと9バイトの命令セット(コード本体)が現れた。うれしいのでこれを逆ハンドアセンブルする。

2A/B7/00/01/B1

B2/00/02/12/03/B6/00/04/B1

文法の常識としてオペコード・オペランドとくるはずだ。それぞれの文頭は以下の

 

aload_0

getstatic

 

オペコードに対応しているのが分かった。

Aloadrefference型のロード命令で詳細は不明。その次が、invokespecial ということになるはずで、これは後にバイトのオペランドを必要とするらしく0001の読み込みをこれで行うということになるんではないだろうか。コンスタンとプールの0001はinitなので、これで初期化めそっどを呼び出したことになるのだろう。

 

Getstatic 0002対して何かやってるので、io.クラスの読み込みか何かだろうか。続いての12はldc03がオペランドのようだ。次に

invokevirtualを呼び出して0004をインヴォークしている。この0004printstream “ABCDEFG”のことになっている。

最後はどちらもB1で恐らく終了コマンドかなにかだろう。調べてみたらreturnということであった。

 

今までの経緯を逆ハンドアセンブルしてみる

:初期化コード

Aload_0;

Invokespesial <0001>;

Return;

:メインコード

Getstatic <0002>;

Ldc <03>;

Invokevirtual <0004>;

Return;

 

なんだか真面目にここまでやってタイトルもない。

 

えんでー、エンエンエーン

 

おわり