ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 24.12.2021

Просмотров: 12181

Скачиваний: 10

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

3 9 8

 Глава 5. Уровень архитектуры команд

Таблица 5.9.

 Некоторые моделируемые команды UltraSPARC II

Команда Как получить команду

MOV SRC, DST Выполнить команду OR над SRC и GO и сохранить результат в DST
CMP SRC1, SRC2 Вычесть SRC2 из SRC1 (команда SUBCC) и сохранить результат в GO

TST SRC Выполнить команду ORCC над SRC и GO и сохранить результат в GO

NOT DST Выполнить команду XNOR над DST и GO
NEG DST Вычесть SRC2 из SRC1 (команда SUBCC) и сохранить результат в GO
INC DST Прибавить 1 к DST (непосредственный операнд) — команда ADD
DEC DST Отнять 1 от DST (непосредственный операнд) — команда SUB

CLR DST Выполнить команду OR над GO и GO и сохранить результат в DST

NOP SETHI GO на О
RET JMPL%l7+8, %G0

JVM содержит относительно небольшой набор простых команд. Набор всех

команд JVM (за исключением некоторых расширенных, коротких и быстрых ва-
риантов команд) приведен на рис. 5.23.

Команды JVM типизированы. Одну и ту же операцию с разными типами дан-

ных выполняют разные команды. Например, команда ILOAD помещает в стек целое
32-битное число, а команда ALOAD помещает в стек 32-битный указатель. Такое стро-

гое разделение необязательно для правильного выполнения программы, посколь-
ку в обоих случаях 32 бита, которые находятся в определенной ячейке памяти,
передаются в стек независимо от типа этого 32-битного слова. Такое жесткое
разграничение типов требуется для того, чтобы можно было проверить во время
выполнения программы, не нарушены ли какие-нибудь ограничения (например,
не пытается ли программа превратить целое число в указатель, чтобы обратиться
к памяти).

Перейдем к командам JVM. Первая команда в списке — typeLOAD IND8.
На самом деле это не одна команда, а шаблон для порождения команд. Коман-

ды JVM регулярны, поэтому вместо того чтобы приводить все команды по одной,

в некоторых случаях мы будем давать правило для порождения команд. В данном
случае слово type заменяет одну из четырех букв: I, L, F и D, которые соответству-
ют типам integer (целые числа), long, float (32-битные числа с плавающей точкой)
и double (64-битные числа с плавающей точкой) соответственно. Следовательно,

здесь подразумевается 4 команды (ILOAD, LLOAD, FLOAD и DLOAD), каждая из которых
содержит 8-битный индекс IND8 для нахождения локальной переменной и поме-
щает в стек значение соответствующей длины и типа. Мы рассматривали только

одну из этих команд — ILOAD, но остальные действуют точно так же и отличаются
только по числу слов, помещаемых в стек, и по типу значения.

Кроме этих четырех команд существует еще четыре команды загрузки typeALOAD.

Эти команды помещают в стек элементы массива. Во всех четырех случаях снача-

ла в стек должен загружаться указатель на массив и индекс элемента массива.

Затем эти команды выталкивают индекс и указатель, производят вычисление,

чтобы найти элемент массива, и помещают этот элемент в стек. При вычислении

нужно знать размер элементов, который определяется по типу. Эти команды по-

лучают индекс массива из стека, поэтому сама команда не содержит операнда.


background image

Типы команд

399

ж

Команды загрузки

typeLOAD IND8

typeALOAD

BALOAD

SALOAD
CALOAD
AALOAD

Помещает локальную переменную в стек

Помещает элемент массива в стек

Помещает байт из массива в стек

Помещает short integer из массива в стек

Помещает символ из массива в стек

Помещает указатель из массива в стек

Команды сохранения

typeSTORE IND8

typeASTORE

BASTORE
SASTORE

CASTORE
AASTORE

Выталкивает из стека значение и сохраняет его в локальной переменной

Выталкивает из стека значение и сохраняет его в массиве

Выталкивает из стека байт и сохраняет его в массиве

Выталкивает из стека short и сохраняет его в массиве

Выталкивает из стека символ и сохраняет его в массиве

Выталкивает из стека указатель и сохраняет его в массиве

Команды помещения в стек

BIPUSH CON8

SIPUSHCON16

LDC IND8

typeCONST_*

ACONS_NULL

Помещает небольшую константу в стек

Помещает 16-битную константу в стек

Помещает в стек константу из набора констант

Помещает в стек непосредственную константу

Помещает в стек нулевой указатель

Арифметические команды

typeADD
typeSUB
typeMUL

typeDIV

typeREM
typeNEG

Сложение

Вычитание

Умножение

Деление

Остаток

Отрицание

Логические команды/команды сдвига

HAND

NOR

ilXOR

ilSHL

lISHR

ilUSHR

Логическое И

Логическое ИЛИ

Логическое ИСКЛЮЧАЮЩЕЕ ИЛИ

