Смекни!
smekni.com

Ассемблер для платформы Java (стр. 3 из 6)

· i - int (также byte, short, char и boolean),

· l - long,

· f - float,

· d - double,

· a - ссылка на объект или массив.

Кроме того, есть несколько команд, работающих с типами char, byte и short.

Можно выделить несколько групп команд по назначению:

· команды загрузки и сохранения:

o Загрузка локальной переменной на стек: iload, iload_<n>, lload, lload_<n>, fload, fload_<n>, dload, dload_<n>, aload, aload_<n>;

o Сохранение значения с вершины стека в локальной переменной: istore, istore_<n>, lstore, lstore_<n>, fstore, fstore_<n>, dstore, dstore_<n>, astore, astore_<n>;

o Загрузкаконстантнастек: istore, istore_<n>, lstore, lstore_<n>, fstore, fstore_<n>, dstore, dstore_<n>, astore, astore_<n>;

· арифметические и логические команды:

o сложение: iadd, ladd, fadd, dadd;

o вычитание: isub, lsub, fsub, dsub;

o умножение: imul, lmul, fmul, dmul;

o деление: idiv, ldiv, fdiv, ddiv;

o остаток: irem, lrem, frem, drem;

o изменение знака: ineg, lneg, fneg, dneg;

o сдвиги и побитовые операции: ior, lor, iand, land, ixor, lxor, ishl, ishr, iushr, lshl, lshr, lush;

o сравнение: dcmpg, dcmpl, fcmpg, fcmpl, lcmg;

o инкремент локальной переменной: iinc.

Все эти команды, за исключением iinc, не имеют параметров. Они извлекают операнды с вершины стека и записывают результат на вершину стека. Команда iincимеет два операнда - индекс локальной переменной и величину, на которую значение данной переменной должно быть изменено;

· команды преобразования типов:

o расширяющее: i2l, i2f, i2d, l2f, l2d, f2d;

o сужающее: i2b, i2c, i2s, l2i, f2i, f2l, d2i, d2l, d2f;

· команды работы с объектами и массивами:

o создание объекта: new;

o создание массива: newarray(примитивного типа), anewarray (ссылочного типа), multianewarray(многомерного);

o доступ к полям: getfield, putfield(для полей экземпляра), getstatic, putstatic (для статических полей);

o загрузка элемента массива на стек: baload(тип byte), caload (тип char), saload(тип short), iaload, laload, faload, daload, aaload;

o сохранение значения с вершины стека в элемент массива: bastore, castore, sastore, iastore, lastore, fastore, dastore, aastore;

o получение размера массива: arraylength;

o проверка типов: instanceof(возвращает на вершине стека логическое значение) и checkcast (генерирует исключение в случае несоответствия типа ссылки на вершине стека требуемому типу);

· команды манипуляций со стеком операндов:

o pop - удаление верхнего элемент стека;

o pop2 - удаление двух верхних элемента стека;

o dup, dup2, dup_x1, dup2_x1, dup_x2, dup2_x2 - дублирование элементов на вершине стека;

o swap - перемена местами двух верхних элементов стека;

· команды безусловной передачи управления:

o jsr, jsr_w, ret - вызов подпрограмм и возврат из них. Используются при компиляции блока finally;

o goto, goto_w- безусловный переход;

· команды условного перехода:ifeq, iflt, ifle, ifne, ifgt, ifge, ifnull, ifnonnull, if_icmpeq, if_icmpne, if_icmplt, if_icmpgt, if_icmple, if_icmpge, if_acmpeq, if_acmpne;

· команды вызова методов:

o invokevirtual - обычный вызов метода экземпляра с использованием механизма позднего связывания;

o invokestatic - вызов статического метода;

o invokeinterface - вызов метода интерфейса у объекта, реализующего данный интерфейс;

o invokespecial - вызов метода экземпляра без использования механизма позднего связывания. Используется для вызова конструкторов, методов суперкласса и private-методов;

· команды возврата из метода:

o return - возврат из метода, возвращающего void;

o ireturn, lreturn, freturn, dreturn, areturn - возврат значения соответствующего типа;

· команда генерации исключений: athrow;

· команды синхронизации (механизм блокировок):

o monitorenter- установить блокировку (войти в критическую секцию);

o monitorexit - освободить блокировку (выйти из критической секции).

Синтаксис языка ассемблера для платформы Java (языка JASM).

