Общий дизайн
- Модель машины и соглашения о вызовах предназначены для приблизительной имитации общих реальных архитектур и соглашений о вызовах в стиле C:
- Машина основана на регистрах, а размеры кадров фиксируются при создании. Каждый кадр состоит из определенного количества регистров (указанного методом), а также любых дополнительных данных, необходимых для выполнения метода, таких как (но не ограничиваясь ими) программный счетчик и ссылка на файл
.dex
, содержащий метод. . - При использовании для битовых значений (таких как целые числа и числа с плавающей запятой) регистры считаются 32-битными. Смежные пары регистров используются для 64-битных значений. Для пар регистров не требуется выравнивания.
- При использовании для ссылок на объекты регистры считаются достаточно широкими, чтобы содержать ровно одну такую ссылку.
- С точки зрения побитового представления
(Object) null == (int) 0
. - N аргументов метода помещаются в последние N регистров кадра вызова метода по порядку. Широкие аргументы занимают два регистра. Методы экземпляра передаются по ссылке
this
в качестве первого аргумента.
- Машина основана на регистрах, а размеры кадров фиксируются при создании. Каждый кадр состоит из определенного количества регистров (указанного методом), а также любых дополнительных данных, необходимых для выполнения метода, таких как (но не ограничиваясь ими) программный счетчик и ссылка на файл
- Единицей памяти в потоке команд является 16-битная беззнаковая величина. Некоторые биты в некоторых инструкциях игнорируются/должны быть равны нулю.
- Инструкции не ограничиваются безвозмездно определенным типом. Например, инструкции, которые перемещают 32-битные значения регистров без интерпретации, не должны указывать, перемещают ли они целые числа или числа с плавающей запятой.
- Существуют отдельно перечисляемые и индексируемые пулы констант для ссылок на строки, типы, поля и методы.
- Побитовые литеральные данные представлены в потоке инструкций.
- Поскольку на практике для метода редко требуется более 16 регистров, а потребность в более чем восьми регистрах достаточно распространена, многие инструкции ограничиваются адресацией только первых 16 регистров. Когда это разумно возможно, инструкции позволяют обращаться к первым 256 регистрам. Кроме того, у некоторых инструкций есть варианты, которые позволяют использовать гораздо большее количество регистров, включая пару универсальных инструкций
move
, которые могут обращаться к регистрам в диапазоне отv0
v65535
. В тех случаях, когда вариант инструкции недоступен для обращения к нужному регистру, ожидается, что содержимое регистра будет перемещено из исходного регистра в младший регистр (перед операцией) и/или перемещено из младшего результирующего регистра в старший. зарегистрироваться (после операции). - Существует несколько «псевдоинструкций», которые используются для хранения полезных данных переменной длины, на которые ссылаются обычные инструкции (например,
fill-array-data
). Такие инструкции никогда не должны встречаться во время нормального потока выполнения. Кроме того, инструкции должны располагаться по четным смещениям байт-кода (то есть выровнены по 4 байтам). Чтобы выполнить это требование, инструменты генерации dex должны генерировать дополнительную инструкциюnop
в качестве разделителя, если в противном случае такая инструкция была бы невыровненной. Наконец, хотя это и не обязательно, ожидается, что большинство инструментов предпочтут генерировать эти инструкции в конце методов, поскольку в противном случае, скорее всего, потребуются дополнительные инструкции для ветвления вокруг них. - При установке в работающей системе некоторые инструкции могут быть изменены, изменив их формат, в качестве оптимизации статической компоновки во время установки. Это сделано для того, чтобы обеспечить более быстрое выполнение после того, как связь известна. Предлагаемые варианты см. в соответствующем документе форматов инструкций . Слово «предложил» использовано преднамеренно; их выполнение не является обязательным.
- Человеческий синтаксис и мнемоника:
- Заказ аргументов по принципу "назначение, затем источник".
- Некоторые коды операций имеют суффикс имени, устраняющий неоднозначность, чтобы указать тип (ы), с которыми они работают:
- 32-битные коды операций общего типа не помечены.
- 64-битные коды операций общего типа имеют суффикс
-wide
. - Коды операций, зависящие от типа, имеют суффикс их типа (или прямую аббревиатуру), один из:
-boolean
-byte
-char
-short
-int
-long
-float
-double
-object
-string
-class
-void
- Некоторые коды операций имеют суффикс, устраняющий неоднозначность, чтобы различать в остальном идентичные операции, которые имеют разные макеты инструкций или параметры. Эти суффиксы отделяются от основных имен косой чертой ("
/
") и в основном вообще существуют для того, чтобы было взаимно-однозначное сопоставление со статическими константами в коде, генерирующем и интерпретирующем исполняемые файлы (то есть для уменьшения неоднозначности для человека). - В описаниях здесь ширина значения (указывающая, например, диапазон константы или количество регистров, которые могут быть адресованы) подчеркивается использованием символа на четыре бита ширины.
- Например, в инструкции "
move-wide/from16 vAA, vBBBB
":- "
move
" - это базовый код операции, указывающий на базовую операцию (перемещение значения регистра). - «
wide
» — это суффикс имени, указывающий, что он работает с широкими (64-битными) данными. - "
from16
" — это суффикс кода операции, указывающий на вариант, который имеет 16-битную ссылку на регистр в качестве источника. - «
vAA
» — это регистр назначения (подразумеваемый операцией; опять же, правило состоит в том, что аргументы назначения всегда идут первыми), который должен находиться в диапазонеv0
—v255
. - «
vBBBB
» — исходный регистр, который должен находиться в диапазоне отv0
v65535
.
- "
- См. документ форматов инструкций для получения более подробной информации о различных форматах инструкций (перечисленных в разделе «Операция и формат»), а также сведения о синтаксисе кода операции.
- См. документ о формате файла
.dex
для получения более подробной информации о том, как байт-код вписывается в общую картину.
Сводка по набору байткодов
Оп и формат | Мнемоника/Синтаксис | Аргументы | Описание |
---|---|---|---|
00 10x | нет | Циклы отходов. Примечание. Псевдоинструкции, несущие данные, помечаются этим кодом операции, и в этом случае старший байт единицы кода операции указывает характер данных. См. «Формат | |
01 12x | двигаться vA, vB | A: регистр назначения (4 бита)B: исходный регистр (4 бита) | Переместите содержимое одного необъектного регистра в другой. |
02 22x | двигаться/из16 vAA, vBBBB | A: регистр назначения (8 бит)B: исходный регистр (16 бит) | Переместите содержимое одного необъектного регистра в другой. |
03 32x | ход/16 vAAAA, vBBBB | A: регистр назначения (16 бит)B: исходный регистр (16 бит) | Переместите содержимое одного необъектного регистра в другой. |
04 12x | широкий ход vA, vB | A: пара регистров назначения (4 бита)B: пара исходных регистров (4 бита) | Переместить содержимое одной пары регистров в другую. Примечание. Разрешен переход от |
05 22x | широкий ход/от16 vAA, vBBBB | A: пара регистров назначения (8 бит)B: пара исходных регистров (16 бит) | Переместить содержимое одной пары регистров в другую. Примечание. Рекомендации по реализации такие же, как и для |
06 32x | широкий ход/16 vAAAA, vBBBB | A: пара регистров назначения (16 бит)B: пара исходных регистров (16 бит) | Переместить содержимое одной пары регистров в другую. Примечание. Рекомендации по реализации такие же, как и для |
07 12x | переместить объект vA, vB | A: регистр назначения (4 бита)B: исходный регистр (4 бита) | Переместить содержимое одного объектного регистра в другой. |
08 22x | переместить объект/от16 vAA, vBBBB | A: регистр назначения (8 бит)B: исходный регистр (16 бит) | Переместить содержимое одного объектного регистра в другой. |
09 32x | переместить объект/16 vAAAA, vBBBB | A: регистр назначения (16 бит)B: исходный регистр (16 бит) | Переместить содержимое одного объектного регистра в другой. |
0а 11х | ход-результат vAA | A: регистр назначения (8 бит) | Переместите однословный необъектный результат самого последнего invoke- kind в указанный регистр. Это должно быть сделано в виде инструкции сразу после invoke- kind , чей результат (одно слово, не объект) не должен игнорироваться; где-либо еще является недействительным. |
0b 11x | vAA для всего результата перемещения | A: пара регистров назначения (8 бит) | Переместите двойное слово результата самого последнего invoke- kind в указанную пару регистров. Это должно быть сделано как инструкция сразу после invoke- kind , результат которого (двойное слово) не должен игнорироваться; где-либо еще является недействительным. |
0с 11х | объект-результат перемещения vAA | A: регистр назначения (8 бит) | Переместите результат объекта самого последнего invoke- kind в указанный регистр. Это должно быть сделано как инструкция сразу после invoke- kind или filled-new-array , чей результат (объект) не должен игнорироваться; где-либо еще является недействительным. |
0д 11х | движение-исключение vAA | A: регистр назначения (8 бит) | Сохранить только что перехваченное исключение в указанный регистр. Это должна быть первая инструкция любого обработчика исключений, чье пойманное исключение не должно игнорироваться, и эта инструкция должна когда-либо появляться только как первая инструкция обработчика исключений; где-либо еще является недействительным. |
0e 10x | возврат-недействительность | Возврат из метода void . | |
0f 11x | вернуть vAA | A: регистр возвращаемого значения (8 бит) | Возврат из метода одинарной ширины (32-разрядного) без объекта, возвращающего значение. |
10 11x | vAA для всего возврата | A: возвращаемое значение регистр-пара (8 бит) | Возврат из метода, возвращающего значение двойной ширины (64 бита). |
11 11x | возвращаемый объект vAA | A: регистр возвращаемого значения (8 бит) | Возврат из метода, возвращающего объект. |
12 11н | const/4 vA, #+B | A: регистр назначения (4 бита)B: целое число со знаком (4 бита) | Переместите заданное литеральное значение (расширенное по знаку до 32 бит) в указанный регистр. |
13 21с | const/16 vAA, #+BBBB | A: регистр назначения (8 бит)B: целое число со знаком (16 бит) | Переместите заданное литеральное значение (расширенное по знаку до 32 бит) в указанный регистр. |
14 31и | const vAA, #+BBBBBBBB | A: регистр назначения (8 бит)B: произвольная 32-битная константа | Переместите заданное литеральное значение в указанный регистр. |
15 21ч | const/high16 vAA, #+BBBB0000 | A: регистр назначения (8 бит)B: целое число со знаком (16 бит) | Переместите заданное литеральное значение (правый-ноль-расширенный до 32 бит) в указанный регистр. |
16 21с | const-wide/16 vAA, #+BBBB | A: регистр назначения (8 бит)B: целое число со знаком (16 бит) | Переместите заданное литеральное значение (расширенное по знаку до 64 бит) в указанную пару регистров. |
17 31и | const-wide/32 vAA, #+BBBBBBBB | A: регистр назначения (8 бит)B: целое со знаком (32 бита) | Переместите заданное литеральное значение (расширенное по знаку до 64 бит) в указанную пару регистров. |
18 51л | const-wide vAA, #+BBBBBBBBBBBBBBBB | A: регистр назначения (8 бит)B: произвольная константа двойной ширины (64 бита) | Переместите заданное литеральное значение в указанную пару регистров. |
19 21ч | const-wide/high16 vAA, #+BBBB000000000000 | A: регистр назначения (8 бит)B: целое число со знаком (16 бит) | Переместите заданное литеральное значение (правый-ноль-расширенный до 64 бит) в указанную пару регистров. |
1а 21с | константная строка vAA, строка@BBBB | A: регистр назначения (8 бит)B: индекс строки | Переместить ссылку на строку, указанную данным индексом, в указанный регистр. |
1б 31с | const-string/jumbo vAA, string@BBBBBBBB | A: регистр назначения (8 бит)B: индекс строки | Переместить ссылку на строку, указанную данным индексом, в указанный регистр. |
1с 21с | константный класс vAA, тип@BBBB | A: регистр назначения (8 бит)B: индекс типа | Переместите ссылку на класс, указанный данным индексом, в указанный регистр. В случае, когда указанный тип является примитивным, будет храниться ссылка на вырожденный класс примитивного типа. |
1д 11х | монитор-введите vAA | A: опорный регистр (8 бит) | Приобретите монитор для указанного объекта. |
1е 11х | монитор-выход vAA | A: опорный регистр (8 бит) | Отпустите монитор для указанного объекта. Примечание: Если эта инструкция должна сгенерировать исключение, она должна сделать это так, как если бы преклир уже прошел эту инструкцию. Может быть полезно думать об этом как об успешном выполнении инструкции (в некотором смысле) и об исключении, возникающем после инструкции, но до того, как следующая получит шанс запуститься. Это определение позволяет методу использовать универсальный блок очистки монитора (например, |
1ф 21с | чек-каст vAA, type@BBBB | A: опорный регистр (8 бит)B: индекс типа (16 бит) | ClassCastException , если ссылка в данном регистре не может быть приведена к указанному типу. Примечание. Поскольку |
20 22с | экземпляр vA, vB, type@CCCC | A: регистр назначения (4 бита)B: опорный регистр (4 бита)C: индекс типа (16 бит) | Сохранить в заданном регистре назначения 1 , если указанная ссылка является экземпляром данного типа, или 0 , если нет. Примечание. Поскольку |
21 12x | длина массива vA, vB | A: регистр назначения (4 бита)B: опорный регистр массива (4 бита) | Сохранить в заданном целевом регистре длину указанного массива в записях |
22 21с | новый экземпляр vAA, тип@BBBB | A: регистр назначения (8 бит)B: индекс типа | Создайте новый экземпляр указанного типа, сохранив ссылку на него в месте назначения. Тип должен относиться к классу, не являющемуся массивом. |
23 22с | новый массив vA, vB, type@CCCC | A: регистр назначения (4 бита)B: регистр размераC: индекс типа | Создайте новый массив указанного типа и размера. Тип должен быть типом массива. |
24 35с | заполненный новый массив {vC, vD, vE, vF, vG}, type@BBBB | A: размер массива и количество слов аргумента (4 бита)B: индекс типа (16 бит)C..G: регистры аргументов (по 4 бита в каждом) | Создайте массив заданного типа и размера, заполнив его предоставленным содержимым. Тип должен быть типом массива. Содержимое массива должно состоять из одного слова (то есть допустимы не массивы long или double , а ссылочные типы). Сконструированный экземпляр сохраняется как «результат» таким же образом, как инструкции вызова метода сохраняют свои результаты, поэтому сконструированный экземпляр должен быть перемещен в регистр сразу же последующей инструкцией move-result-object (если она должна использоваться ). |
25 3рк | заполненный новый массив/диапазон {vCCCC .. vNNNN}, type@BBBB | A: размер массива и количество слов аргумента (8 бит)B: индекс типа (16 бит)C: регистр первого аргумента (16 бит)N = A + C - 1 | Создайте массив заданного типа и размера, заполнив его предоставленным содержимым. Уточнения и ограничения такие же, как и для filled-new-array , описанного выше. |
26 31т | fill-array-data vAA, +BBBBBBBB (с дополнительными данными, как указано ниже в «формате fill-array-data-payload ») | A: ссылка на массив (8 бит)B: подписанное смещение «ветви» к псевдоинструкции табличных данных (32 бита) | Заполните заданный массив указанными данными. Ссылка должна быть на массив примитивов, а таблица данных должна соответствовать ему по типу и содержать не больше элементов, чем поместится в массиве. То есть массив может быть больше, чем таблица, и если это так, устанавливаются только начальные элементы массива, а остальные остаются в покое. |
27 11x | бросить вАА | A: регистр исключения (8 бит) | Выдать указанное исключение. |
28 10т | перейти к +АА | A: смещение ветви со знаком (8 бит) | Безоговорочный переход к указанной инструкции. Примечание. Смещение ветвления не должно быть равно |
29 20т | перейти/16 +AAAA | A: смещение ветви со знаком (16 бит) | Безоговорочный переход к указанной инструкции. Примечание. Смещение ветвления не должно быть равно |
2а 30т | перейти/32 +AAAAAAAA | A: смещение ветви со знаком (32 бита) | Безоговорочный переход к указанной инструкции. |
2б 31т | упакованный коммутатор vAA, +BBBBBBBB (с дополнительными данными, как указано ниже в «формате packed-switch-payload ») | A: зарегистрироваться для тестированияB: подписанное смещение «ветви» к псевдоинструкции табличных данных (32 бита) | Перейти к новой инструкции на основе значения в данном регистре, используя таблицу смещений, соответствующих каждому значению в определенном диапазоне интегралов, или перейти к следующей инструкции, если совпадения нет. |
2с 31т | sparse-switch vAA, +BBBBBBBB (с дополнительными данными, указанными ниже в «формате sparse-switch-payload ») | A: зарегистрироваться для тестированияB: подписанное смещение «ветви» к псевдоинструкции табличных данных (32 бита) | Перейти к новой инструкции на основе значения в данном регистре, используя упорядоченную таблицу пар значение-смещение, или перейти к следующей инструкции, если совпадения нет. |
2д..31 23х | тип cmp vAA, vBB, vCC 2d: cmpl-float (смещение lt) 2e: cmpg-float (смещение gt) 2f: cmpl-двойной (низкий уклон) 30: cmpg-double (уклон gt) 31: cmp-длинный | A: регистр назначения (8 бит)B: первый исходный регистр или параC: второй исходный регистр или пара | Выполните указанное сравнение с плавающей запятой или long сравнение, установив a в 0 , если b == c , 1 , если b > c , или -1 , если b < c . «Смещение», указанное для операций с плавающей запятой, указывает, как обрабатываются сравнения NaN : инструкции «gtbias» возвращают 1 для сравнений NaN , а инструкции «ltbias» возвращают -1 . Например, чтобы проверить, является ли число с плавающей запятой |
32..37 22т | если- тест vA, vB, +CCCC 32: если-экв 33: если-не 34: если-л 35: если-гэ 36: если-гт 37: если-ле | A: первый регистр для проверки (4 бита)B: второй регистр для проверки (4 бита)C: смещение ветви со знаком (16 бит) | Перейти к заданному месту назначения, если заданные значения двух регистров сравниваются, как указано. Примечание. Смещение ветвления не должно быть равно |
38..3д 21т | if- test z vAA, +BBBB 38: если-eqz 39: если-нет 3а: если-лц 3б: если-гез 3c: если-ГТЦ 3d: если-лез | A: зарегистрироваться для тестирования (8 бит)B: смещение перехода со знаком (16 бит) | Перейти к заданному месту назначения, если значение данного регистра сравнивается с 0, как указано. Примечание. Смещение ветвления не должно быть равно |
3e..43 10x | (неиспользованный) | (неиспользованный) | |
44..51 23x | массивы vAA, vBB, vCC 44: получить 45: широкая 46: получить-объект 47: логическое значение 48: получить-байт 49: гет-чар 4a: аге-короткий 4б: апут 4c: aput-широкий 4d: aput-объект 4e: aput-boolean 4f: входной байт 50: апут-символ 51: aput-короткий | A: регистр значения или пара; может быть источником или получателем (8 бит)B: регистр массива (8 бит)C: индексный регистр (8 бит) | Выполнить операцию с идентифицированным массивом по идентифицированному индексу данного массива, загружая или сохраняя в регистр значения. |
52..5f 22c | i instanceop vA, vB, field@CCCC 52: игет 53: iget-широкий 54: iget-объект 55: iget-логическое значение 56: iget-байт 57: игет-чар 58: iget-короткий 59: ввод 5a: общий ввод 5b: Iput-объект 5c: Iput-логическое значение 5d: ввод-байт 5e: ввод-символ 5f: iput-короткий | A: регистр значения или пара; может быть источником или получателем (4 бита)B: объектный регистр (4 бита)C: индекс ссылки на поле экземпляра (16 бит) | Выполнить операцию поля экземпляра идентифицированного объекта с идентифицированным полем, загрузив или сохранив в регистр значения. Примечание. Эти коды операций являются разумными кандидатами для статической компоновки, изменяя аргумент поля, чтобы он был более прямым смещением. |
60..6д 21с | s staticop vAA, field@BBBB 60: сгет 61: широкий 62: sget-объект 63: sget-логическое значение 64: sget-байт 65: sget-char 66: короткий 67: тыр 68: ширина носа 69: развед-объект 6a: sput-boolean 6b: sput-byte 6c: sput-char 6д: спут-короткая | A: регистр значения или пара; может быть источником или получателем (8 бит)B: индекс ссылки статического поля (16 бит) | Выполнить операцию статического поля идентифицированного объекта с идентифицированным статическим полем, загрузив или сохранив в регистр значения. Примечание. Эти коды операций являются разумными кандидатами для статической компоновки, изменяя аргумент поля, чтобы он был более прямым смещением. |
6д..72 35с | вызывать вид {vC, vD, vE, vF, vG}, meth@BBBB 6e: вызвать виртуальный 6f: вызвать-супер 70: прямой вызов 71: вызвать-статический 72: вызов интерфейса | A: количество слов аргумента (4 бита)B: индекс ссылки на метод (16 бит)C..G: регистры аргументов (по 4 бита в каждом) | Вызвать указанный метод. Результат (если есть) может быть сохранен с соответствующим вариантом move-result* в качестве непосредственно следующей за ним инструкции. Когда В файлах Dex версии Примечание. Эти коды операций являются разумными кандидатами для статической компоновки, изменяя аргумент метода, чтобы он был более прямым смещением (или парой смещений). |
73 10x | (неиспользованный) | (неиспользованный) | |
74..78 3рб | вызывать вид /диапазон {vCCCC .. vNNNN}, meth@BBBB 74: вызвать-виртуальный/диапазон 75: вызвать-супер/диапазон 76: непосредственный вызов/диапазон 77: вызвать-статический/диапазон 78: вызов интерфейса/диапазона | A: количество слов аргумента (8 бит)B: индекс ссылки на метод (16 бит)C: регистр первого аргумента (16 бит)N = A + C - 1 | Вызвать указанный метод. Подробности, предостережения и предложения см. в описании первого invoke- kind выше. |
79..7а 10х | (неиспользованный) | (неиспользованный) | |
7б..8ф 12х | unop vA , vB 7b: отрицательное целое 7c: не-инт 7d: отрицательная длинна 7e: недолго 7f: отрицательный с плавающей запятой 80: отрицательный двойной 81: от целого к длинному 82: in-to-float 83: инт-в-дабл 84: длинное в целое 85: долго плавающий 86: длинный-удвоить 87: число с плавающей запятой 88: с плавающей запятой 89: число с плавающей запятой 8a: двойное целое 8b: двойной к длинному 8c: двойное плавание 8d: int-to-byte 8e: int-to-char 8f: инт-к-короткому | A: регистр назначения или пара (4 бита)B: исходный регистр или пара (4 бита) | Выполните идентифицированную унарную операцию в исходном регистре, сохранив результат в целевом регистре. |
90..af 23x | биноп vAA, vBB, vCC 90: надстройка 91: субинт 92: многоцелевое 93: деление-целое 94: остаток-инт 95: и-инт 96: или-целое 97: xor-int 98: шл-инт 99: шр-инт 9а: ушр-инт 9b: добавить долго 9c: субдлинный 9d: мул-лонг 9e: длинный раздел 9f: rem-длинный a0: и-длинный a1: или-длинный a2: xor-лонг a3: з/д a4: шр-длинный a5: ушр - длинная a6: добавить с плавающей запятой a7: вспомогательный поплавок a8: множественное число с плавающей запятой a9: деление с плавающей запятой aa: rem-поплавок аб: добавить-двойной переменный ток: саб-дабл объявление: мул-дабл ae: div-двойной af: rem-двойной | A: регистр назначения или пара (8 бит)B: первый исходный регистр или пара (8 бит)C: второй исходный регистр или пара (8 бит) | Выполните идентифицированную двоичную операцию над двумя исходными регистрами, сохранив результат в целевом регистре. Примечание. В отличие от других математических операций |
b0..cf 12x | binop /2addr vA, vB b0: add-int/2addr b1: sub-int/2addr b2: mul-int/2addr b3: дел-целое/2адрес b4: rem-int/2addr b5: и-int/2addr b6: or-int/2addr b7: xor-int/2addr b8: shl-int/2addr b9: шр-инт/2адрес ba: ushr-int/2addr bb: add-long/2addr bc: sub-long/2addr bd: mul-long/2addr быть: div-long/2addr bf: rem-long/2addr c0: и-длинный/2адрес c1: or-long/2addr c2: xor-long/2addr c3: shl-long/2addr c4: shr-long/2addr c5: ushr-long/2addr c6: add-float/2addr c7: sub-float/2addr c8: mul-float/2addr c9: div-float/2addr ca: rem-float/2addr cb: add-double/2addr копия: sub-double/2addr cd: mul-double/2addr ce: div-двойной/2addr cf: rem-double/2addr | A: регистр назначения и первый регистр источника или пара (4 бита)B: второй исходный регистр или пара (4 бита) | Выполните идентифицированную двоичную операцию над двумя исходными регистрами, сохранив результат в первом исходном регистре. Примечание. В отличие от других математических операций |
d0..d7 22с | binop /lit16 vA, vB, #+CCCC d0: добавить int/lit16 d1: rsub-int (обратное вычитание) d2: mul-int/lit16 d3: дел-целое/лит16 d4: рем-инт/лит16 d5: и-инт/лит16 d6: or-int/lit16 d7: xor-int/lit16 | A: регистр назначения (4 бита)B: исходный регистр (4 бита)C: целочисленная константа со знаком (16 бит) | Выполните указанную бинарную операцию над указанным регистром (первый аргумент) и литеральным значением (второй аргумент), сохраняя результат в регистре назначения. Примечание: |
d8..e2 22b | binop /lit8 vAA, vBB, #+CC d8: добавить int/lit8 d9: rsub-int/lit8 da: mul-int/lit8 БД: div-int/lit8 постоянный ток: rem-int/lit8 дд: и-инт/лит8 de: or-int/lit8 df: xor-int/lit8 e0: shl-int/lit8 e1: шр-инт/лит8 e2: ushr-int/lit8 | A: регистр назначения (8 бит)B: исходный регистр (8 бит)C: целочисленная константа со знаком (8 бит) | Выполните указанную бинарную операцию над указанным регистром (первый аргумент) и литеральным значением (второй аргумент), сохраняя результат в регистре назначения. Примечание . Подробнее о семантике |
e3..f9 10x | (неиспользованный) | (неиспользованный) | |
фа 45cc | вызывать-полиморфные {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH | A: количество слов аргумента (4 бита)B: индекс ссылки на метод (16 бит)C: приемник (4 бита)D..G: регистры аргументов (по 4 бита в каждом)H: индекс ссылки на прототип (16 бит) | Вызвать указанный полиморфный метод подписи. Результат (если есть) может быть сохранен с соответствующим вариантом move-result* в качестве непосредственно следующей за ним инструкции.Ссылка на метод должна быть на сигнатурный полиморфный метод, такой как java.lang.invoke.MethodHandle.invoke или java.lang.invoke.MethodHandle.invokeExact .Получатель должен быть объектом, поддерживающим вызываемый полиморфный метод сигнатуры. Ссылка на прототип описывает предоставленные типы аргументов и ожидаемый тип возвращаемого значения. invoke-polymorphic байт-код может вызывать исключения при выполнении. Исключения описаны в документации API для вызываемого полиморфного метода подписи.Присутствует в файлах Dex, начиная с версии 038 . |
фб 4ркк | вызывать-полиморфный/диапазон {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH | A: количество слов аргумента (8 бит)B: индекс ссылки на метод (16 бит)C: приемник (16 бит)H: индекс ссылки на прототип (16 бит)N = A + C - 1 | Вызвать указанный дескриптор метода. Подробности смотрите в описании invoke-polymorphic выше.Присутствует в файлах Dex, начиная с версии 038 . |
ФК 35с | пользовательский вызов {vC, vD, vE, vF, vG}, call_site@BBBB | A: количество слов аргумента (4 бита)B: индекс ссылки на сайт вызова (16 бит)C..G: регистры аргументов (по 4 бита в каждом) | Разрешает и вызывает указанный сайт вызова. Результат вызова (если есть) может быть сохранен с соответствующим вариантом move-result* в качестве непосредственно следующей за ним инструкции.Эта инструкция выполняется в два этапа: разрешение сайта вызова и вызов сайта вызова. Разрешение сайта вызова проверяет, имеет ли указанный сайт вызова связанный экземпляр java.lang.invoke.CallSite . В противном случае вызывается метод компоновщика начальной загрузки для указанного сайта вызова с использованием аргументов, присутствующих в файле DEX (см. call_site_item ). Метод компоновщика начальной загрузки возвращает экземпляр java.lang.invoke.CallSite , который затем будет связан с указанным сайтом вызова, если связи не существует. Другой поток, возможно, уже создал ассоциацию первым, и если это так, выполнение инструкции продолжается с первым связанным экземпляром java.lang.invoke.CallSite .Вызов сайта вызова выполняется в целевом объекте java.lang.invoke.MethodHandle разрешенного экземпляра java.lang.invoke.CallSite . Цель вызывается так же, как если бы выполнялась invoke-polymorphic функция вызова (описанная выше), используя дескриптор метода и аргументы инструкции invoke-custom в качестве аргументов для точного вызова дескриптора метода.Исключения, вызванные методом компоновщика начальной загрузки, оборачиваются в java.lang.BootstrapMethodError . Ошибка BootstrapMethodError также возникает, если:
038 . |
фд 3rc | пользовательский вызов/диапазон {vCCCC .. vNNNN}, call_site@BBBB | A: количество слов аргумента (8 бит)B: индекс ссылки на сайт вызова (16 бит)C: регистр первого аргумента (16 бит)N = A + C - 1 | Разрешите и вызовите сайт вызова. Подробности смотрите в описании invoke-custom выше.Присутствует в файлах Dex, начиная с версии 038 . |
фе 21с | const-метод-дескриптор vAA, method_handle@BBBB | A: регистр назначения (8 бит)B: индекс дескриптора метода (16 бит) | Переместите ссылку на дескриптор метода, указанный данным индексом, в указанный регистр. Присутствует в файлах Dex начиная с версии 039 . |
фф 21с | const-method-type vAA, proto@BBBB | A: регистр назначения (8 бит)B: ссылка на прототип метода (16 бит) | Переместить ссылку на прототип метода, заданный данным индексом, в указанный регистр. Присутствует в файлах Dex начиная с версии 039 . |
упакованный формат полезной нагрузки переключателя
Имя | Формат | Описание |
---|---|---|
идентификация | ушорт = 0x0100 | определение псевдокода операции |
размер | ушорт | количество записей в таблице |
первый_ключ | инт | первое (и самое низкое) значение регистра переключения |
цели | интервал [] | список целевых ветвей относительного size . Цели относятся к адресу кода операции переключателя, а не к этой таблице. |
Примечание . Общее количество единиц кода для экземпляра этой таблицы равно (size * 2) + 4
.
формат разреженного переключателя полезной нагрузки
Имя | Формат | Описание |
---|---|---|
идентификация | ушорт = 0x0200 | определение псевдокода операции |
размер | ушорт | количество записей в таблице |
ключи | интервал [] | список ключевых значений size , отсортированных по возрастанию |
цели | интервал [] | список целевых ветвей относительного size , каждая из которых соответствует значению ключа в одном и том же индексе. Цели относятся к адресу кода операции переключателя, а не к этой таблице. |
Примечание . Общее количество единиц кода для экземпляра этой таблицы равно (size * 4) + 2
.
формат заполнения-массива-данных-полезной нагрузки
Имя | Формат | Описание |
---|---|---|
идентификация | ушорт = 0x0300 | определение псевдокода операции |
element_width | ушорт | количество байтов в каждом элементе |
размер | не | количество элементов в таблице |
данные | убайт[] | значения данных |
Примечание . Общее количество единиц кода для экземпляра этой таблицы равно (size * element_width + 1) / 2 + 4
.
Детали математической операции
Примечание. Операции с плавающей запятой должны соответствовать правилам IEEE 754 с использованием округления до ближайшего и постепенного потери значимости, если не указано иное.
Опкод | Си Семантика | Заметки |
---|---|---|
отрицательный интервал | int32 а; результат int32 = -а; | Унарное дополнение до двух. |
не-инт | int32 а; int32 результат = ~а; | Унарные единицы-дополнение. |
отрицательный | int64 а; результат int64 = -а; | Унарное дополнение до двух. |
недолго | int64 а; int64 результат = ~ а; | Унарные единицы-дополнение. |
отрицательный с плавающей запятой | плавать а; результат с плавающей запятой = -a; | Floating point negation. |
neg-double | double a; double result = -a; | Floating point negation. |
int-to-long | int32 a; int64 result = (int64) a; | Sign extension of int32 into int64 . |
int-to-float | int32 a; float result = (float) a; | Conversion of int32 to float , using round-to-nearest. This loses precision for some values. |
int-to-double | int32 a; double result = (double) a; | Conversion of int32 to double . |
long-to-int | int64 a; int32 result = (int32) a; | Truncation of int64 into int32 . |
long-to-float | int64 a; float result = (float) a; | Conversion of int64 to float , using round-to-nearest. This loses precision for some values. |
long-to-double | int64 a; double result = (double) a; | Conversion of int64 to double , using round-to-nearest. This loses precision for some values. |
float-to-int | float a; int32 result = (int32) a; | Conversion of float to int32 , using round-toward-zero. NaN and -0.0 (negative zero) convert to the integer 0 . Infinities and values with too large a magnitude to be represented get converted to either 0x7fffffff or -0x80000000 depending on sign. |
float-to-long | float a; int64 result = (int64) a; | Conversion of float to int64 , using round-toward-zero. The same special case rules as for float-to-int apply here, except that out-of-range values get converted to either 0x7fffffffffffffff or -0x8000000000000000 depending on sign. |
float-to-double | float a; double result = (double) a; | Conversion of float to double , preserving the value exactly. |
double-to-int | double a; int32 result = (int32) a; | Conversion of double to int32 , using round-toward-zero. The same special case rules as for float-to-int apply here. |
double-to-long | double a; int64 result = (int64) a; | Conversion of double to int64 , using round-toward-zero. The same special case rules as for float-to-long apply here. |
double-to-float | double a; float result = (float) a; | Conversion of double to float , using round-to-nearest. This loses precision for some values. |
int-to-byte | int32 a; int32 result = (a << 24) >> 24; | Truncation of int32 to int8 , sign extending the result. |
int-to-char | int32 a; int32 result = a & 0xffff; | Truncation of int32 to uint16 , without sign extension. |
int-to-short | int32 a; int32 result = (a << 16) >> 16; | Truncation of int32 to int16 , sign extending the result. |
add-int | int32 a, b; int32 result = a + b; | Twos-complement addition. |
sub-int | int32 a, b; int32 result = a - b; | Twos-complement subtraction. |
rsub-int | int32 a, b; int32 result = b - a; | Twos-complement reverse subtraction. |
mul-int | int32 a, b; int32 result = a * b; | Twos-complement multiplication. |
div-int | int32 a, b; int32 result = a / b; | Twos-complement division, rounded towards zero (that is, truncated to integer). This throws ArithmeticException if b == 0 . |
rem-int | int32 a, b; int32 result = a % b; | Twos-complement remainder after division. The sign of the result is the same as that of a , and it is more precisely defined as result == a - (a / b) * b . This throws ArithmeticException if b == 0 . |
and-int | int32 a, b; int32 result = a & b; | Bitwise AND. |
or-int | int32 a, b; int32 result = a | b; | Bitwise OR. |
xor-int | int32 a, b; int32 result = a ^ b; | Bitwise XOR. |
shl-int | int32 a, b; int32 result = a << (b & 0x1f); | Bitwise shift left (with masked argument). |
shr-int | int32 a, b; int32 result = a >> (b & 0x1f); | Bitwise signed shift right (with masked argument). |
ushr-int | uint32 a, b; int32 result = a >> (b & 0x1f); | Bitwise unsigned shift right (with masked argument). |
add-long | int64 a, b; int64 result = a + b; | Twos-complement addition. |
sub-long | int64 a, b; int64 result = a - b; | Twos-complement subtraction. |
mul-long | int64 a, b; int64 result = a * b; | Twos-complement multiplication. |
div-long | int64 a, b; int64 result = a / b; | Twos-complement division, rounded towards zero (that is, truncated to integer). This throws ArithmeticException if b == 0 . |
rem-long | int64 a, b; int64 result = a % b; | Twos-complement remainder after division. The sign of the result is the same as that of a , and it is more precisely defined as result == a - (a / b) * b . This throws ArithmeticException if b == 0 . |
and-long | int64 a, b; int64 result = a & b; | Bitwise AND. |
or-long | int64 a, b; int64 result = a | b; | Bitwise OR. |
xor-long | int64 a, b; int64 result = a ^ b; | Bitwise XOR. |
shl-long | int64 a; int32 b; int64 result = a << (b & 0x3f); | Bitwise shift left (with masked argument). |
shr-long | int64 a; int32 b; int64 result = a >> (b & 0x3f); | Bitwise signed shift right (with masked argument). |
ushr-long | uint64 a; int32 b; int64 result = a >> (b & 0x3f); | Bitwise unsigned shift right (with masked argument). |
add-float | float a, b; float result = a + b; | Floating point addition. |
sub-float | float a, b; float result = a - b; | Floating point subtraction. |
mul-float | float a, b; float result = a * b; | Floating point multiplication. |
div-float | float a, b; float result = a / b; | Floating point division. |
rem-float | float a, b; float result = a % b; | Floating point remainder after division. This function is different than IEEE 754 remainder and is defined as result == a - roundTowardZero(a / b) * b . |
add-double | double a, b; double result = a + b; | Floating point addition. |
sub-double | double a, b; double result = a - b; | Floating point subtraction. |
mul-double | double a, b; double result = a * b; | Floating point multiplication. |
div-double | double a, b; double result = a / b; | Floating point division. |
rem-double | double a, b; double result = a % b; | Floating point remainder after division. This function is different than IEEE 754 remainder and is defined as result == a - roundTowardZero(a / b) * b . |