以下为从官网复制的一份,方便不查看。
官方地址:https://source.android.com/devices/tech/dalvik/instruction-formats
https://source.android.com/devices/tech/dalvik/dalvik-bytecode
· 机器模型和调用规范旨在大致模仿常见的真实架构和 C 样式的调用规范:
· 机器基于寄存器,而帧的大小在创建时确定后就固定不变。每一帧由特定数量的寄存器(由相应方法指定)以及执行该方法所需的所有辅助数据构成,例如(但不限于)程序计数器和对包含该方法的 .dex
文件的引用。
· 当用于位值(例如整数和浮点数)时,寄存器会被视为宽度为 32 位。如果值是 64 位,则使用两个相邻的寄存器。对于寄存器对,没有对齐要求。
· 当用于对象引用时,寄存器会被视为其宽度能够正好容纳一个此类引用。
· 对于按位表示,(Object) null == (int) 0
。
· 如果一个方法有 N 个参数,则在该方法的调用帧的最后N 个寄存器中按顺序传递参数。较宽的参数占用两个寄存器。给实例方法传递一个 this
引用作为其第一个参数。
· 指令流中的存储单元是 16 位无符号数。某些指令中的某些位会被忽略/必须为 0。
· 指令并非一定限于特定类型。例如,在不做任何解释的情况下移动 32 位寄存器值的指令不一定非得指定是在移动整数还是浮点数。
· 对字符串、类型、字段和方法的引用有单独枚举和已编入索引的常量池。
· 按位字面数据在指令流中内嵌表示。
· 在实践中,一个方法需要 16 个以上的寄存器不太常见,而需要8 个以上的寄存器却相当普遍,因此很多指令仅限于寻址前16 个寄存器。在合理的可能情况下,指令允许引用最多前256 个寄存器。此外,某些指令还具有允许更多寄存器的变体,包括可寻址 v0
- v65535
范围内的寄存器的一对catch-all move
指令。如果指令变体不能用于寻址所需的寄存器,寄存器内容会(在运算前)从原始寄存器移动到低位寄存器和/或(在运算后)从低位结果寄存器移动到高位寄存器。
· 存在几个“伪指令”,用来容纳被常规指令(例如,fill-array-data
)引用的可变长度数据有效负荷。在正常的执行流程中绝对不能遇到这类指令。此外,这类指令必须位于偶数字节码偏移(即以 4 字节对齐)上。为了满足这一要求,如果这类指令未对齐,则 dex 生成工具必须发出额外的 nop
指令来进行填充。最后,虽然并非必须这样做,但是大多数工具会选择在方法的末尾发出这些额外的指令,否则可能需要在这些方法周围分布额外的指令。
· 如果安装到正在运行的系统中,那么在安装过程中,静态链接优化可能会更改某些指令的格式。这样可以在链接已知之后加快执行的速度。有关建议的变体,请参阅相关的指令格式文档。使用“建议”一词是因为并非必须强制实施这些变体。
· 人类语法和助记符:
· 对参数进行 Dest-then-source 排序。
· 一些运算码具有消除歧义的名称后缀,这些后缀用来表明运算类型:
· 常规类型的 32 位运算码未标记。
· 常规类型的 64 位运算码以 -wide
为后缀。
· 特定类型的运算码以其类型(或简单缩写)为后缀,这些类型包括:-boolean
、-byte
、-char
、-short
、-int
、-long
、-float
、-double
、-object
、-string
、-class
和 -void
。
· 一些运算码具有消除歧义的后缀,这些后缀用于区分具有不同指令版式或选项的相同运算。这些后缀与主要名称之间以斜杠(“/
”)分开,主要目的是使生成和解析可执行文件的代码中存在与静态常量的一对一映射关系(即,降低让代码查看者感到模糊不清的可能性)。
· 在本文档的说明部分,我们使用 4 位宽的字符来强调值的宽度(例如,表示常量的范围或可能寻址的寄存器的数量)。
· 例如,在指令“move-wide/from16 vAA, vBBBB
”中:
· “move
”为基础运算码,表示这是基本运算(移动寄存器的值)。
· “wide
”为名称后缀,表示指令对较宽(64位)数据进行运算。
· “from16
”为运算码后缀,表示具有 16 位寄存器引用源的变体。
· “vAA
”为目标寄存器(隐含在运算中;并且,规定目标参数始终在前),取值范围为 v0
- v255
。
· “vBBBB
”为源寄存器,取值范围为 v0
- v65535
。
· 请参阅指令格式文档,详细了解各种指令格式(在“运算和格式”下列出)以及运算码语法。
· 请参阅 .dex
文件格式文档,详细了解字节码如何融入整个编码环境。
运算和格式 |
助记符/语法 |
参数 |
说明 |
00 10x |
nop |
|
空循环。 注意:数据传送伪指令用此运算码来标记,在这种情况下, 运算码单元的高阶字节表示数据的性质。请参阅下文的“ |
01 12x |
move vA, vB |
|
将一个非对象寄存器的内容移到另一个非对象寄存器中。 |
02 22x |
move/from16 vAA, vBBBB |
|
将一个非对象寄存器的内容移到另一个非对象寄存器中。 |
03 32x |
move/16 vAAAA, vBBBB |
|
将一个非对象寄存器的内容移到另一个非对象寄存器中。 |
04 12x |
move-wide vA, vB |
|
将一个寄存器对的内容移到另一个寄存器对中。 注意:可以从 写入运算之前,为要读取的寄存器对的两部分均安排实现。 |
05 22x |
move-wide/from16 vAA, vBBBB |
|
将一个寄存器对的内容移到另一个寄存器对中。 注意:实现的注意事项与上文的 |
06 32x |
move-wide/16 vAAAA, vBBBB |
|
将一个寄存器对的内容移到另一个寄存器对中。 注意:实现的注意事项与上文的 |
07 12x |
move-object vA, vB |
|
将一个对象传送寄存器的内容移到另一个对象传送寄存器中。 |
08 22x |
move-object/from16 vAA, vBBBB |
|
将一个对象传送寄存器的内容移到另一个对象传送寄存器中。 |
09 32x |
move-object/16 vAAAA, vBBBB |
|
将一个对象传送寄存器的内容移到另一个对象传送寄存器中。 |
0a 11x |
move-result vAA |
|
将最新的 |
0b 11x |
move-result-wide vAA |
|
将最新的 |
0c 11x |
move-result-object vAA |
|
将最新的 |
0d 11x |
move-exception vAA |
|
将刚刚捕获的异常保存到给定寄存器中。该指令必须为捕获的异常不会被忽略的任何异常处理程序的第一条指令,且该指令必须仅作为异常处理程序的第一条指令执行,否则无效。 |
0e 10x |
return-void |
|
从 |
0f 11x |
return vAA |
|
从单字宽度(32 位)非对象值返回方法返回。 |
10 11x |
return-wide vAA |
|
从双字宽度(64 位)值返回方法返回。 |
11 11x |
return-object vAA |
|
从对象返回方法返回。 |
12 11n |
const/4 vA, #+B |
|
将给定的字面值(符号扩展为 32 位)移到指定的寄存器中。 |
13 21s |
const/16 vAA, #+BBBB |
|
将给定的字面值(符号扩展为 32 位)移到指定的寄存器中。 |
14 31i |
const vAA, #+BBBBBBBB |
|
将给定的字面值移到指定的寄存器中。 |
15 21h |
const/high16 vAA, #+BBBB0000 |
|
将给定的字面值(右零扩展为 32 位)移到指定的寄存器中。 |
16 21s |
const-wide/16 vAA, #+BBBB |
|
将给定的字面值(符号扩展为 64 位)移到指定的寄存器对中。 |
17 31i |
const-wide/32 vAA, #+BBBBBBBB |
|
将给定的字面值(符号扩展为 64 位)移到指定的寄存器对中。 |
18 51l |
const-wide vAA, #+BBBBBBBBBBBBBBBB |
|
将给定的字面值移到指定的寄存器对中。 |
19 21h |
const-wide/high16 vAA, #+BBBB000000000000 |
|
将给定的字面值(右零扩展为 64 位)移到指定的寄存器对中。 |
1a 21c |
const-string vAA, string@BBBB |
|
将通过给定的索引获取的字符串引用移到指定的寄存器中。 |
1b 31c |
const-string/jumbo vAA, string@BBBBBBBB |
|
将通过给定的索引获取的字符串引用移到指定的寄存器中。 |
1c 21c |
const-class vAA, type@BBBB |
|
将通过给定的索引获取的类引用移到指定的寄存器中。如果指定的类型是原始类型,则将存储对原始类型的退化类的引用。 |
1d 11x |
monitor-enter vAA |
|
获取指定对象的监视锁。 |
1e 11x |
monitor-exit vAA |
|
释放指定对象的监视锁。 注意:如果该指令需要抛出异常,则必须以 pc 已提前超出该指令的方式抛出。不妨将其想象成,该指令(在一定意义上)已成功执行,并且在该指令之后但又在下一条指令找到机会执行之前抛出异常。这种定义使得某个方法有可能将监视锁清理 catch-all(例如 |
1f 21c |
check-cast vAA, type@BBBB |
|
如果给定寄存器中的引用不能转型为指定的类型,则抛出 注意:由于 |
20 22c |
instance-of vA, vB, type@CCCC |
|
如果指定的引用是给定类型的实例,则为给定目标寄存器赋值 注意:由于 |
21 12x |
array-length vA, vB |
|
将指定数组的长度(条目个数)赋值给给定目标寄存器 |
22 21c |
new-instance vAA, type@BBBB |
|
根据指定的类型构造新实例,并将对该新实例的引用存储到目标寄存器中。该类型必须引用非数组类。 |
23 22c |
new-array vA, vB, type@CCCC |
|
根据指定的类型和大小构造新数组。该类型必须是数组类型。 |
24 35c |
filled-new-array {vC, vD, vE, vF, vG}, type@BBBB |
|
根据给定类型和大小构造数组,并使用提供的内容填充该数组。该类型必须是数组类型。数组的内容必须是单字类型(即不接受 |
25 3rc |
filled-new-array/range {vCCCC .. vNNNN}, type@BBBB |
|
根据给定类型和大小构造数组,并使用提供的内容填充该数组。相关的说明和限制与上文所述 |
26 31t |
fill-array-data vAA, +BBBBBBBB(有关补充数据,请参阅下文的“ |
|
用指定的数据填充给定数组。必须引用原始类型的数组,且数据表格的类型必须与数组匹配;此外,数据表格所包含的元素个数不得超出数组中的元素个数。也就是说,数组可能比表格大;如果是这样,仅设置数组的初始元素,而忽略剩余元素。 |
27 11x |
throw vAA |
|
抛出指定的异常。 |
28 10t |
goto +AA |
|
无条件地跳转到指定的指令。 注意:分支偏移量不得为 |
29 20t |
goto/16 +AAAA |
|
无条件地跳转到指定的指令。 注意:分支偏移量不得为 |
2a 30t |
goto/32 +AAAAAAAA |
|
无条件地跳转到指定的指令。 |
2b 31t |
packed-switch vAA, +BBBBBBBB(有关补充数据,请参阅下文的“ |
|
通过使用与特定整数范围内的每个值相对应的偏移量表,基于给定寄存器中的值跳转到新指令;如果没有匹配项,则跳转到下一条指令。 |
2c 31t |
sparse-switch vAA, +BBBBBBBB(有关补充数据,请参阅下文的“ |
|
通过使用偏移值对的有序表,基于给定寄存器中的值跳转到新指令;如果没有匹配项,则跳转到下一条指令。 |
2d..31 23x |
cmpkind vAA, vBB, vCC |
|
执行指定的浮点或 例如,建议使用 |
32..37 22t |
if-test vA, vB, +CCCC |
|
如果两个给定寄存器的值比较结果符合预期,则分支到给定目标寄存器。 注意:分支偏移量不得为 |
38..3d 21t |
if-testz vAA, +BBBB |
|
如果给定寄存器的值与 0 的比较结果符合预期,则分支到给定目标寄存器。 注意:分支偏移量不得为 |
3e..43 10x |
(未使用) |
|
(未使用) |
44..51 23x |
arrayop vAA, vBB, vCC |
|
在给定数组的已标识索引处执行已确定的数组运算,并将结果加载或存储到值寄存器中。 |
52..5f 22c |
iinstanceop vA, vB, field@CCCC |
|
对已标识的字段执行已确定的对象实例字段运算,并将结果加载或存储到值寄存器中。 注意:这些运算码是静态链接的合理候选项,将字段参数更改为更直接的偏移量。 |
60..6d 21c |
sstaticop vAA, field@BBBB |
|
对已标识的静态字段执行已确定的对象静态字段运算,并将结果加载或存储到值寄存器中。 注意:这些运算码是静态链接的合理候选项,将字段参数更改为更直接的偏移量。 |
6e..72 35c |
invoke-kind {vC, vD, vE, vF, vG}, meth@BBBB |
|
调用指定的方法。所得结果(如果有的话)可能与紧跟其后的相应 使用 当 在版本
注意:这些运算码是静态链接的合理候选项,将方法参数更改为更直接的偏移量(或相关的寄存器对)。 |
73 10x |
(未使用) |
|
(未使用) |
74..78 3rc |
invoke-kind/range {vCCCC .. vNNNN}, meth@BBBB |
|
调用指定的方法。有关详情、注意事项和建议,请参阅上文第一个 |
79..7a 10x |
(未使用) |
|
(未使用) |
7b..8f 12x |
unop vA, vB |
|
对源寄存器执行已确定的一元运算,并将结果存储到目标寄存器中。 |
90..af 23x |
binop vAA, vBB, vCC |
|
对两个源寄存器执行已确定的二元运算,并将结果存储到目标寄存器中。 注意:与其他 |
b0..cf 12x |
binop/2addr vA, vB |
|
对两个源寄存器执行已确定的二元运算,并将结果存储到第一个源寄存器中。 注意:与其他 |
d0..d7 22s |
binop/lit16 vA, vB, #+CCCC |
|
对指定的寄存器(第一个参数)和字面值(第二个参数)执行指定的二元运算,并将结果存储到目标寄存器中。 注意: |
d8..e2 22b |
binop/lit8 vAA, vBB, #+CC |
|
对指定的寄存器(第一个参数)和字面值(第二个参数)执行指定的二元运算,并将结果存储到目标寄存器中。 注意:有关 |
e3..f9 10x |
(未使用) |
|
(未使用) |
fa 45cc |
invoke-polymorphic {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH |
|
调用指定的签名多态方法。所得结果(如果有的话)可能与紧跟其后的相应 |
fb 4rcc |
invoke-polymorphic/range {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH |
|
调用指定的方法句柄。有关详情,请参阅上文的 |
fc 35c |
invoke-custom {vC, vD, vE, vF, vG}, call_site@BBBB |
|
解析并调用指定的调用点。调用的结果(如果有的话)可能与紧跟其后的相应 · 该引导程序链接器方法无法返回 · 返回的 · 该方法句柄目标不属于所请求的类型。 存在于版本 |
fd 3rc |
invoke-custom/range {vCCCC .. vNNNN}, call_site@BBBB |
|
解析并调用一个调用点。有关详情,请参阅上文的 |
fe 21c |
const-method-handle vAA, method_handle@BBBB |
|
将通过特定索引指定的方法句柄的引用移到指定的寄存器中。 |
ff 21c |
const-method-type vAA, proto@BBBB |
|
将通过特定索引指定的方法原型的引用移到指定的寄存器中。 |
名称 |
格式 |
说明 |
ident |
ushort = 0x0100 |
识别伪运算码 |
Size |
ushort |
表格中的条目数 |
first_key |
int |
第一位(即最低位)switch case 的值 |
targets |
int[] |
与 |
注意:此表格一个实例的代码单元总数为 (size * 2) + 4
。
名称 |
格式 |
说明 |
ident |
ushort = 0x0200 |
识别伪运算码 |
Size |
ushort |
表格中的条目数 |
keys |
int[] |
|
targets |
int[] |
与 |
注意:此表格一个实例的代码单元总数为 (size * 4) + 2
。
名称 |
格式 |
说明 |
ident |
ushort = 0x0300 |
识别伪运算码 |
element_width |
ushort |
每个元素的字节数 |
Size |
uint |
表格中的元素数 |
data |
ubyte[] |
数据值 |
注意:此表格一个实例的代码单元总数为 (size *element_width + 1) / 2 + 4
。
注意:除非另有说明,否则浮点运算必须遵循 IEEE 754 规则,使用最近舍入和渐进式下溢。
运算码 |
C 语义 |
备注 |
neg-int |
int32 a; |
一元二进制补码。 |
not-int |
int32 a; |
一元反码。 |
neg-long |
int64 a; |
一元二进制补码。 |
not-long |
int64 a; |
一元反码。 |
neg-float |
float a; |
浮点否定。 |
neg-double |
double a; |
浮点否定。 |
int-to-long |
int32 a; |
将 |
int-to-float |
int32 a; |
使用最近舍入,将 |
int-to-double |
int32 a; |
将 |
long-to-int |
int64 a; |
将 |
long-to-float |
int64 a; |
使用最近舍入,将 |
long-to-double |
int64 a; |
使用最近舍入,将 |
float-to-int |
float a; |
使用向零舍入,将 |
float-to-long |
float a; |
使用向零舍入,将 |
float-to-double |
float a; |
将 |
double-to-int |
double a; |
使用向零舍入,将 |
double-to-long |
double a; |
使用向零舍入,将 |
double-to-float |
double a; |
使用最近舍入,将 |
int-to-byte |
int32 a; |
符号扩展结果,将 |
int-to-char |
int32 a; |
无需符号扩展,将 |
int-to-short |
int32 a; |
符号扩展结果,将 |
add-int |
int32 a, b; |
二进制补码加法。 |
sub-int |
int32 a, b; |
二进制补码减法。 |
rsub-int |
int32 a, b; |
二进制补码反向减法。 |
mul-int |
int32 a, b; |
二进制补码乘法。 |
div-int |
int32 a, b; |
二进制补码除法,向零舍入(即截断为整数)。如果 |
rem-int |
int32 a, b; |
二进制补码除后取余数。结果的符号与 |
and-int |
int32 a, b; |
按位 AND。 |
or-int |
int32 a, b; |
按位 OR。 |
xor-int |
int32 a, b; |
按位 XOR。 |
shl-int |
int32 a, b; |
按位左移(带掩码参数)。 |
shr-int |
int32 a, b; |
按位有符号右移(带掩码参数)。 |
ushr-int |
uint32 a, b; |
按位无符号右移(带掩码参数)。 |
add-long |
int64 a, b; |
二进制补码加法。 |
sub-long |
int64 a, b; |
二进制补码减法。 |
mul-long |
int64 a, b; |
二进制补码乘法。 |
div-long |
int64 a, b; |
二进制补码除法,向零舍入(即截断为整数)。如果 |
rem-long |
int64 a, b; |
二进制补码除后取余数。结果的符号与 |
and-long |
int64 a, b; |
按位 AND。 |
or-long |
int64 a, b; |
按位 OR。 |
xor-long |
int64 a, b; |
按位 XOR。 |
shl-long |
int64 a; |
按位左移(带掩码参数)。 |
shr-long |
int64 a; |
按位有符号右移(带掩码参数)。 |
ushr-long |
uint64 a; |
按位无符号右移(带掩码参数)。 |
add-float |
float a, b; |
浮点加法。 |
sub-float |
float a, b; |
浮点减法。 |
mul-float |
float a, b; |
浮点乘法。 |
div-float |
float a, b; |
浮点除法。 |
rem-float |
float a, b; |
浮点除后取余数。该函数不同于 IEEE 754 取余,定义为 |
add-double |
double a, b; |
浮点加法。 |
sub-double |
double a, b; |
浮点减法。 |
mul-double |
double a, b; |
浮点乘法。 |
div-double |
double a, b; |
浮点除法。 |
rem-double |
double a, b; |
浮点除后取余数。该函数不同于 IEEE 754 取余,定义为 |
按位描述
格式表的第一列列出了格式的按位布局。它由一个或多个空格分隔的“单词”组成,每个单词描述一个 16 位代码单元。单词中的每个字符代表四位,从高位往低位读取,并使用竖线 (“|”)分隔以方便阅读。从“A”开始的大写字母用于表示格式中的字段,这些字段随后由语法列做进一步定义。“op”一词用于表示格式内八位操作码的位置。带斜划的零(“Ø”)用于表示所有在指示位置的位必须为零。
一般而言,在一个代码单元内,字母的顺序为,较早的代码单元对应的字母在前,后期的代码单元对应的字母在后,按照从低阶到高阶排序。但是,这种一般规则存在一些例外情况,主要是为了让含义相似的部分在不同的指令格式中使用相同的命名。格式说明对这些情况进行了明确的描述。
例如,“B|A|op CCCC”格式表示其包含两个 16 位代码单元。第一个字由低 8 位中的操作码和高 8 位中的两个四位值组成;第二个字由单个 16 位值组成。
格式 ID
格式表中的第二列表示格式的短标识符,用于在其他文档和代码中识别该格式。
大多数格式 ID 包含三个字符:前两个是十进制数,最后一个是字母。第一个十进制数表示格式中 16 位代码单元的数量。第二个十进制数表示格式包含的最大寄存器数量(使用最大值是因为某些格式可容纳的寄存器数量为可变值),特殊标识“r”表示已对寄存器的数量范围进行编码。最后一个字母以半助记符的形式表示该格式编码的任何其他数据类型。例如,“21t”格式的长度为 2,包含一个寄存器引用,另外还有一个分支目标。
建议使用的静态链接格式有一个额外的“s”后缀,因此加上后缀一共是四个字符。同样,建议使用的“内联”链接格式也有一个额外的“i”后缀。(在这种情况下,内联链接与静态链接类似,但它与机器实现具有更直接的联系。)最后,几个建议使用的奇怪格式(例如,“20bc”)包含两个数据块,它们均体现在格式 ID 中。
类型代码字母的完整列表如下。请注意,由于格式上的差异,部分形式的大小可能有所不同:
助记符 |
位数 |
含义 |
b |
8 |
有符号立即数(字节) |
c |
16、32 |
常量池索引 |
f |
16 |
接口常量(仅对静态链接格式有效) |
h |
16 |
有符号立即数(32 位或 64 位值的高阶位,低阶位全为 0) |
i |
32 |
有符号立即数(整型)或 32 位浮点数 |
l |
64 |
有符号立即数(长整型)或 64 位双精度浮点数 |
m |
16 |
方法常量(仅对静态链接格式有效) |
n |
4 |
有符号立即数(半字节) |
s |
16 |
有符号立即数(短整型) |
t |
8、16、32 |
分支目标 |
x |
0 |
无额外数据 |
语法
格式表的第三列指出了指令中所使用的人类可识别的语法。每个指令以命名的操作码开始,后面可选择使用一个或多个参数,并且参数之间用逗号分隔。
当参数指第一列中的某个字段时,该字段的字母将在语法中出现,并在字段中每四位重复一次。例如,第一列中标记为“BB”的八位字段在语法列中也将标记为“BB”。
命名寄存器的参数形式为“vX”。选择“v”而不是更常用的“r”作为前缀,是因为这样可避免与可能会在其上实现Dalvik 可执行格式的(非虚拟)架构(其寄存器使用“r”作为前缀)出现冲突。(也就是说,我们可以直截了当地同时讨论虚拟和实际寄存器。)
表示字面值的参数形式为“#+X”。有些格式表示高阶位仅为非零位的字面量;对于这种类型的字面量,在语法表示时会明确写出后面的 0,但是在按位表示时这些 0 会被省略。
表示相对指令地址偏移量的参数形式为“+X”。
表示字面量常量池索引的参数形式为“kind@X”,其中“kind”表示正在引用的常量池。每个使用此类格式的操作码明确地表示只允许使用一种常量;请查看操作码参考,找出对应关系。常量池的种类包括“string”(字符串池索引)、“type”(类型池索引)、“field”(字段池索引)、“meth”(方法池索引)和“site”(调用点索引)。
此外还可使用一些建议的可选形式,它们与常量池索引的表示类似,表示预链接的偏移量或索引。可以使用两种类型的建议预链接值:vtable 偏移(表示为“vtaboff”)和字段偏移(表示为“fieldoff”)。
如果格式值并非明确地包含在语法中,而是选择使用某种变体,则每个变体都以“[X=N]”(例如,“[A=2]”)为前缀来表示对应关系
格式
格式 |
ID |
语法 |
包含的重要操作码 |
无 |
00x |
N/A |
用于未使用操作码的伪格式;建议用作断点操作码的标称格式 |
ØØ|op |
10x |
op |
|
B|A|op |
12x |
Op vA, vB |
|
11n |
Op vA, #+B |
|
|
AA|op |
11x |
Op vAA |
goto |
10t |
Op +AA |
||
ØØ|op AAAA |
20t |
Op +AAAA |
goto/16 |
AA|op BBBB |
20bc |
Op AA, kind@BBBB |
静态确定验证错误的建议格式;其中,A 表示错误类型,B 表示适当类型的表索引(例如,出现“不存在这种方法”错误时的方法引用) |
AA|op BBBB |
22x |
Op vAA, vBBBB |
|
21t |
Op vAA, +BBBB |
|
|
21s |
Op vAA, #+BBBB |
|
|
21h |
Op vAA, #+BBBB0000 |
|
|
op vAA, #+BBBB000000000000 |
|
||
21c |
Op vAA, type@BBBB |
check-cast |
|
Op vAA, field@BBBB |
const-class |
||
Op vAA, method_handle@BBBB |
const-method-handle |
||
Op vAA, proto@BBBB |
const-method-type |
||
Op vAA, string@BBBB |
const-string |
||
AA|op CC|BB |
23x |
Op vAA, vBB, vCC |
|
22b |
Op vAA, vBB, #+CC |
|
|
B|A|op CCCC |
22t |
Op vA, vB, +CCCC |
|
22s |
Op vA, vB, #+CCCC |
|
|
22c |
Op vA, vB, type@CCCC |
instance-of |
|
Op vA, vB, field@CCCC |
|||
22cs |
op vA, vB, fieldoff@CCCC |
22c 格式的静态链接字段访问指令的建议格式 |
|
ØØ|op AAAAAAAA |
30t |
Op +AAAAAAAA |
|
ØØ|op AAAA BBBB |
32x |
Op vAAAA, vBBBB |
|
AA|op BBBBloBBBBhi |
31i |
Op vAA, #+BBBBBBBB |
|
31t |
Op vAA, +BBBBBBBB |
|
|
31c |
Op vAA, string@BBBBBBBB |
const-string/jumbo |
|
A|G|op BBBB F|E|D|C |
35c |
[A=5] op {vC, vD, vE, vF, vG}, meth@BBBB |
|
[A=5] op {vC, vD, vE, vF, vG}, site@BBBB |
|||
[A=5] op {vC, vD, vE, vF, vG}, type@BBBB |
|||
[A=4] op {vC, vD, vE, vF}, kind@BBBB |
|||
[A=3] op {vC, vD, vE}, kind@BBBB |
|||
[A=2] op {vC, vD}, kind@BBBB |
|||
|
|||
[A=0] op {}, kind@BBBB |
|||
此处的特殊字母选择反映出其目的在于使计数和引用索引的标签与 3rc 格式中的标签一样。 |
|||
35ms |
[A=5] op {vC, vD, vE, vF, vG}, vtaboff@BBBB |
35c 格式的静态链接 invoke-virtual和 invoke-super指令的建议格式
|
|
[A=4] op {vC, vD, vE, vF}, vtaboff@BBBB |
|||
[A=3] op {vC, vD, vE}, vtaboff@BBBB |
|||
[A=2] op {vC, vD}, vtaboff@BBBB |
|||
[A=1] op {vC}, vtaboff@BBBB |
|||
此处的特殊字母选择反映出其目的在于使计数和引用索引的标签与 3rms 格式中的标签一样。 |
|||
35mi |
[A=5] op {vC, vD, vE, vF, vG}, inline@BBBB |
35c 格式内联链接 invoke-static和 invoke-virtual指令的建议格式 |
|
[A=4] op {vC, vD, vE, vF}, inline@BBBB |
|||
[A=3] op {vC, vD, vE}, inline@BBBB |
|||
[A=2] op {vC, vD}, inline@BBBB |
|||
[A=1] op {vC}, inline@BBBB |
|||
此处的特殊字母选择反映出其目的在于使计数和引用索引的标签与 3rmi 格式中的标签一样。 |
|||
AA|op BBBB CCCC |
3rc |
Op {vCCCC .. vNNNN}, meth@BBBB 其中 NNNN = CCCC+AA-1,即 A确定计数 0..255,C确定第一个寄存器 |
|
3rms |
Op {vCCCC .. vNNNN}, vtaboff@BBBB 其中 NNNN = CCCC+AA-1,即 A 确定计数 0..255,C 确定第一个寄存器 |
3rc格式的静态链接 invoke-virtual和 invoke-super指令的建议格式 |
|
3rmi |
Op {vCCCC .. vNNNN}, inline@BBBB 其中 NNNN = CCCC+AA-1,即 A 确定计数 0..255,C 确定第一个寄存器 |
3rc 格式的内联链接 invoke-static和 invoke-virtual指令的建议格式 |
|
A|G|op BBBB F|E|D|C HHHH |
45cc |
[A=5] op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH |
invoke-polymorphic |
[A=4] op {vC, vD, vE, vF}, meth@BBBB, proto@HHHH |
|||
[A=3] op {vC, vD, vE}, meth@BBBB, proto@HHHH |
|||
[A=2] op {vC, vD}, meth@BBBB, proto@HHHH |
|||
[A=1] op {vC}, meth@BBBB, proto@HHHH |
|||
AA|op BBBB CCCC HHHH |
4rcc |
op> {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH 其中NNNN = CCCC+AA-1,即A确定计数0..255,C确定第一个寄存器 |
invoke-polymorphic/range |
AA|op BBBBloBBBB BBBB BBBBhi |
51l |
|
const-wide |