Сдвиг влево

Сдвиг вправо

Сдвиг вправо без знака

Команды преобразования

х2у

i2c
i2b

Преобразует х в у

Преобразует целое число в символ

Преобразует целое число в байт

Команды управления стеком

DUPxx

POP

РОР2

SWAP

Шесть команд дублирования

Выталкивает целое число из стека и отбрасывает его

Выталкивает два целых числа из стека и отбрасывает их

Меняет местами два верхних целых числа в стеке

Рис. 5.23.

 Набор  к о м а н д а м (начало)


background image

4 0 0

Глава 5. Уровень архитектуры команд

Команды сравнения

IF ICMPrel 0FFSET16

IF ACMPEQ 0FFSET16
IF ACMPNE0FFSET16

IFrel 0FFSET16

IFNULLOFFSET16

IFNONNULLOFFSET16

LCMP

FCMPL

FCMPG
DCMPL

DCMPG

Условный переход

Переход в случае равенства двух значений

Переход в случае неравенства двух значений

Проверяет одно значение и совершает переход

Совершает переход, если значение равно 0

Совершает переход, если значение не равно 0

Сравнивает два числа long

Сравнивает два числа с плавающей точкой на <
Сравнивает два числа с плавающей точкой на >

Сравнивает два числа типа double на <
Сравнивает два числа типа double на >

Команды передачи управления

и

INVOKEVIRTUAL IND16

INVOKESTATIC IND16

INVOKEINTRFACE

INVOKESPECIAL IND16

JSROFFSET16

tipeRETURN

ARETURN

RETURN

RET IND8

G0T0 0FFSET16

Вызов процедуры
Вызов процедуры
Вызов процедуры
Вызов процедуры
Вызов процедуры

Возвращает значение

Возвращает указатель

Возвращает пустой тип

Выход из процедуры

Безусловный переход

Операции с массивами

ANEWARRAYIND16

NEWARRAY ATYPE

MULTINEWARRAY 1N16, D

ARRAYLENGTH

Создает массив переменных

Создает массив из массивов

Создает многомерный массив

Выдает длину массива

Прочие команды

л

IINCIND8, CON16

WIDE

NOP

GETFIELDIND16
PUTFIELD IND16

GETSTATIC IND16

NEWIND16

INSTANCEOF 0FFSET16

CHECKCASTIND16

ATHROW

LOOKUPSWITCH...

TABLESWITCH...

MONITORENTER

MONITOREXIT

Увеличивает локальную переменную на 1

Префикс

Пустая операция

Считывает поле из объекта
Записывает слово в объект

Получает статическое поле из класса

Создает новый объект

Определяет тип объекта

Проверяет тип объекта
Обработка исключения

Разбросанные многоуровневые переходы

Компактные многоуровневые переходы

Входит в управляющую прграмму

Выходит из управляющей прграммы

IND

 8/16 = индекс

локальной переменной;

CON 8/16, D, ATYPE = константа;

type, х, у = I, L, F, D;

OFFSET 16 для команд перехода

Рис. 5.23.

 Набор команд JVM (окончание)


background image

Типы команд 401

Последние четыре команды этой группы также предназначены для работы с эле-

ментами массива, но только других типов. Они поддерживают byte (байт — 8 би-

тов), short (16 битов), char (символ — 16 битов) и pointer (указатель — 32 бита).

Таким образом, всего существует 12 команд LOAD.

Команды typeSTORE обратны командам typeLOAD. Каждая команда выталкивает

элемент из стека и сохраняет его в локальной переменной. Одну из этих команд

(ISTORE) мы уже рассматривали, когда изучали машину IJVM. Здесь также имеют-

ся команды для сохранения элементов массива. В вершине стека находится значе-
ние нужного типа. Под ним находится индекс, а еще ниже — указатель на массив.

Все три элемента удаляются из стека этой командой.

Команды PUSH помещают значение в стек. Команду ВI PUSH мы уже рассматрива-

ли. Команда SIPUSH выполняет ту же операцию, но только с 16-битным числом.
Команда LDC помещает в стек значение из набора констант. Следующая команда

представляет целую группу команд всех четырех основных типов (integer, long,

float и double). Каждая команда содержит только код операции, и каждый код опе-

рации помещает определенное значение в стек. Например, команда ICONST0 (код

операции 0x03) помещает в стек 32-битное слово 0. То же самое действие можно
произвести с помощью команды BIPUSH, но это займет два байта. Благодаря опти-

мизации самых распространенных команд программы JVM получаются неболь-
шими по размеру. Поддерживаются следующие значения: Integers (целые чис-

ла)  - 1 , 0, 1, 2, 3, 4, 5; longs 0 и 1; floats (числа с плавающей точкой) 0,0, 1,0 и 2,0 и

doubles 0,0 и 1,0. Команда CONST_NULL помещает в стек нулевой указатель. Сочета-

ние кодов операций и самых распространенных адресов в одной 1 -байтной коман-

