ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 14.01.2021
Просмотров: 161
Скачиваний: 1
Передача управления
BPcc ADDR |
Условный переход с прогнозированием |
BPr SRC, ADDR |
Условный переход по регистру |
CALL ADDR |
Вызов процедуры |
RETURN ADDR |
Выход из процедуры |
JMPL ADDR, DST |
Переход со связыванием |
SAVE R1, S2, DST |
Расширение регистровых окон |
RESTORE |
Восстановление регистровых окон |
Тсс СС, TRAP# |
Системное прерывание при определенном условии |
PREFETCH FNC |
Выборка данных из памяти с упреждением |
LDSTUB ADDR, R |
Атомарная операция загрузки/сохранения |
MEMBAR MASK |
Барьер памяти |
Прочие команды |
|
SETHI CON, DST |
Установка битов с 10 по 31 |
MOVcc CC, S2, DST |
Перемещение данных при определенном условии |
MOVr R1, S2, DST |
Перемещение в зависимости от значения регистра |
NOP |
Пустая операция |
POPC S1, DST |
Подсчет генеральной совокупности |
RDCCR V, DST |
Чтение регистра кода условия |
WRCCR R1, S2, V |
Запись регистра кода условия |
RDPC V, DST |
Чтение счетчика команд |
Обозначения:
SRC - входной регистр; DST - выходной регистр; R1 - входной регистр; S2 - регистр-источник или непосредственный операнд; ADDR - адрес памяти; R - выходной регистр;
TRAP# - номер системного прерывания; FCN - код функции; MASK - тип операции; CON - константа; V - указатель регистра;
СС - набор кодов условия;
cc - условие; r – условие.
Группа логических команд включает команды AND (И), OR (ИЛИ), XOR (ИСКЛЮЧАЮЩЕЕ ИЛИ), ANDN (НЕ-И), ORN (НЕ-ИЛИ) и XNOR (ИСКЛЮЧАЮЩЕЕ НЕ-ИЛИ). Полезность последних трех команд спорна, но они могут выполняться за один цикл и не требуют дополнительного аппаратного обеспечения, поэтому часто включаются в набор команд.
Следующая группа содержит команды передачи управления. ВРсс представляет собой набор команд, которые совершают переходы при различных условиях и содержат прогноз компилятора по поводу перехода. Команды ВРr проверяют регистр и совершает переход, если условие подтвердилось.
Предусмотрено два способа вызова процедур. Для команды CALL используется формат 4 (см. выше) с 30-битным смещением. Этого значения достаточно для того, чтобы достичь любой команды в пределах 2 Гбайт от вызывающего оператора в любом направлении. Команда CALL копирует адрес возврата в регистр R15, который после вызова превращается в регистр R31.
Второй способ вызова процедуры - команда JMPL (формат 1а или 1b), позволяющая помещать адрес возврата в произвольный регистр. Такая форма может быть полезной в случае, если адрес возврата вычисляется во время выполнения.
Команды SAVE и RESTORE манипулируют регистровым окном и указателем стека. Обе команды совершают прерывание, если следующее (предыдущее) окно недоступно.
В последней группе содержатся команды, которые не попали ни в одну из групп. Команда SETHI необходима при записи 32-битного непосредственного операнда в регистр. Для этого команда SETHI устанавливает биты с 10 по 31, а затем следующая команда должна передать оставшиеся биты, используя непосредственный формат.
Команда РОРС подсчитывает число установленных битов в слове. Последние три команды предназначены для чтения и записи специальных регистров.
Ряд распространенных CISC-команд, которых нет в этом списке, можно смоделировать RISC-командами. Для этого используются регистр G0 (=R0) либо операнд-константа (формат lb). Некоторые из них даны в следующей таблице. Эти команды распознаются ассемблером UltraSPARC II и часто порождаются компиляторами. Многие из них используют тот факт, что регистр G0 связан с 0, и запись в этот регистр не производит никакого результата.
CISC-команда RISC-реализация
MOV SRC, DST Выполнить OR над SRC и GO и сохранить результат в DST
CMP SRC1, SRC2 Вычесть SRC2 из SRC1 (SUBCC) и сохранить результат в G0
TST SRC Выполнить ORCC над SRC и GO и сохранить результат в G0
NOT DST Выполнить XNOR над DST и G0
NEG DST Вычесть SRC2 из SRC1 (SUBCC) и сохранить результат в G0
INC DST Прибавить 1 к DST (непосредственный операнд) - команда ADD
DEC DST Вычесть 1 из DST (непосредственный операнд) - команда SUB
CLR DST Выполнить OR над G0 и G0 и сохранить результат в DST
NOP SETHI G0 с 0
RET JMPL %I7+8, %G0 (% - обозн. регистра)
5.2.3. Команды компьютера picoJava II
В этом компьютере реализован полный набор команд JVM (226 команд), а также 115 дополнительных команд, предназначенных для С/C++ и операционной системы. Мы рассмотрим в основном команды JVM, компилятор Java производит только эти команды. Как уже говорилось, архитектура команд JVM не содержит регистров, доступных пользователю. Большинство команд JVM помещают слова в стек, оперируют ими и выталкивают слова из стека.
Большая часть команд выполняется аппаратным обеспечением picoJava II, но некоторые из них микропрограммируются, а некоторые передаются некоторой программе для выполнения. Таким образом, для полноценной работы JVM требуется небольшая система уровня команд, но она гораздо меньше по объему, чем интерпретатор JVM, и вызывается она только в редких случаях. Она содержит код для интерпретации нескольких сложных команд, загрузчик класса, верификатор байт-кода, администратор потока и программу чистки памяти (“сборщик мусора”).
Набор всех команд JVM за исключением некоторых расширенных, коротких и быстрых вариантов команд, приведен в нижеследующей таблице.
Команды JVM типизированы. Одну и ту же операцию с разными типами данных выполняют разные команды. Например, ILOAD помещает в стек целое 32-битное число, а ALOAD помещает в стек 32-битный указатель. Такое строгое разделение кажется избыточным, поскольку в обоих случаях в стек передаются 32 бита памяти. Оно требуется для того, чтобы во время выполнения программы можно было проверить, не нарушены ли какие-либо ограничения (например, не пытается ли программа превратить целое число в указатель, чтобы обратиться к памяти).
Перейдем к конкретным командам JVM. Первая из них - typeLOAD IND8.
Фактически это не одна команда, а шаблон для записи 4-х команд. Команды JVM регулярны, поэтому вместо перечисления всех команд в ряде случаев можно сообщать правило для порождения команд. В данном случае слово type означает одну из четырех букв - I, L, F и D, которые соответствуют типам int, long, float и double соответственно. Существуют еще четыре команды загрузки typeALOAD, которые помещают в стек элемент массива. Во всех случаях в стек загружаются указатель на массив и индекс его элемента. Затем эти команды выталкивают индекс и указатель, производят вычисление и помещают в стек сам элемент. Размер элементов определяется по типу. Эти команды получают индекс массива из стека, поэтому сама команда не содержит операнда.
Команды загрузки
typeLOAD IND8 |
Помещает локальную переменную в стек |
typeALOAD |
Помещает элемент массива в стек |
BALOAD |
Помещает байт из массива в стек |
SALOAD |
Помещает short integer из массива в стек |
CALOAD |
Помещает символ из массива в стек |
AALOAD |
Помещает указатель из массива в стек |
Команды сохранения
typeSTORE IND8 |
Выталкивает из стека значение и сохраняет его в локальной переменной |
typeASTORE |
Выталкивает из стека значение и сохраняет его в массиве |
BASTORE |
Выталкивает из стека байт и сохраняет его в массиве |
SASTORE |
Выталкивает из стека short и сохраняет его в массиве |
CASTORE |
Выталкивает из стека символ и сохраняет его в массиве |
AASTORE |
Выталкивает из стека указатель и сохраняет его в массиве |
Команды помещения в стек
BIPUSH CON8 |
Помещает небольшую константу в стек |
SIPUSHCON16 |
Помещает 16-битную константу в стек |
LDC IND8 |
Помещает в стек константу из набора констант |
typeCONST_* |
Помещает в стек непосредственную константу |
ACONS_NULL |
Помещает в стек нулевой указатель |
Арифметические команды
typeADD |
Сложение |
typeSUB |
Вычитание |
typeMUL |
Умножение |
typeDIV |
Деление |
typeREM |
Остаток |
typeNEG |
Отрицание |
Логические команды/команды сдвига
ilAND |
Логическое И |
ilOR |
Логическое ИЛИ |
ilXOR |
Логическое ИСКЛЮЧАЮЩЕЕ ИЛИ |
ilSHL |
Сдвиг влево |
ilSHR |
Сдвиг вправо |
ilUSHR |
Сдвиг вправо без знака |
Команды преобразования
х2у |
Преобразует х в у |
I2C |
Преобразует целое число в символ |
I2B |
Преобразует целое число в байт |
Команды управления стеком
DUPxx |
Шесть команд дублирования |
POP |
Выталкивает целое число из стека и отбрасывает его |
РОР2 |
Выталкивает два целых числа из стека и отбрасывает их |
SWAP |
Меняет местами два верхних целых числа в стеке |
Команды сравнения
IF_ICMPrel OFFSET16 |
Условный переход |
IF_ACMPEQ OFFSET16 |
Переход в случае равенства двух значений |
IF_ACMPNE OFFSET16 |
Переход в случае неравенства двух значений |
IFrel OFFSET16 |
Проверяет одно значение и совершает переход |
IFNULL OFFSET16 |
Совершает переход, если значение равно 0 |
IFNONNULL OFFSET16 |
Совершает переход, если значение не равно 0 |
LCMP |
Сравнивает два числа long |
FCMPL |
Сравнивает два числа с плавающей точкой на < |
FCMPG |
Сравнивает два числа с плавающей точкой на > |
DCMPL |
Сравнивает два числа типа double на < |
DCMPG |
Сравнивает два числа типа double на > |
Команды передачи управления |
|
INVOKEVIRTUAL IND16 |
Вызов процедуры |
INVOKESTATIC IND16 |
Вызов процедуры |
INVOKEINTRFACE |
Вызов процедуры |
INVOKESPECIAL IND16 |
Вызов процедуры |
JSR OFFSET16 |
Вызов процедуры |
typeRETURN |
Возвращает значение |
ARETURN |
Возвращает указатель |
RETURN |
Возвращает пустой тип |
RET IND8 |
Выход из процедуры |
GOTO OFFSET16 |
Безусловный переход |
Операции с массивами |
|
ANEWARRAY IND16 |
Создает массив переменных |
NEWARRAY ATYPE |
Создает массив из массивов |
MULTINEWARRAY IN16, D |
Создает многомерный массив |
ARRAYLENGTH |
Выдает длину массива |
Прочие команды |
|
IINC IND8, CON16 |
Увеличивает локальную переменную |
WIDE |
Префикс |
NOP |
Пустая операция |
GETFIELD IND16 |
Считывает поле из объекта |
PUTFIELD IND16 |
Записывает слово в объект |
GETSTATIC IND16 |
Получает статическое поле из класса |
NEW IND16 |
Создает новый объект |
INSTANCEOF OFFSET16 |
Определяет тип объекта |
CHECKCAST IND16 |
Проверяет тип объекта |
ATHROW |
Обработка исключения |
LOOKUPSWITCH... |
Разбросанные многоуровневые переходы |
TABLESWITCH... |
Компактные многоуровневые переходы |
MONITORENTER |
Входит в управляющую прграмму |
MONITOREXIT |
Выходит из управляющей прграммы |
Обозначения:
IND8/16 – индекс локальной переменной;
CON8/16, D, ATYPE = константа;
type, х, у - I, L, F, D;
OFFSET16 – смещение для команд перехода.
Последние четыре команды этой группы также предназначены для работы с элементами массива, но только специализированных типов. Они поддерживают byte, short (16 битов), char (символ - 16 битов) и pointer (указатель - 32 бита).
Команды typeSTORE обратны командам typeLOAD. Каждая команда выталкивает элемент из стека и сохраняет его в локальной переменной. Здесь также имеются команды для работы с элементами массива - typeASTORE. В вершине стека расположено значение нужного типа, под ним находится индекс, а еще ниже - указатель на массив (?). Все три элемента удаляются из стека этой командой.
Команды PUSH помещают значение в стек. Команда LDC записывает в стек значение из таблицы констант. Следующая команда представляет целую группу команд всех четырех основных типов (int, long, float и double). Каждая команда содержит только код операции, и каждый из них помещает в стек определенное значение. Например, ICONST_0 вталкивает в стек 32-битное слово 0. То же самое действие можно произвести с помощью команды BIPUSH, но это займет два байта. Благодаря оптимизации самых распространенных команд программы JVM получаются небольшими по размеру. Поддерживаются следующие значения: int (-1, 0, 1, 2, 3, 4, 5); long (0, 1); float (0.0, 1.0, 2.0) и double (0.0, 1.0). Команда CONST_NULL помещает в стек нулевой указатель.
Для каждого из основных четырех типов имеется 4 арифметические команды. Три логические операции и три операции сдвига применяются только для целых чисел и чисел типа long. Шаблон х2у в таблице представляет 4x4 команд преобразования. Значения каждого типа могут преобразовываться в любой другой тип, кроме того же самого, поэтому здесь имеется 12 команд. Наиболее типичной из них является I2F, которая преобразует целое число в число с плавающей точкой.
Группа команд управления стеком содержит команды, которые копируют верхние одно или два значения стека в различные части стека (не обязательно в вершину). Остальные команды выталкивают значения из стека или меняют местами два верхних значения.
Команды группы сравнения выталкивают одно или два значения из стека и проверяют их. Если из стека выталкивается два значения, то одно из них вычитается из другого, а результат проверяется. Если выталкивается одно значение, то оно и проверяется. Суффикс rel замещает реляционные операторы: LT, LE, EQ, NE, GE и GT. Команды со смещением совершают переход, если определенное условие выполнено. Остальные команды помещают результат обратно в стек.
Следующая группа предназначена для вызова процедур и возврата значений. Они охватывают много вариантов и имеют различные параметры. Их изучение не входит в программу нашего обзора.
Еще одну группу образуют 4 команды для создания одномерных и многомерных массивов и проверки их длины. В JVM массивы хранятся в “куче” и периодически освобождаются (“сборка мусора”), когда они уже больше не нужны.
Последняя группа включает оставшиеся команды. Каждая из них команд имеет специальное назначение, связанное с какой-дибо особенностью языка Java. Описание этих команд также не входит в задачи нашего курса.
Машина picoJava II была разработана не только для программ на Java, но и для С/C++. Чтобы запускать программы на С и C++, нужен соответствующий компилятор. Кроме того, для поддержки этих возможностей к уровню архитектуры команд было добавлено 115 команд. Большинство из них занимает два или более байтов и начинается с одного из двух зарезервированных кодов JVM (0xFE и 0xFF). Программы, использующие эти дополнительные команды, не переносимы на другие машины JVM.