乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Matrix - 與 Java 共舞 - JVM之class文件結(jié)構(gòu)

       zhuge 2006-04-10

                                     by cloud (safesuite@263.net )
                   定義:u1   1個字節(jié)為單位的非負(fù)值
               u2   2個字節(jié)為單位的非負(fù)值
               u3   . . . . . . . .  (其他以此類推 )


          Java文件結(jié)構(gòu)用類似struct的描述如下:

          ClassFile {
                  u4 magic;               // 必須為: 0xCAFEBABE


                  u2 minor_version;
                  u2 major_version;       //CLASS文件結(jié)構(gòu)主次版本號 JAVA2支持45.0-46.
      0
                  u2 constant_pool_count; //記錄常量信息
                  cp_info constant_pool[constant_pool_count-1];   //計數(shù)從1開始
                  u2 access_flags;        //class/interface訪問權(quán)限
                  u2 this_class;          //指向constant_poll中的有效索引值
                  u2 super_class;         //0或指向constant_poll中的有效索引值,對于in
      terface必須為非0
                  u2 interfaces_count;    //superinterfaces的個數(shù)
                  u2 interfaces[interfaces_count];  //計數(shù)[0,count-1) 對應(yīng)constant_po
      ol中的一個索引值
                  u2 fields_count;
                  field_info fields[fields_count];  //主要用于記錄class及實例中的變量
                  u2 methods_count;
                  method_info methods[methods_count];
                  u2 attributes_count;
                  attribute_info attributes[attributes_count];
          }

          cp_info {
                  u1 tag;


                  u1 info[];
          }
              tag 意義如下:

              CONSTANT_Class                7
              CONSTANT_Fieldref             9
              CONSTANT_Methodref            10
              CONSTANT_InterfaceMethodref   11
              CONSTANT_String               8
              CONSTANT_Integer              3
              CONSTANT_Float                4
              CONSTANT_Long                 5
              CONSTANT_Double               6
              CONSTANT_NameAndType          12
              CONSTANT_Utf8                 1

              此時cp_info分別對應(yīng)結(jié)構(gòu)變化為
              1. CONSTANT_Class
              CONSTANT_Class_info {
                      u1 tag;
                      u2 name_index;
              }



              2. CONSTANT_Fieldref
                CONSTANT_Fieldref_info {
                          u1 tag;
                          u2 class_index;  //constant_pool的索引,對應(yīng)CONSTANT_Class_
      info
                          u2 name_and_type_index;//constant_pool的索引,對應(yīng)CONSTANT_
      NameAndType_info
                }

              3. CONSTANT_Methodref
                 CONSTANT_Methodref_info {
                          u1 tag;
                          u2 class_index;
                          u2 name_and_type_index;
                 }

              4. CONSTANT_InterfaceMethodref
                 CONSTANT_InterfaceMethodref_info {
                          u1 tag;
                          u2 class_index;
                          u2 name_and_type_index;


                 }

              5. CONSTANT_String
                 CONSTANT_String_info {
                          u1 tag;
                          u2 string_index;
                  }

              6. CONSTANT_Integer
                  CONSTANT_Integer_info {
                          u1 tag;
                          u4 bytes;
                  }


              7. CONSTANT_Float
                 CONSTANT_Float_info {
                          u1 tag;
                          u4 bytes;
                 }

              8. CONSTANT_Long


                  CONSTANT_Long_info {
                          u1 tag;
                          u4 high_bytes;
                          u4 low_bytes;
                   }

              9. CONSTANT_Double
                 CONSTANT_Double_info {
                          u1 tag;
                          u4 high_bytes;
                          u4 low_bytes
                 }

              10.CONSTANT_NameAndType
                  CONSTANT_NameAndType_info {
                          u1 tag;
                          u2 name_index;
                          u2 descriptor_index;
                  }

              11.CONSTANT_Utf8
                  CONSTANT_Utf8_info {


                          u1 tag;
                          u2 length;
                          u1 bytes[length];
                  }

          access_flags意義如下:

              ACC_PUBLIC     0x0001
              ACC_FINAL      0x0010
              ACC_SUPER      0x0020
              ACC_INTERFACE  0x0200
              ACC_ABSTRACT   0x0400

            如果是interface那么必須置ACC_INTERFACE,如果沒有置ACC_INTERFACE則定義的是一
      個類而非接口。
            如果設(shè)置了ACC_INTERFACE,那么ACC_ABSTRACT位也必須被設(shè)置,當(dāng)然也可以設(shè)置AC
      C_PUBLIC。
            ACC_SUPER用以表明invokespecial語義,Sun公司老的JAVA編譯器沒有設(shè)置ACC_SUPER
      ,并且老的JVM
          忽略ACC_SUPER位,但新的編譯器應(yīng)該實現(xiàn)invokespecial語義。
            其他未指明的位保留將來使用,并且編譯器應(yīng)當(dāng)將其置為0,同時Java虛擬機(jī)應(yīng)當(dāng)忽
      略他們。



         this_class:  constant_pool中的索引值,指向的元素的cp_info等價為CONSTANT_Class
      _info

              CONSTANT_Class_info {
                  u1 tag;                 //必須為CONSTANT_Class (7)
                  u2 name_index;          //為指向constant_pool中的一個索引值
              }

                  name_index :指向的元素的cp_info等價為CONSTANT_Utf8_info

                      CONSTANT_Utf8_info {
                             u1 tag;               //必須為CONSTANT_Utf8 (1)
                             u2 length;
                             u1 bytes[length];     //Utf8編碼的字符串
                      }


          field_info {
                  u2 access_flags;   //訪問控制權(quán)
                  u2 name_index;     //constant_pool中的索引,對應(yīng)于CONSTANT_Utf8_inf
      o描述。


                  u2 descriptor_index; //constant_pool中的索引,對應(yīng)于CONSTANT_Utf8_i
      nfo描述。
                  u2 attributes_count;
                  attribute_info attributes[attributes_count]; //attribute_info將在mo
      thods后描述。
          }
             field_info中access_flages意義如下:

                 ACC_PUBLIC     0x0001
                 ACC_PRIVATE    0x0002
                 ACC_PROTECTED  0x0004
                 ACC_STATIC     0x0008
                 ACC_FINAL      0x0010
                 ACC_VOLATILE   0x0040
                 ACC_TRANSIENT  0x0080

                 其中很顯然不能同時為ACC_FINAL和ACC_VOLATILE ;且前三項是互斥的。
                 interface必須置ACC_PUBLIC, ACC_STATIC,ACC_FINAL位,且不能置其他位。
                 其他未指明的位保留將來使用,并且編譯器應(yīng)當(dāng)將其置為0,同時Java虛擬機(jī)應(yīng)
      當(dāng)忽略他們。




          methods指明了類中的所有方法。

              method_info {
                          u2 access_flags;
                          u2 name_index;   //指向constant_pool的入口,對應(yīng)為CONSTANT_
      Utf8_info
                          u2 descriptor_index;  //指向constant_pool的入口,對應(yīng)為CONS
      TANT_Utf8_info
                          u2 attributes_count;
                          attribute_info attributes[attributes_count];
                          //此處只能出現(xiàn)Code、Exceptions、Synthetic、Deprecated四種類
      型的屬性
              }
                 access_flags訪問權(quán)描述如下:
                  ACC_PUBLIC        0x0001
                  ACC_PRIVATE       0x0002
                  ACC_PROTECTED     0x0004
                  ACC_STATIC        0x0008
                  ACC_FINAL         0x0010
                  ACC_SYNCHRONIZED  0x0020
                  ACC_NATIVE        0x0100
                  ACC_ABSTRACT      0x0400


                  ACC_STRICT        0x0800


          attribute_info {
                  u2 attribute_name_index;  //constant_pool中的索引,對應(yīng)于CONSTANT_U
      tf8_info描述。
                  u4 attribute_length;
                  u1 info[attribute_length];
          }

          現(xiàn)在已經(jīng)預(yù)定義的屬性有:

            1. SourceFile : attribute_info被替代為:

                 SourceFile_attribute {
                          u2 attribute_name_index;
                          u4 attribute_length;
                          u2 sourcefile_index; //指向constant_pool中的一個CONSTANT_Ut
      f8_info 結(jié)構(gòu)。
                 }

            2. ConstantValue : attribute_info被替代為:



                ConstantValue_attribute {
                          u2 attribute_name_index;
                          u4 attribute_length;    //必須為2
                          u2 constantvalue_index;
                }

                對于constantvalue_index意義如下:
                        long                              CONSTANT_Long
                        float                             CONSTANT_Float
                        double                            CONSTANT_Double
                        int, short, char, byte, boolean   CONSTANT_Integer
                        String                            CONSTANT_String

                ConstantValue用于field_info 中,用于描述一個static常量,
                且此時field_info的access_flags應(yīng)為ACC_STATIC


            3. Code : attribute_info被替代為:

                 Code_attribute {
                          u2 attribute_name_index;


                          u4 attribute_length;
                          u2 max_stack;  //執(zhí)行此函數(shù)時可用的棧的最大深度
                          u2 max_locals; //執(zhí)行此函數(shù)可用到的最大本地變量數(shù)目,包括參
      數(shù)。
                                         // 注意:一個long/double相當(dāng)于2個變量數(shù)目.
                          u4 code_length; //本函數(shù)用到的代碼長度。
                          u1 code[code_length]; //實現(xiàn)本函數(shù)的真正字節(jié)碼
                          u2 exception_table_length;
                          {   u2 start_pc;
                              u2 end_pc; //捕獲違例時執(zhí)行代碼數(shù)組中的[start_pc, end_p
      c)部分
                              u2  handler_pc; //現(xiàn)在還不大明白他是干嘛的!!
                              u2  catch_type; //指向constant_pool的索引,對應(yīng)CONSTANT
      _Class_info
                          }exception_table[exception_table_length];
                          u2 attributes_count;
                          attribute_info attributes[attributes_count];
                 }

                      CONSTANT_Class_info {
                          u1 tag;         //必須為CONSTANT_Class (7)
                          u2 name_index;  //不用我再說了吧?


                       }

                 Code屬性用于method_info結(jié)構(gòu)中。

            4. Exceptions : attribute_info被替代為:

                 Exceptions_attribute {
                        u2 attribute_name_index;
                        u4 attribute_length;
                        u2 number_of_exceptions;
                        u2 exception_index_table[number_of_exceptions];
                 }

            5. InnerClasses  : attribute_info被替代為:

                 InnerClasses_attribute {
                        u2 attribute_name_index;
                        u4 attribute_length;
                        u2 number_of_classes;
                        {  u2 inner_class_info_index;
                           u2 outer_class_info_index;
                           u2 inner_name_index;


                           u2 inner_class_access_flags;
                        } classes[number_of_classes];
                  }

            6. Synthetic : attribute_info被替代為:

                 Synthetic_attribute {
                       u2 attribute_name_index;  //不用廢話了吧?
                       u4 attribute_length;     //必須為0
                 }
                Synthetic用在 field_info、 method_info 中,
                一個沒有出現(xiàn)在源程序中的變量必須使用Synthetic標(biāo)記。

            7. LineNumberTable : attribute_info被替代為:

                LineNumberTable_attribute {
                          u2 attribute_name_index;
                          u4 attribute_length;
                          u2 line_number_table_length;
                          {  u2 start_pc;        //代碼數(shù)組中的開始處
                             u2 line_number;     //源文件中的行號(對于每一非空行都有這
      么一項)


                          } line_number_table[line_number_table_length];
                }
                LineNumberTable用于Code屬性中,通常用于調(diào)試。


            8. LocalVariableTable : attribute_info被替代為:

                    LocalVariableTable_attribute {
                          u2 attribute_name_index;
                          u4 attribute_length;
                          u2 local_variable_table_length;
                          {   u2 start_pc;
                              u2 length; //當(dāng)解釋到代碼數(shù)組的[start_pc,start_pc+lengt
      h]
                                         //時變量必須被賦值??
                              u2 name_index;
                              u2 descriptor_index;
                              u2 index;  //到本地變量數(shù)組的一個索引
                          } local_variable_table[local_variable_table_length];
                    }

            9. Deprecated : attribute_info被替代為:



                    Deprecated_attribute {
                              u2 attribute_name_index;
                          u4 attribute_length;   //必須為0
                    }


            當(dāng)然你也可以定義自己的屬性,但要你自己的編譯器和虛擬機(jī)實現(xiàn)。JVM將忽略自己
      不認(rèn)可的屬性。

      來實踐一下吧!
      編寫一個最簡單的程序:
      class Test
      {
              public static void main(String[] args)
              {
                      System.out.println("Hello World!");
              }
      }

      c:\work>javac Test.java



      c:\work>filedump Test.class

      File Dump V0.3 Beta by cloud (safesuite@363.net).

      01:00    ca fe ba be 00 03 00 2d 00 1d 0a 00 06 00 0f 09   .......-........
      01:01    00 10 00 11 08 00 12 0a 00 13 00 14 07 00 15 07   ................
      01:02    00 16 01 00 06 3c 69 6e 69 74 3e 01 00 03 28 29   .....<init>...()
      01:03    56 01 00 04 43 6f 64 65 01 00 0f 4c 69 6e 65 4e   V...Code...LineN
      01:04    75 6d 62 65 72 54 61 62 6c 65 01 00 04 6d 61 69   umberTable...mai
      01:05    6e 01 00 16 28 5b 4c 6a 61 76 61 2f 6c 61 6e 67   n...([Ljava/lang
      01:06    2f 53 74 72 69 6e 67 3b 29 56 01 00 0a 53 6f 75   /String;)V...Sou
      01:07    72 63 65 46 69 6c 65 01 00 09 54 65 73 74 2e 6a   rceFile...Test.j
      >d
      02:00    61 76 61 0c 00 07 00 08 07 00 17 0c 00 18 00 19   ava.............
      02:01    01 00 0c 48 65 6c 6c 6f 20 57 6f 72 6c 64 21 07   ...Hello World!.
      02:02    00 1a 0c 00 1b 00 1c 01 00 04 54 65 73 74 01 00   ..........Test..
      02:03    10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63   .java/lang/Objec
      02:04    74 01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 53 79   t...java/lang/Sy
      02:05    73 74 65 6d 01 00 03 6f 75 74 01 00 15 4c 6a 61   stem...out...Lja
      02:06    76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61   va/io/PrintStrea
      02:07    6d 3b 01 00 13 6a 61 76 61 2f 69 6f 2f 50 72 69   m;...java/io/Pri
      >d


      03:00    6e 74 53 74 72 65 61 6d 01 00 07 70 72 69 6e 74   ntStream...print
      03:01    6c 6e 01 00 15 28 4c 6a 61 76 61 2f 6c 61 6e 67   ln...(Ljava/lang
      03:02    2f 53 74 72 69 6e 67 3b 29 56 00 20 00 05 00 06   /String;)V. ....
      03:03    00 00 00 00 00 02 00 00 00 07 00 08 00 01 00 09   ................
      03:04    00 00 00 1d 00 01 00 01 00 00 00 05 2a b7 00 01   ............*...
      03:05    b1 00 00 00 01 00 0a 00 00 00 06 00 01 00 00 00   ................
      03:06    01 00 09 00 0b 00 0c 00 01 00 09 00 00 00 25 00   ..............%.
      03:07    02 00 01 00 00 00 09 b2 00 02 12 03 b6 00 04 b1   ................
      >d
      04:00    00 00 00 01 00 0a 00 00 00 0a 00 02 00 00 00 05   ................
      04:01    00 08 00 06 00 01 00 0d 00 00 00 02 00 0e         ..............
      >

      解讀一下:

      ca fe ba be     magic
      00 03 00 2d     次主版本號,換算一下:   45.3 (注意,不是高字節(jié)在前,別犯職業(yè)?。?br>)
      00 1d           constant_pool元素個數(shù)加一  :  29  那么constant_pool就是[1-28]
      constant_pool: 1-28

      1.  0a 00 06 00 0f


                      0x0a :CONSTANT_InterfaceMethodref  0x06 :class index  0x0f :nam
      e-type-index
      2.  09 00 10 00 11
                      0x09 : CONSTANT_Fieldref             0x10:  . . .       0x11 :
      . . . .
      3.  08 00 12     0x08 : CONSTANT_String    0x12 : string_index
      4.  0a 00 13 00 14     0x0a同于1.
      5.  07 00 15     0x07 : CONSTANT_Class     0x15 : name_index
      6.  07 00 16
      7.  01 00 06 3c 69 6e 69 74 3e 01  ...<init>
                      0x01   CONSTANT_Utf8     0x06  : string length   "<init>" : 構(gòu)造
      函數(shù)
      8.  01 00 03 28 29 56   ...()V   函數(shù),無參數(shù)
                      0x01   . . . . . .       0x03  : . . . .         "()V"    :  .
      . .
      9.  01 00 04 43 6f 64 65    ...Code
      10. 01 00 0f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65  ...LineNumberTable
      11. 01 00 04 6d 61 69 6e    ...main
      12. 01 00 16 28 5b 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 29 56
                 ...([Ljava/lang/String;)V   函數(shù),參數(shù)為String[]類型
      13. 01 00 0a 53 6f 75 72 63 65 46 69 6c 65   ...SourceFile
      14. 01 00 09 54 65 73 74 2e 6a 61 76 61      ...Test.java


      15. 0c 00 07 00 08         0x0c:CONSTANT_NameAndType  07 : name-index 08:name-t
      ype-index
      16. 07 00 17
      17. 0c 00 18 00 19
      18. 01 00 0c 48 65 6c 6c 6f 20 57 6f 72 6c 64 21  ...Hello World!
      19. 07 00 1a
      20. 0c 00 1b 00 1c
      21. 01 00 04 54 65 73 74   ...Test
      22. 01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 4f 62 6a 65 63 74   ...java/lang/Obj
      ect
      23. 01 00 10 6a 61 76 61 2f 6c 61 6e 67 2f 53 79 73 74 65 6d   ...java/lang/Sys
      tem
      24. 01 00 03 6f 75 74    ...out
      25. 01 00 15 4c 6a 61 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61 6d 3b
             ...Ljava/io/PrintStream;
      26. 01 00 13 6a 61 76 61 2f 69 6f 2f 50 72 69 6e 74 53 74 72 65 61 6d...java/io
      /PrintStream
      27. 01 00 07 70 72 69 6e 74 6c 6e   ...println
      28. 01 00 15 28 4c 6a 61 76 61 2f 6c 61 6e 67 2f 53 74 72 69 6e 67 3b 29 56
             ...(Ljava/lang/String;)V




      00 20    access_flags
      00 05    this_class
      00 06    super_class
      00 00    interfaces_count
      00 00    fields_count
      00 02    methods_count

      methods[2]:

      method_info {
          u2 access_flags;
          u2 name_index;
          u2 descriptor_index;
          u2 attributes_count;
          attribute_info attributes[attributes_count];
      }
      0.   00 00     access_flags;
           00 07     name_index;     看看constant_pool的第7項: <init>  表明當(dāng)前描述構(gòu)
      造函數(shù)
           00 08     descriptor_index;
           00 01     attributes_count;
           00 09     attribute_name_index   0x09 看看constant_pool的第9項,簡單明了Cod


      e ?。?br>     00 00 00 1d  attribute_length   = 29
           00 01     max_stack
           00 01     max_locals
           00 00 00 05  code_length
           2a b7 00 01 b1       JVM定義的操作碼代碼段數(shù)組
           00 00    exception_table_length
           00 01    attributes_count     一個,接下來是attribute_info結(jié)構(gòu)
           00 0a    attribute_name_index  看看constant_pool的第10項: LineNumberTable(
      顯然調(diào)試用)
           00 00 00 06  attribute_length
           00 01    line_number_table_length
           00 00    start_pc
           00 01    line_number

      1.   00 09    access_flags   PUBLIC & STATIC
           00 0b    name_index;                   表明當(dāng)前描述main函數(shù)
           00 0c    descriptor_index;   ...([Ljava/lang/String;)V
           00 01    attributes_count;
           00 09    attribute_name_index   Code
           00 00 00 25    attribute_length   = 37
           00 02    max_stack


           00 01    max_locals
           00 00 00 09   code_length
           b2 00 02 12 03 b6 00 04 b1    代碼數(shù)組  codeArray1[0-8]
           00 00    exception_table_length
           00 01    attributes_count    接下來是attribute_info結(jié)構(gòu)
           00 0a    attribute_name_index  LineNumberTable
           00 00 00 0a  attribute_length
           00 02    line_number_table_length
           00 00    start_pc
           00 05    line_number
           00 08    start_pc     : codeArray1[8] = 0xb1 -->  return
           00 06    line_number  第6行源程序為  }


      00 01     attributes_count
      00 0d     attribute_name_index   屬性為SourceFile
      00 00 00 02  attribute_length
      00 0e     sourcefile_index    constant_pool[0x0e] --- >  "Test.java"


      接下來我們看看main()函數(shù)對應(yīng)的代碼:



      b2 00 02 12 03 b6 00 04 b1

      0xb2  0x00  0x02 : getstatic #2
               看看constant_pool[0x02] :09 00 10 00 11
                      0x09 : CONSTANT_Fieldref         0x10:  class index   0x11 :nam
      e-type-index
                constant_pool[0x10]:  --> constant_pool[0x17]  : java/lang/System
                constant_pool[0x11]:    0x18 : class index   0x19 :name-type-index
                         constant_pool[0x18] : out
                         constant_pool[0x19] : Ljava/io/PrintStream

                           即 System.out 為 java.io.PrintStream 類型



      0x12  0x03  : ldc #3
                看看 constant_pool[3] : 08 00 12     0x08 : CONSTANT_String    0x12 :
      string_index
                              指向一個字符串  constant_pool[0x12]: "Hello World!"
                故該指令加載了字符串索引到本地棧
      0xb6  0x00  0x04: invokevirtual #4
                              ------->到constant_pool查查 0x13  :class   0x14 :name-t


                                                     看看constant_pool[0x13]:java/io/
      PrintStream
                                                     constant_pool[20] :-->  00 1b 00
      1c
                                                     constant_pool[0x1b]:println
                                                     . . . .            :(Ljava/lang/
      String;)V

             故該指令調(diào)用了 java.io.PrintStream.println(java.lang.String)
                 而參數(shù)則為 ldc #3 加載的 "Hello World!"
      0xb1  : return



        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多