46867 (Ассемблер для платформы Java)
Описание файла
Документ из архива "Ассемблер для платформы Java", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "курсовые/домашние работы", в предмете "информатика, программирование" в общих файлах.
Онлайн просмотр документа "46867"
Текст из документа "46867"
Содержание.
Содержание. 1
Содержание. 2
Введение. 3
Постановка задачи. 4
Формат файла класса. 5
Структура файла класса. 5
Типы элементов Constant_pool 6
Формат структуры field_info 7
Формат структуры method_info 7
Формат атрибута Code. 8
Работа JVM 10
Система команд JVM. 12
Синтаксис языка ассемблера для платформы Java (языка JASM). 14
Тестовые примеры. 18
1. 18
2. 19
3. 20
Проектирование и реализация компилятора. 25
Заключение. 30
Использованная литература. 31
Введение.
Язык программирования Java был разработан в середине 90-х годов на основе языка Oak, предназначавшегося для программирования «прошивок» для различных электронных устройств. Однако, в отличие от своего предшественника, язык Java получил широкое распространение, прежде всего как язык, использовавшийся в программировании для сети Интернет. В настоящее время область применения Java значительно расширилась, и этот язык часто применяется и в обычном прикладном программировании. Это обусловлено такими преимуществами как кроссплатформенность и безопасность, которые обеспечиваются тем, что исходный код на Java компилируется не непосредственно в машинный код, а в, так называемый, байт-код, который интерпретируется виртуальной машиной Java (JVM). Во многих современных реализациях JVM байт-код перед выполнением преобразуется в машинные инструкции, что значительно повышает производительность, приближая ее к производительности программ, написанных на C/C++. Таким образом, Java, в современном состоянии этой технологии, сочетает преимущества интерпретируемых и компилируемых языков программирования.
Спецификация, описывающая JVM, как абстрактную вычислительную машину, предоставлена компанией Sun в открытый доступ. Это позволяет создавать как собственные реализации JVM для различных платформ, так и альтернативные компиляторы, генерирующие байт-код Java, в том числе для языков программирования, отличных от Java. Большинство литературы, посвященной Java, почти не уделяет внимания устройству JVM и описывает лишь сам язык Java. Однако, в ряде случаев, знание особенностей архитектуры бывает весьма полезным. В данной работе я создал учебную программу, которая может помочь в изучении архитектуры JVM – несложный ассемблер для байт-кода Java.
Постановка задачи.
Требуется изучить архитектуру уровня команд платформы Java, формат файла класса Java, и написать компилятор ассемблероподобного языка, позволяющего создавать файлы классов, корректно обрабатываемые реальной JVM. Данный компилятор должен поддерживать все команды байт-кода Java и важнейшие возможности JVM.
Формат файла класса.
Основным форматом исполняемых файлов в архитектуре Java является формат файла класса, описанный в The JavaTM Virtual Machine Specification, изданной компанией Sun. Файл данного формата имеет имя, совпадающее с идентификатором класса (за исключением вложенных классов) и расширение .class.
Структура файла класса.
Файл класса имеет следующую структуру:
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];
}
(здесь и далее u1, u2, u4 – целые числа размером 8, 16 и 32 бит с порядком байтов старший байт по младшему адресу). Рассмотрим последовательно все поля.
-
magic – так называемое магическое число, имеющее в шестнадцатеричной записи вид 0xCAFEBABE;
-
minor_version, major_version – версия формата файла, по ней определяется совместимость данного файла с конкретной версией JVM;
-
constant_pool_count – количество элементов в Constant_pool плюс единица;
-
constant_pool – область констант – массив структур переменного размера, представляющих те или иные константные значения. Обращения в область констант производятся по индексу (индексация начинается с единицы; индексы, следующие за позициями констант, представляющих числа типов long и double, не используются). Форматы констант различных видов будут рассмотрены ниже;
-
access_flags – комбинация битовых флагов, определяющих права доступа и некоторые другие характеристики класса:
Флаг | Значение | Смысл |
ACC_PUBLIC | 0x0001 | Доступен из-за пределов пакета |
ACC_FINAL | 0x0010 | Запрещено наследование от данного класса |
ACC_SUPER | 0x0020 | В методах данного класса требуется использовать принятую в Java2 трактовку команды invokespecial |
ACC_INTERFACE | 0x0200 | Интерфейс (является классом специального вида) |
ACC_ABSTRACT | 0x0400 | Абстрактный класс |
-
this_class, super_class – индексы структур в области констант, ссылающихся на данный класс и его класс-предок;
-
interfaces_count – число интерфейсов, реализуемых данным классом;
-
interfaces – массив индексов структур в области констант, ссылающихся на интерфейсы, реализуемые данным классом;
-
fields_count – количество полей в данном классе;
-
fields – массив структур field_info, описывающих поля класса. Формат структуры field_info будет рассмотрен ниже;
-
methods_count – количество методов;
-
methods – массив структур method_info, описывающих методы класса. Формат структуры mettho_info будет рассмотрен ниже. Конструкторы и статические инициализаторы представляются методами со специальными именами
и ; -
attributes_count – количество атрибутов класса;
-
attributes – массив структур-атрибутов класса (поля, методы и байт-код методов также могут иметь свои атрибуты). Каждая такая структура в начале имеет два обязательных поля, описывающих тип атрибута и его размер. К классу могут быть применены следующие стандартные атрибуты: SourceFile – указывает на файл исходного текста, из которого был получен данный файл класса, и Deprecated – класс оставлен для совместимости со старым кодом и его использование не рекомендуется. Возможно создание атрибутов нестандартных типов, но они будут игнорироваться средой выполнения.
Типы элементов Constant_pool
Каждый элемент сonstant_pool начинается с однобайтного поля, определяющего его тип. Размер и содержание остальной части структуры зависит от типа. Существуют следующие типы констант (элементов constant_pool):
-
CONSTANT_Class – указывает на класс. Содержит индекс константы типа CONSTANT_Utf8, хранящей дескриптор класса;
-
CONSTANT _Fieldref – указывает на поле класса. Содержит индексы констант типа CONSTANT_Class и CONSTANT_NameAndType;
-
CONSTANT _Methodref указывает на метод класса (не интерфейса). Содержит индексы констант типа CONSTANT_Class и CONSTANT_NameAndType;
-
CONSTANT _InterfaceMethodref указывает на метод интерфейса. Содержит индексы констант типа CONSTANT_Class и CONSTANT_NameAndType;
-
CONSTANT_String – указывает на строку, содержит индекс константы типа CONSTANT_Utf8;
-
CONSTANT_Integer – содержит целое 32-разрядное число;
-
CONSTANT_Float – содержит вещественное число одинарной точности;
-
CONSTANT_Long – содержит целое 64-разрядное число;
-
CONSTANT_Double – содержит вещественное число двойной точности;
-
CONSTANT_NameAndType – описывает сигнатуру и имя метода либо тип и имя поля. Содержит индексы двух констант типа CONSTANT_Utf8, хранящих соответственно имя и дескриптор типа (сигнатуры);
-
CONSTANT_Utf8 – содержит строку в формате Utf8 (символы Unicode представляются комбинациями от 1 до 3-х байт, причем символы с кодами, не превышающими 127, представляются одним байтом).
Дескрипторы – это строки, описывающие типы и сигнатуры методов в компактном формате. Примитивные типы обозначаются одной буквой, типы массивов – открывающими квадратными скобками в количестве, равном размерности массива, перед обозначением базового типа. Классы описываются строкой, содержащей имя класса с полным путем, при этом вместо точки роль разделителя имен пакетов и класса выполняет слэш. В дескрипторах сигнатур методов в круглых скобках без разделителей перечисляются дескрипторы типов параметров; после закрывающей скобки находится дескриптор типа возвращаемого значения. Для устранения неоднозначностей при этом перед дескрипторами классов записывается буква L, а после них – точка с запятой. Например, (ILjava/lang/Object;)I – (int, Object):int (буквой I обозначается тип int).
Формат структуры field_info
Структура field_info имеет следующий формат:
field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
Здесь:
-
access_flags - комбинация битовых флагов, определяющих права доступа и некоторые другие характерист ики поля:
Имя флага
Значение
Смысл
ACC_PUBLIC
0x0001
Поле объявлено как public
ACC_PRIVATE
0x0002
Поле объявлено как private
ACC_PROTECTED
0x0004
Поле объявлено как protected
ACC_STATIC
0x0008
Поле является статическим
ACC_FINAL
0x0010
Поле объявлено как final и не может быть изменено после начальной инициализации
ACC_VOLATILE
0x0040
Поле объявлено как volatile
ACC_TRANSIENT
0x0080
Поле объявлено как transient – не сохранятся при сериализации
-
name_index – индекс строковой константы-имени поля в Constant Pool;
-
descriptor_index – индекс строковой константы-дескриптора поля (описывает тип) в Constant Pool;
-
attributes_count – число атрибутов поля;
-
attributes – атрибуты поля. К полям могут быть применены стандартные атрибуты Deprecated (см. выше), Synthetic (поле создано компилятором и не объявлено явно в исходном тексте) и ConstantValue (инициализирующее значение для статического поля).
Формат структуры method_info
Структура method_info имеет следующий формат:
method_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
Здесь:
-
access_flags – битовые флаги, определяющие права доступа и некоторые дополнительные свойства метода:
Flag Name | Value | Interpretation |
ACC_PUBLIC | 0x0001 | Метод объявлен как public |
ACC_PRIVATE | 0x0002 | Метод объявлен как private |
ACC_PROTECTED | 0x0004 | Метод объявлен как protected |
ACC_STATIC | 0x0008 | Метод является статическим |
ACC_FINAL | 0x0010 | Метод является финальным и не может быть замещен |
ACC_SYNCHRONIZED | 0x0020 | Метод объявлен как synchronized |
ACC_NATIVE | 0x0100 | Метод является «родным» и содержит код, непосредственно выполняющийся физическим процессором |
ACC_ABSTRACT | 0x0400 | Метод является абстрактным |
ACC_STRICT | 0x0800 | Устанавливает «строгий» режим работы с вещественными числами (только в Java 2). |
-
name_index, descriptor_index, attributes_count – аналогично field_info;
-
attributes – атрибуты метода. Методы могут иметь следующие стандартные атрибуты:
-
Deprecated, Synthetic – аналогично соответствующим атрибутам полей;
-
Exceptions – описание исключений, которые может генерировать метод. Нужно отметить, что обязательное описание исключений не является необходимым требованием для корректного выполнения;
-
Code – собственно говоря, байт-код метода.
-
Формат атрибута Code.
Атрибут Code имеет следующую структуру:
Code_attribute {