де сильно сокращает размер команды, что экономит память и время на передачу

бинарных программ на языке Java по Интернету.

Арифметические операции абсолютно регулярны. Для каждого из основных

четырех типов имеется 4 команды. Три логические операции и три операции сдви-
га применяются только для целых чисел и чисел типа long. Наличие команды AND

для чисел с плавающей точкой противоречило бы строгим правилам типизирова-

ния JVM. Строка х2у в таблице представляет 4x4 команд преобразования. Значе-

ния каждого типа могут переделываться в любой другой тип (но только не в тот же
самый), поэтому здесь имеется 12 команд. Самой типичной из них является ко-
манда I2F, которая превращает целое число в число с плавающей точкой.

Группа команд управления стеком содержит команды, которые дублируют верх-

нее значение или два значения стека и помещают их в различные части стека (не
обязательно в вершину). Остальные команды выталкивают значения из стека и
меняют местами два верхних значения.

Команды группы сравнения выталкивают одно или два значения из стека и

проверяют их. Если из стека выталкивается два значения, то одно из них вычита-

ется из другого, а результат проверяется. Если выталкивается одно значение, то
оно и проверяется. Суффикс rel замещает реляционные операторы: LT, LE, EQ,
NE, GE и GT. Команды со смещением совершают переход, если определенное усло-

вие подтверждено. Остальные команды помещают результат обратно в стек.

Следующая группа предназначена для вызова процедур и возвращения зна-

чений. При изучении машины IJVM мы рассматривали очень простые версии ко-
манд INVOKEVIRTUAL и IRETURN. Полные версии содержат гораздо больше параметров,


background image

4 0 2 Глава 5. Уровень архитектуры команд

и существует множество команд, которые покрывают самые различные случаи.

В этой книге мы не будем описывать эти команды. Подробнее см. [85].

Еще одну группу образуют 4 команды для создания одномерных и многомер-

ных массивов и проверки их длины. В машине JVM массивы хранятся в «куче» и
периодически очищаются (процесс «сборки мусора»), когда они уже больше не
нужны.

Последняя группа включает в себя оставшиеся команды. Каждая из этих ко-

манд имеет специальное назначение, связанное с какой-нибудь особенностью языка

Java. Описание этих команд не входит в задачи этой книги.

А теперь нужно сказать пару слов о самом уровне команд picojava II. Это ма-

шина с обратным порядком байтов (хотя существует несколько команд, которые
можно переделать в формат с прямым порядком байтов). Слова состоят из 32 би-
тов, хотя существуют команды для работы с единицами по 8,16 и

 64

 бита. Стек

в памяти располагается от верхних адресов к нижним в отличие от IJVM (специ-
фикация JVM допускает оба варианта).

Машина picojava II была разработана для программ на Java, С и C++. Но чтобы

запустить программы на С и C++, нужен компилятор, который превращает С и

C++ в команды picojava И. После того как программа на С или C++ была скомпи-

лирована на JVM, все способы оптимизации аппаратного обеспечения, которые
мы описывали в главе 4, становятся применимы для С и C++.

Чтобы программы на С и C++ могли работать на машине picojava II, к уровню

архитектуры команд было добавлено 115 дополнительных команд. Большинство
из них составляют два или более байтов в длину и начинаются с одного из двух
зарезервированных кодов JVM (OxFE и OxFF), которые показывают, что дальше
следует расширенная команда. Ниже мы дадим краткий обзор особенностей
picojava II, не характерных для JVM.

В машине picojava II содержится 25 32-битных регистров. Четыре из них по

функциям эквивалентны регистрам PC, LV, SP и СРР машины IJVM. Регистр

OPLIM помещает определенное предельное значение в SP. Ести значение SP вы-

ходит за пределы OPLIM, то происходит прерывание. Эта особенность позволяет
представлять стек в виде связного списка участков стека, а не как один непрерыв-
ный блок памяти. Регистр FRAME отмечает конец фрейма локальных переменных
и указывает на слово, которое содержит счетчик команд вызывающей процедуры.

Среди других регистров можно назвать слово состояния программы — это ре-

гистр, который следит, насколько заполнен 64-регистровый стековый кэш, и четы-
ре регистра, которые используются для управления потоком. Кроме того, суще-
ствует 4 регистра для ловушек и прерываний и 4 регистра для вызова процедур и
возвращения значений в командах на языках С и C++. Поскольку picojava II не
имеет виртуальной памяти, для ограничения определенной части памяти, к которой
может иметь доступ текущая программа на С или C++, используются два специаль-
ных регистра. Расширенные команды можно разделить на 5 категорий. К первой
категории относятся команды для чтения и записи верхних регистров. Ко второй
категории относятся команды для работы с указателями. Они позволяют считы-
вать из памяти и записывать в память произвольные слова. Большинство из этих
команд выталкивают машинный адрес из стека, а затем помещают в стек содержи-