Чтение инструкции Java-байт-кода: что означает число? - PullRequest
8 голосов
/ 18 февраля 2012

Я читал байт-код Java и увидел это:

getfield #5 (Field java.lang.String name)

Что означает #5?

А как мне написать программу в байт-коде?

Ответы [ 3 ]

6 голосов
/ 18 февраля 2012

Файлы классов Java и байт-код

Файлы классов Java (файлы-байт-коды) состоят из различных компонентов:

http://en.wikipedia.org/wiki/Java_class_file

  • Магическое число: 0xCAFEBABE
  • Версия формата файла класса: младшая и основная версии файла класса
  • Пул констант: Пул констант для класса
  • (...)
  • Поля: любые поля в классе
  • Методы: любые методы в классе
  • Атрибуты: любые атрибуты класса (например, имя исходного файла)и т. д.)

Число # 5 просто обозначает местоположение в постоянном пуле.И в этой позиции находится CONSTANT_FieldRef, который содержит ссылку на CONSTANT_NameAndType среди других атрибутов.И CONSTANT_NameAndType содержит ссылку на CONSTANT_Utf8 (который содержит фактическую строку / имя.)

Таким образом, поток выглядит следующим образом:

getfield #number -> FieldRef -> NameAndType -> Utf8 -> string

http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html

Итаквместо сохранения всей строки в каждой инструкции getfield сохраняется номер.Это повышает производительность интерпретатора (или JIT) и пространство в файле класса.

Байт-коды рукописной записи

Байт-коды рукописной записи могут быть собраны в файл классас помощью этого инструмента (он содержит много примеров):

http://jasmin.sourceforge.net/

4 голосов
/ 18 февраля 2012

Инструкция getfield (IIRC) делает ссылку на постоянный пул файла класса для получения информации о том, какое поле следует искать. Номер 5 здесь означает «запись 5 постоянного пула», и этот постоянный пул затем содержит информацию «поиск поля name типа java.lang.String). Причина этого заключается в том, что он сохраняет размер getfield инструкция одинакова, независимо от имени или типа поля для поиска.

Я не уверен, что понимаю, что вы подразумеваете под "как мне написать программу в байт-коде?" Это довольно открытый вопрос; это все равно что спрашивать, как писать программы на любом языке, и требует много изучения. Возможно, вы захотите взглянуть на Java-ассемблер Jasmin , который может значительно упростить этот процесс.

Надеюсь, это поможет!

0 голосов
/ 04 ноября 2018

это постоянный индекс пула, постоянный пул хранит всю информацию о файле класса, индекс использования инструкций JVM ссылается на информацию о классе, такую ​​как поля, методы.

Я буду использовать пример Hello World, чтобы показать, как это работает:

источник

System.out.println("hello world");

байткод

 0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
 3: ldc           #3                  // String hello world
 5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
 8: return

инструкция байт-кода отформатирована как instruction constant pool index

  Constant pool:

   #4 = Methodref          #28.#29        // java/io/PrintStream.println:(Ljava/lang/String;)V
  #28 = Class              #36            // java/io/PrintStream
  #29 = NameAndType        #37:#38        // println:(Ljava/lang/String;)V
  #36 = Utf8               java/io/PrintStream
  #37 = Utf8               println
  #38 = Utf8               (Ljava/lang/String;)V

поэтому эта инструкция будет вызывать метод с индексом 4

invokevirtual #4

и индекс 4 представляет собой Methodref из // java/io/PrintStream.println:(Ljava/lang/String;)V

если мы пойдем по ссылке в пуле констант, мы обнаружим, что вся информация хранится в строке и компоновывается в сложный тип, такой как метод, поле, класс.

...