Файл исходного текста на языке ассемблера для платформы Java (языке JASM) представляет собой текстовый файл, строки которого разделены последовательностью символов с кодами 13 и 10. Имя файла исходного текста и его расширение могут быть любыми, однако рекомендуется, чтобы имя совпадало с именем описанного в файле класса, а расширением было .jasm либо .jsm. Файл исходного текста состоит из предложений, разделенных точкой с запятой. Последнее предложение может не иметь в конце точки с запятой. Комментарии отделяются знаком процента и распространяются до конца строки. Точки с запятой и знаки процента внутри строковых констант, ограниченных двойными кавычками, не имеют своего специального значения. Две идущие подряд двойные кавычки внутри строковой константы интерпретируются как одна двойная кавычка в строке. Любые последовательности пробельных символов (пробелов, табуляций, переводов строки и т. д.) интерпретируются как один пробел, если с обеих сторон от них находятся символы следующих видов: буквы латинского алфавита, цифры, знак подчеркивания, либо, в противном случае, игнорируются. Исключение составляют пробельные символы в строковых константах и комментариях. Верхний и нижний регистр букв в идентификаторах, именах команд и других лексемах различается.

Каждый файл исходного текста компилируется в один файл класса. Файл исходного текста должен иметь следующую структуру:

[модификаторы_доступа] {class|interface} <имя_класса>;

[extends <базовый класс>;]

[implements <интерфейс_1>, <интерфейс_2>, ... , <интерфейс_n>;]

[fields;

<описания_полей>

]

[methods;

<описания_методов>

]

Здесь и далее в квадратные скобки заключены необязательные элементы, в фигурные - альтернативные варианты (разделены вертикальной чертой), в угловые - нетерминальные символы.

Модификаторы_доступа - это слова public, final, abstract, super, соответствующие флагам прав доступа ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_STATIC. Эти флаги устанавливаются в единицу тогда и только тогда, когда в объявлении класса присутствует соответствующее ключевое слово. Класс может иметь несколько различных модификаторов доступа, разделенных пробелом (или любой другой последовательностью пробельных символов). Повторение одинаковых модификаторов в заголовке одного класса не допускается. Когда класс не имеет флага ACC_INTERFACE, в его объявлении используется слово class, иначе используется ключевое слово interface. Все имена классов и интерфейсов записываются с указанием полного пути (пакетов, в которых эти классы содержатся). Имена пакетов и класса отделяются точкой, например, java.lang.String. В аргументах команд, там, где это необходимо, вместо полного имени текущего класса можно использовать символ «@». Если базовый класс не указан (предложение extendsотсутствует), то по умолчанию используется java.lang.Object. Интерфейсы - предки описываемого интерфейса записываются в секции implements.

Для идентификаторов - имен пакетов, классов, полей и методов, а также меток, используются следующие правила: они должны состоять из букв латинского алфавита любого регистра (регистр имеет значение), знаков подчеркивания и цифр, причем не должны начинаться с цифры. Настоятельно не рекомендуется использование идентификаторов, совпадающих с ключевыми словами языка Java, что может привести к некорректной компиляции, либо интерпретации файлов классов JVM. Два специальных имени <init> и <clinit> также рассматриваются как идентификаторы.

Простейший пример описания класса, не имеющего полей и методов:

public abstract class some_package.SomeClass;

% это комментарий

extends

some_package.nested_package1.BaseClass;

implements % и это комментарий

some_package.Interface1, some_package.nested_package2.Interface2;

Описание поля имеет следующий вид:

[модификаторы_доступа] <имя_поля>:<тип_поля> [=<начальное значение>];

Здесь модификаторы_доступа - следующие слова: public, protected, private, final, static, transient, volatile, соответствующие флагам доступа поля ACC_PUBLIC, ACC_PROTECTED, ACC_PRIVATE, ACC_FINAL, ACC_STATIC, ACC_TRANSIENT, ACC_VOLATILE. Повторение одинаковых модификаторов доступа в объявлении одного поля и сочетания модификаторов, соответствующие запрещенным сочетаниям флагов доступа (см. The Java Virtual Machine Specification), вызываютошибкувременикомпиляции. Поля интерфейса обязательно должны быть объявлены с модификаторами public, static и final. Имя_поля - корректный идентификатор. Тип_поля - имя класса либо имя примитивного типа (имена примитивных типов совпадают с соответствующими ключевыми словами языка Java - byte, short, int, long, char, float, double, boolean). Начальное значение может быть задано только для статического поля, если оно указано, то у поля создается атрибут ConstantValue. Начальное значение может быть целочисленной, вещественной, логической либо символьной константой для полей соответствующих типов. Вещественная константа может быть записана в десятичной либо экспоненциальной форме, в формате вещественных чисел, принятом в Java. Символьные константы заключаются в апострофы. Кроме того, может быть указан код символа как обычное целое число. Логические константы записываются в виде слов trueи false. Примеры описаний полей:

public final static COUNT:int = 10;

static c:char = ‘A’;

static c1:char = 13;

private volatile m_flag:boolean;

protected m_list:java.util.ArrayList;

Описание метода в общем случае имеет вид: