Общий дизайн
- Модель машины и соглашения о вызовах призваны приблизительно имитировать распространенные реальные архитектуры и соглашения о вызовах в стиле 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.
- "
- Подробную информацию о различных форматах инструкций (перечисленных в разделе Op & Format), а также о синтаксисе кодов операций можно найти в документе о форматах инструкций.
- Подробную информацию о том, как байт-код вписывается в общую картину, можно найти в документе о формате файла
.dex.
Сводка набора байт-кода
| Оператор и формат | Мнемоника / синтаксис | Аргументы | Описание |
|---|---|---|---|
| 00 10x | nop | Циклы утилизации отходов.
Примечание.
Псевдоинструкции, содержащие данные, помечаются этим кодом операции. В этом случае старший байт единицы кода операции указывает на тип данных. См. разделы "Формат |
|
| 01 12x | move vA, vB | A: регистр назначения (4 бита)B: исходный регистр (4 бита) |
Перемещать содержимое одного реестра, не относящегося к объектам, в другой. |
| 02 22x | move/from16 vAA, vBBBB | A: регистр назначения (8 бит)B: регистр источника (16 бит) |
Перемещать содержимое одного реестра, не относящегося к объектам, в другой. |
| 03 32x | move/16 vAAAA, vBBBB | A: регистр назначения (16 бит)B: исходный регистр (16 бит) |
Перемещать содержимое одного реестра, не относящегося к объектам, в другой. |
| 04 12x | move-wide vA, vB | A: пара регистров назначения (4 бита)B: пара исходных регистров (4 бита) |
Переместить содержимое одной пары регистров в другую.
Примечание.
Переход от |
| 05 22x | move-wide/from16 vAA, vBBBB | A: пара регистров назначения (8 бит)B: пара исходных регистров (16 бит) |
Переместить содержимое одной пары регистров в другую.
Примечание.
О чем важно помнить, описано в разделе |
| 06 32x | move-wide/16 vAAAA, vBBBB | A: пара регистров назначения (16 бит)B: пара регистров источника (16 бит) |
Переместить содержимое одной пары регистров в другую.
Примечание.
О чем важно помнить, описано в разделе |
| 07 12x | move-object vA, vB | A: регистр назначения (4 бита)B: исходный регистр (4 бита) |
Переместить содержимое одного реестра объектов в другой. |
| 08 22x | move-object/from16 vAA, vBBBB | A: регистр назначения (8 бит)B: регистр источника (16 бит) |
Переместить содержимое одного регистра, содержащего объект, в другой. |
| 09 32x | move-object/16 vAAAA, vBBBB | A: регистр назначения (16 бит)B: исходный регистр (16 бит) |
Переместить содержимое одного реестра объектов в другой. |
| 0a 11x | move-result vAA | Регистр назначения A: (8 бит) |
Переместить однословный результат, не являющийся объектом, из последнего запроса invoke-kind в указанный регистр.
Эта инструкция должна следовать сразу за инструкцией invoke-kind, результат которой (одно слово, не объект) не должен игнорироваться. В любом другом месте она будет недействительна. |
| 0b 11x | move-result-wide vAA | A: – пара регистров назначения (8 бит); |
Перемещает результат двойного слова из последнего
invoke-kind в указанную пару регистров.
Это нужно сделать сразу после инструкции invoke-kind, результат которой (двойное слово) не должен игнорироваться. В любом другом месте это будет недопустимо. |
| 0c 11x | move-result-object vAA | Регистр назначения A: (8 бит) |
Переместить объект, полученный в результате последнего действия invoke-kind, в указанный регистр. Это нужно сделать в виде инструкции сразу после invoke-kind или filled-new-array, результат которой не игнорируется. В других местах это недопустимо. |
| 0d 11x | move-exception vAA | Регистр назначения A: (8 бит) |
Сохраняет только что пойманное исключение в указанном регистре. Это должна быть первая инструкция любого обработчика исключений, пойманное исключение которого не должно игнорироваться. Эта инструкция должна всегда быть первой инструкцией обработчика исключений. В любом другом месте она недопустима. |
| 0e 10x | return-void | Возвращает значение из метода void. |
|
| 0f 11x | return vAA | Регистр возвращаемого значения A: (8 бит) |
Возврат из метода, возвращающего значение, которое не является объектом и имеет одинарную ширину (32 бита). |
| 10 11x | return-wide vAA | Пара регистров возвращаемого значения A: (8 бит) |
Возврат из метода, возвращающего значение двойной ширины (64-битное). |
| 11 11x | return-object vAA | Регистр возвращаемого значения A: (8 бит) |
Возвращает значение из метода, возвращающего объект. |
| 12 11n | const/4 vA, #+B | A: регистр назначения (4 бита)B: знаковое целое число (4 бита) |
Перемещает заданное литеральное значение (с расширением знака до 32 бит) в указанный регистр. |
| 13 21 | const/16 vAA, #+BBBB | A: регистр назначения (8 бит)B: знаковое целое число (16 бит) |
Перемещает заданное литеральное значение (с расширением знака до 32 бит) в указанный регистр. |
| 14 31i | const vAA, #+BBBBBBBB | A: регистр назначения (8 бит)B: произвольная 32-битная константа |
Перемещает заданное литеральное значение в указанный регистр. |
| 15 21h | const/high16 vAA, #+BBBB0000 | A: регистр назначения (8 бит)B: знаковое целое число (16 бит) |
Перемещает заданное литеральное значение (дополненное справа нулями до 32 бит) в указанный регистр. |
| 16 21 | const-wide/16 vAA, #+BBBB | A: регистр назначения (8 бит)B: знаковое целое число (16 бит) |
Перемещает заданное литеральное значение (с расширением знака до 64 бит) в указанную пару регистров. |
| 17 31i | const-wide/32 vAA, #+BBBBBBBB | A: регистр назначения (8 бит)B: целое число со знаком (32 бита) |
Перемещает заданное литеральное значение (с расширением знака до 64 бит) в указанную пару регистров. |
| 18 51l | const-wide vAA, #+BBBBBBBBBBBBBBBB | A: регистр назначения (8 бит)B: произвольная константа двойной ширины (64 бита) |
Переместить заданное литеральное значение в указанную пару регистров. |
| 19 21h | const-wide/high16 vAA, #+BBBB000000000000 | A: регистр назначения (8 бит)B: знаковое целое число (16 бит) |
Перемещает заданное литеральное значение (справа дополненное нулями до 64 бит) в указанную пару регистров. |
| 1a 21c | const-string vAA, string@BBBB | A: регистр назначения (8 бит)B: индекс строки |
Перемещает ссылку на строку, указанную заданным индексом, в указанный регистр. |
| 1b 31c | const-string/jumbo vAA, string@BBBBBBBB | A: регистр назначения (8 бит)B: индекс строки |
Перемещает ссылку на строку, указанную заданным индексом, в указанный регистр. |
| 1c, 21c | const-class vAA, type@BBBB | A: регистр назначения (8 бит)B: индекс типа |
Перемещает ссылку на класс, указанный заданным индексом, в указанный регистр. Если указанный тип является примитивным, будет сохранена ссылка на вырожденный класс примитивного типа. |
| 1 день, 11 раз | monitor-enter vAA | A: регистр ссылок (8 бит) |
Получите монитор для указанного объекта. |
| 1e 11x | monitor-exit vAA | A: – регистр, содержащий ссылку (8 бит). |
Освободите монитор для указанного объекта.
Примечание.
Если эта инструкция должна вызвать исключение, она должна сделать
это так, как если бы указатель уже прошел инструкцию.
Можно считать, что инструкция успешно выполняется, а исключение генерируется после нее, но до следующей. Это определение позволяет методу использовать универсальный блок очистки монитора (например, |
| 1f 21c | check-cast vAA, type@BBBB | A: регистр с ссылкой (8 бит)B: индекс типа (16 бит) |
Выбрасывает исключение ClassCastException, если ссылку в указанном регистре нельзя привести к указанному типу.
Примечание. Поскольку |
| 20 22c | instance-of vA, vB, type@CCCC | A: регистр назначения (4 бита)B: регистр со ссылкой (4 бита)C: индекс типа (16 бит) |
Сохраняет в указанном регистре назначения 1, если указанная ссылка является экземпляром заданного типа, или 0, если нет.
Примечание. Поскольку |
| 21 12x | array-length vA, vB | A: регистр назначения (4 бита)B: регистр, содержащий ссылку на массив (4 бита) |
Сохраняет в указанном регистре длину массива, выраженную в записях. |
| 22 21c | new-instance vAA, type@BBBB | A: регистр назначения (8 бит)B: индекс типа |
Создает новый экземпляр указанного типа и сохраняет ссылку на него в целевом объекте. Тип должен относиться к классу, не являющемуся массивом. |
| 23 22c | new-array vA, vB, type@CCCC | A: регистр назначения (4 бита)B: регистр размераC: индекс типа |
Создает новый массив указанного типа и размера. Тип должен быть массивом. |
| 24 35c | filled-new-array {vC, vD, vE, vF, vG}, type@BBBB |
A: размер массива и количество слов в аргументе (4 бита)B: индекс типа (16 бит)C..G: регистры аргументов (по 4 бита)
|
Создает массив заданного типа и размера, заполняя его указанным содержимым. Тип должен быть типом массива. Массив должен содержать только отдельные слова (то есть не массивы long или double, но ссылочные типы допустимы). Созданный экземпляр сохраняется как "результат" так же, как инструкции вызова метода сохраняют свои результаты, поэтому созданный экземпляр должен быть перемещен в регистр с помощью непосредственно следующей инструкции move-result-object (если он должен быть использован). |
| 25 3rc | filled-new-array/range {vCCCC .. vNNNN}, type@BBBB | A: размер массива и количество слов в аргументе (8 бит)B: индекс типа (16 бит)C: регистр первого аргумента (16 бит)N = A + C - 1 |
Создает массив заданного типа и размера, заполняя его предоставленным содержимым. Уточнения и ограничения такие же, как и для поля filled-new-array (описано выше). |
| 26 31t | fill-array-data vAA, +BBBBBBBB (с дополнительными данными, как указано ниже в разделе fill-array-data-payload Format) |
A: ссылка на массив (8 бит)B: знаковое смещение "ветви" к псевдоинструкции данных таблицы
(32 бита)
|
Заполняет указанный массив данными. Ссылка должна указывать на массив примитивов, а таблица данных должна соответствовать ему по типу и содержать не больше элементов, чем может поместиться в массиве. Массив может быть больше таблицы, и в этом случае будут заданы только начальные элементы массива, а остальные останутся без изменений. |
| 27 11x | бросить vAA | A: регистр исключений (8 бит) |
Вызвать указанное исключение. |
| 28 10t | goto +AA | A: смещение подписанной ветви (8 бит) |
Безусловный переход к указанной инструкции.
Примечание.
Смещение ветви не должно быть равно |
| 29 20t | goto/16 +AAAA | A: смещение перехода со знаком (16 бит) |
Безусловный переход к указанной инструкции.
Примечание.
Смещение ветви не должно быть равно |
| 2a 30t | goto/32 +AAAAAAAA | A: смещение подписанного перехода (32 бита) |
Безусловный переход к указанной инструкции. |
| 2b 31t | packed-switch vAA, +BBBBBBBB (дополнительные данные указаны ниже в разделе "packed-switch-payload Формат") |
A: регистр для тестированияB: смещение подписанной ветви к псевдоинструкции данных таблицы
(32 бита)
|
Переход к новой инструкции на основе значения в заданном регистре с использованием таблицы смещений, соответствующих каждому значению в определенном целочисленном диапазоне, или переход к следующей инструкции, если совпадений нет. |
| 2c 31t | sparse-switch vAA, +BBBBBBBB (с дополнительными данными, как указано ниже в разделе "Формат sparse-switch-payload") |
A: регистр для тестированияB: псевдоинструкция со знаком "ветвь" для смещения данных таблицы
(32 бита)
|
Перейти к новой инструкции на основе значения в заданном регистре, используя упорядоченную таблицу пар "значение-смещение", или перейти к следующей инструкции, если совпадений нет. |
| 2д..31 23x | cmpkind vAA, vBB, vCC 2d: cmpl-float (lt bias) 2e: cmpg-float (gt bias) 2f: cmpl-double (lt bias) 30: cmpg-double (gt bias) 31: cmp-long |
A:регистр назначения (8 бит);B: первый исходный регистр или пара;C: второй исходный регистр или пара. |
Выполняет указанное сравнение чисел с плавающей запятой или long, задавая для a значение 0, если b == c, 1, если b > c, или -1, если b < c.
Параметр "bias", указанный для операций с плавающей запятой, определяет, как обрабатываются сравнения NaN: инструкции "gt bias" возвращают 1 для сравнений NaN, а инструкции "lt bias" возвращают -1.
Например, чтобы проверить, является ли значение с плавающей запятой |
| 32..37 22t | if-test vA, vB, +CCCC 32: if-eq 33: if-ne 34: if-lt 35: if-ge 36: if-gt 37: if-le |
A: первый регистр для тестирования (4 бита)B: второй регистр для тестирования (4 бита)C: смещение перехода со знаком (16 бит) |
Переход к указанному пункту назначения, если значения двух регистров соответствуют заданным условиям.
Примечание.
Смещение ветви не должно быть равно |
| 38..3d 21t | if-testz vAA, +BBBB 38: if-eqz 39: if-nez 3a: if-ltz 3b: if-gez 3c: if-gtz 3d: if-lez |
A: регистр для тестирования (8 бит)B: смещение подписанного перехода (16 бит) |
Переход к указанному пункту назначения, если значение указанного регистра сравнивается с нулем в соответствии с заданными условиями.
Примечание. Смещение ветви не должно быть равно |
| 3e..43 10x | (не используется) | (unused) | |
| 44..51 23x | arrayop vAA, vBB, vCC 44: aget 45: aget-wide 46: aget-object 47: aget-boolean 48: aget-byte 49: aget-char 4a: aget-short 4b: aput 4c: aput-wide 4d: aput-object 4e: aput-boolean 4f: aput-byte 50: aput-char 51: aput-short |
A: регистр или пара значений; может быть источником или назначением
(8 бит)B: регистр массива (8 бит)C: индексный регистр (8 бит) |
Выполняет указанную операцию с массивом по указанному индексу заданного массива, загружая или сохраняя значение в регистре значений. |
| 52..5f 22c | iinstanceop vA, vB, field@CCCC 52: iget 53: iget-wide 54: iget-object 55: iget-boolean 56: iget-byte 57: iget-char 58: iget-short 59: iput 5a: iput-wide 5b: iput-object 5c: iput-boolean 5d: iput-byte 5e: iput-char 5f: iput-short |
регистр или пара значений A:; может быть источником или получателем (4 бита)регистр объекта B: (4 бита)индекс ссылки на поле экземпляра C: (16 бит) |
Выполните операцию с полем экземпляра объекта, используя определенное поле, загружая или сохраняя значение в регистре значений.
Примечание. Эти операционные коды подходят для статического связывания, при котором аргумент поля заменяется на более прямое смещение. |
| 60..6d 21c | sstaticop vAA, field@BBBB 60: sget 61: sget-wide 62: sget-object 63: sget-boolean 64: sget-byte 65: sget-char 66: sget-short 67: sput 68: sput-wide 69: sput-object 6a: sput-boolean 6b: sput-byte 6c: sput-char 6d: sput-short |
A:регистр или пара значений; может быть источником или получателем
(8 бит)B: индекс статического поля (16 бит) |
Выполните операцию со статическим полем идентифицированного объекта, используя идентифицированное статическое поле, загружая или сохраняя значение в регистре значений.
Примечание. Эти коды операций можно использовать для статической компоновки, изменив аргумент поля на более прямое смещение. |
| 6e..72 35c | invoke-kind {vC, vD, vE, vF, vG}, meth@BBBB 6e: invoke-virtual 6f: invoke-super 70: invoke-direct 71: invoke-static 72: invoke-interface |
A: количество слов в аргументе (4 бита)B: индекс ссылки на метод (16 бит)C..G: регистры аргументов (по 4 бита)
|
Вызовите указанный метод. Результат (если он есть) может быть сохранен с помощью соответствующего варианта move-result* в качестве следующей инструкции.
Если В файлах Dex версии
Примечание. Эти операционные коды подходят для статического связывания, при котором аргумент метода заменяется на более прямое смещение (или пару смещений). |
| 73 10x | (не используется) | (unused) | |
| 74..78 3rc | invoke-kind/range {vCCCC .. vNNNN}, meth@BBBB 74: invoke-virtual/range 75: invoke-super/range 76: invoke-direct/range 77: invoke-static/range 78: invoke-interface/range |
A: Количество слов в аргументе (8 бит).B: Индекс ссылки на метод (16 бит).C: Регистр первого аргумента (16 бит).N = A + C - 1 |
Вызовите указанный метод. Подробную информацию, предостережения и рекомендации можно найти в первом описании выше.invoke-kind
|
| 79..7a 10x | (не используется) | (не используется) | |
| 7b..8f 12x | unop vA, vB 7b: neg-int 7c: not-int 7d: neg-long 7e: not-long 7f: neg-float 80: neg-double 81: int-to-long 82: int-to-float 83: int-to-double 84: long-to-int 85: long-to-float 86: long-to-double 87: float-to-int 88: float-to-long 89: float-to-double 8a: double-to-int 8b: double-to-long 8c: double-to-float 8d: int-to-byte 8e: int-to-char 8f: int-to-short |
A: регистр или пара регистров назначения (4 бита)B: регистр или пара регистров источника (4 бита) |
Выполните указанную унарную операцию с исходным регистром, сохранив результат в целевом регистре. |
| 90..af 23x | binop vAA, vBB, vCC 90: add-int 91: sub-int 92: mul-int 93: div-int 94: rem-int 95: and-int 96: or-int 97: xor-int 98: shl-int 99: shr-int 9a: ushr-int 9b: add-long 9c: sub-long 9d: mul-long 9e: div-long 9f: rem-long a0: and-long a1: or-long a2: xor-long a3: shl-long a4: shr-long a5: ushr-long a6: add-float a7: sub-float a8: mul-float a9: div-float aa: rem-float ab: add-double ac: sub-double ad: mul-double ae: div-double af: rem-double |
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: div-int/2addr b4: rem-int/2addr b5: and-int/2addr b6: or-int/2addr b7: xor-int/2addr b8: shl-int/2addr b9: shr-int/2addr ba: ushr-int/2addr bb: add-long/2addr bc: sub-long/2addr bd: mul-long/2addr be: div-long/2addr bf: rem-long/2addr c0: and-long/2addr 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 cc: sub-double/2addr cd: mul-double/2addr ce: div-double/2addr cf: rem-double/2addr |
A:Целевой адрес и первый регистр источника или пара регистров (4 бита)B:Второй регистр источника или пара регистров (4 бита) |
Выполните указанную бинарную операцию с двумя исходными регистрами и сохраните результат в первом из них.
Примечание.
В отличие от других математических операций |
| d0..d7 22s | binop/lit16 vA, vB, #+CCCC d0: add-int/lit16 d1: rsub-int (обратное вычитание) d2: mul-int/lit16 d3: div-int/lit16 d4: rem-int/lit16 d5: and-int/lit16 d6: or-int/lit16 d7: xor-int/lit16 |
A: регистр назначения (4 бита)B: исходный регистр (4 бита)C: константа типа signed int (16 бит) |
Выполняет указанную бинарную операцию над указанным регистром (первый аргумент) и литеральным значением (второй аргумент), сохраняя результат в целевом регистре.
Примечание.
У |
| d8..e2 22b | binop/lit8 vAA, vBB, #+CC d8: add-int/lit8 d9: rsub-int/lit8 da: mul-int/lit8 db: div-int/lit8 dc: rem-int/lit8 dd: and-int/lit8 de: or-int/lit8 df: xor-int/lit8 e0: shl-int/lit8 e1: shr-int/lit8 e2: ushr-int/lit8 |
A: целевой регистр (8 бит)B: исходный регистр (8 бит)C: константа со знаком (8 бит) |
Выполняет указанную бинарную операцию над указанным регистром (первый аргумент) и литеральным значением (второй аргумент), сохраняя результат в целевом регистре.
Примечание. Подробные сведения о семантике |
| e3..f9 10x | (unused) | (unused) | |
| fa 45cc | invoke-polymorphic {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.
|
| fb 4rcc | invoke-polymorphic/range {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH |
A: количество слов в аргументе (8 бит) B: индекс ссылки на метод (16 бит) C: получатель (16 бит) H: индекс ссылки на прототип (16 бит) N = A + C - 1
|
Вызовите указанный дескриптор метода. Подробную информацию вы найдете в описании invoke-polymorphic выше.Присутствует в файлах Dex начиная с версии 038.
|
| fc 35c | invoke-custom {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.
|
| fd 3rc | invoke-custom/range {vCCCC .. vNNNN}, call_site@BBBB |
A: Количество слов в аргументе (8 бит) B: Индекс ссылки на место вызова (16 бит) C: Регистр первого аргумента (16 бит) N = A + C - 1
|
Разрешение и вызов сайта вызова. Подробную информацию вы найдете в описании invoke-custom выше.Присутствует в файлах DEX начиная с версии 038.
|
| fe 21c | const-method-handle vAA, method_handle@BBBB | A: Регистр назначения (8 бит)B: Индекс дескриптора метода (16 бит) |
Перемещает ссылку на дескриптор метода, указанный заданным индексом, в указанный регистр. Присутствует в файлах DEX начиная с версии 039.
|
| ff 21c | const-method-type vAA, proto@BBBB | A: регистр назначения (8 бит)B: ссылка на прототип метода (16 бит) |
Перемещает ссылку на прототип метода, указанный заданным индексом, в указанный регистр. Присутствует в файлах DEX начиная с версии 039.
|
Формат полезной нагрузки с коммутацией пакетов
| Название | Формат | Описание |
|---|---|---|
| ident | ushort = 0x0100 | идентификация псевдооперационного кода; |
| размер | ushort | количество записей в таблице; |
| first_key | ПРХВ | первое (и наименьшее) значение оператора switch; |
| целевые объекты | int[] | список из size относительных целевых ветвей. Целевые адреса относятся к адресу кода операции переключения, а не к адресу этой таблицы.
|
Примечание. Общее количество единиц кода для экземпляра этой таблицы – (size * 2) + 4.
Формат полезной нагрузки sparse-switch
| Название | Формат | Описание |
|---|---|---|
| ident | ushort = 0x0200 | идентификация псевдооперационного кода; |
| размер | ushort | количество записей в таблице; |
| ключи | int[] | список значений ключей size, отсортированный по возрастанию; |
| целевые объекты | int[] | список относительных целевых ветвей size, каждая из которых соответствует
значению ключа с тем же индексом. Целевые адреса относятся к адресу кода операции переключения, а не к адресу этой таблицы.
|
Примечание. Общее количество единиц кода для экземпляра этой таблицы – (size * 4) + 2.
Формат полезной нагрузки fill-array-data-payload
| Название | Формат | Описание |
|---|---|---|
| ident | ushort = 0x0300 | идентификация псевдооперационного кода; |
| element_width | ushort | количество байтов в каждом элементе; |
| размер | uint | количество элементов в таблице |
| данные | ubyte[] | значения данных |
Примечание. Общее количество единиц кода для экземпляра этой таблицы – (size * element_width + 1) / 2 + 4.
Сведения о математической операции
Примечание. Операции с плавающей запятой должны выполняться в соответствии с правилами IEEE 754 с использованием округления до ближайшего и постепенного переполнения, если не указано иное.
| Код операции | Семантика C | Примечания |
|---|---|---|
| neg-int | int32 a; int32 result = -a; |
Унарное дополнение до двух. |
| not-int | int32 a; int32 result = ~a; |
Унарное дополнение до единицы. |
| neg-long | int64 a; int64 result = -a; |
Унарное дополнение до двух. |
| недолго | int64 a; int64 result = ~a; |
Унарное дополнение до единицы. |
| neg-float | float a; float result = -a; |
Отрицание числа с плавающей запятой. |
| neg-double | double a; double result = -a; |
Отрицание числа с плавающей запятой. |
| int-to-long | int32 a; int64 result = (int64) a; |
Подпишите расширение int32 в int64. |
| int-to-float | int32 a; float result = (float) a; |
Конвертация int32 в float с округлением до ближайшего целого числа. Это приводит к потере точности для некоторых значений.
|
| int-to-double | int32 a; double result = (double) a; |
Конвертация int32 в double. |
| long-to-int | int64 a; int32 result = (int32) a; |
Усечение текста int64 до int32. |
| long-to-float | int64 a; float result = (float) a; |
Конвертация int64 в float с округлением до ближайшего целого числа. Это приводит к потере точности для некоторых значений.
|
| long-to-double | int64 a; double result = (double) a; |
Преобразование int64 в double с округлением к ближайшему. Это приводит к потере точности для некоторых значений.
|
| float-to-int | float a; int32 result = (int32) a; |
Конвертация float в int32 с округлением до нуля. NaN и -0.0 (отрицательный ноль) преобразуются в целое число 0. Бесконечности и значения, которые слишком велики, чтобы быть представленными, преобразуются в 0x7fffffff или -0x80000000 в зависимости от знака.
|
| float-to-long | float a; int64 result = (int64) a; |
Конвертация float в int64 с округлением до нуля. Здесь действуют те же правила, что и для float-to-int, за исключением того, что значения вне диапазона преобразуются в 0x7fffffffffffffff или -0x8000000000000000 в зависимости от знака.
|
| float-to-double | float a; double result = (double) a; |
Преобразование float в double с точным сохранением значения.
|
| double-to-int | double a; int32 result = (int32) a; |
Конвертация double в int32 с округлением до нуля. Здесь действуют те же правила, что и для float-to-int.
|
| double-to-long | double a; int64 result = (int64) a; |
Преобразование double в int64 с округлением в сторону нуля. Для него действуют те же правила, что и для float-to-long.
|
| double-to-float | double a; float result = (float) a; |
Конвертация double в float с округлением до ближайшего целого числа. Это приводит к потере точности для некоторых значений.
|
| int-to-byte | int32 a; int32 result = (a << 24) >> 24; |
Усечение int32 до int8, знак
продлевает результат.
|
| int-to-char | int32 a; int32 result = a & 0xffff; |
Усечение int32 до uint16 без расширения знака.
|
| int-to-short | int32 a; int32 result = (a << 16) >> 16; |
Усечение int32 до int16, знак
продлевает результат.
|
| add-int | int32 a, b; int32 result = a + b; |
Сложение в дополнительном коде. |
| sub-int | int32 a, b; int32 result = a - b; |
Вычитание в дополнительном коде. |
| rsub-int | int32 a, b; int32 result = b - a; |
Вычитание с использованием обратного кода. |
| mul-int | int32 a, b; int32 result = a * b; |
Умножение в дополнительном коде. |
| div-int | int32 a, b; int32 result = a / b; |
Деление с дополнением до двух, округление до нуля (то есть усечение до целого числа). Если b == 0, возвращается ArithmeticException.
|
| rem-int | int32 a, b; int32 result = a % b; |
Остаток от деления в дополнительном коде. Знак результата совпадает со знаком a и точнее определяется как result == a - (a / b) * b. В этом случае будет сгенерирована ошибка ArithmeticException, если b == 0.
|
| and-int | int32 a, b; int32 result = a & b; |
Побитовое И. |
| or-int | int32 a, b; int32 result = a | b; |
Побитовое ИЛИ. |
| xor-int | int32 a, b; int32 result = a ^ b; |
Побитовое исключающее ИЛИ. |
| shl-int | int32 a, b; int32 result = a << (b & 0x1f); |
Побитовый сдвиг влево (с маскированным аргументом). |
| shr-int | int32 a, b; int32 result = a >> (b & 0x1f); |
Побитовый сдвиг вправо со знаком (с маскированным аргументом). |
| ushr-int | uint32 a, b; int32 result = a >> (b & 0x1f); |
Побитовый сдвиг вправо без знака (с маскированным аргументом). |
| add-long | int64 a, b; int64 result = a + b; |
Сложение в дополнительном коде. |
| sub-long | int64 a, b; int64 result = a - b; |
Вычитание в дополнительном коде. |
| mul-long | int64 a, b; int64 result = a * b; |
Умножение с дополнением до двух. |
| div-long | int64 a, b; int64 result = a / b; |
Деление с дополнением до двух, округленное до нуля (то есть усеченное до целого числа). В этом случае будет сгенерирована ошибка ArithmeticException, если
b == 0.
|
| rem-long | int64 a, b; int64 result = a % b; |
Остаток от деления в дополнительном коде. Знак результата совпадает со знаком a и точнее определяется как result == a - (a / b) * b. В этом случае будет сгенерирована ошибка ArithmeticException, если b == 0.
|
| and-long | int64 a, b; int64 result = a & b; |
Побитовое И. |
| или-длинный | int64 a, b; int64 result = a | b; |
Побитовое ИЛИ. |
| xor-long | int64 a, b; int64 result = a ^ b; |
Побитовое исключающее ИЛИ. |
| shl-long | int64 a; int32 b; int64 result = a << (b & 0x3f); |
Побитовый сдвиг влево (с маскированным аргументом). |
| shr-long | int64 a; int32 b; int64 result = a >> (b & 0x3f); |
Побитовый сдвиг вправо со знаком (с маскированным аргументом). |
| ushr-long | uint64 a; int32 b; int64 result = a >> (b & 0x3f); |
Побитовый сдвиг вправо без знака (с маскированным аргументом). |
| add-float | float a, b; float result = a + b; |
Сложение чисел с плавающей запятой. |
| sub-float | float a, b; float result = a - b; |
Вычитание чисел с плавающей запятой. |
| mul-float | float a, b; float result = a * b; |
Умножение чисел с плавающей запятой. |
| div-float | float a, b; float result = a / b; |
Деление с плавающей запятой. |
| rem-float | float a, b; float result = a % b; |
Остаток от деления с плавающей запятой. Эта функция отличается от остатка от деления по стандарту IEEE 754 и определяется как result == a - roundTowardZero(a / b) * b.
|
| add-double | double a, b; double result = a + b; |
Сложение чисел с плавающей запятой. |
| sub-double | double a, b; double result = a - b; |
Вычитание чисел с плавающей запятой. |
| mul-double | double a, b; double result = a * b; |
Умножение чисел с плавающей запятой. |
| div-double | double a, b; double result = a / b; |
Деление с плавающей запятой. |
| rem-double | double a, b; double result = a % b; |
Остаток от деления с плавающей запятой. Эта функция отличается от остатка от деления по стандарту IEEE 754 и определяется как result == a - roundTowardZero(a / b) * b.
|