Dalvik 可执行指令格式

本页列出了 Dalvik 可执行文件 (DEX) 格式和 Dalvik 字节码使用的指令格式。它旨在与字节码参考文档结合使用。

按位描述

格式表中的第一列列出了格式的按位布局。它由一个或多个空格分隔的“字词”组成,每个词词描述一个 16 位代码单元。一个词词中的每个字符表示四个位,从高位到低位读取,并用竖线 (“|”) 穿插以帮助阅读。从“A”开始的顺序大写字母用于指示格式内的字段(然后通过语法列进一步定义)。术语“op”用于指示格式中八位操作码的位置。带斜线的零 (“Ø”) 用于指示在指示位置处所有位都必须为零。

在大多数情况下,字母顺序从较早的代码单元到较晚的代码单元,以及从代码单元内的低阶到高阶。但是,此一般规则有一些例外,这样做是为了使含义相似的部分的命名在不同的指令格式中相同。这些情况在格式描述中明确指出。

例如,格式“B|A|op CCCC”表示该格式由两个 16 位代码单元组成。第一个字词由低八位中的操作码和高八位中的一对四位值组成;第二个字词由单个 16 位值组成。

格式 ID

格式表中的第二列指示格式的简短标识符,该标识符用于其他文档和代码中以标识格式。

大多数格式 ID 由三个字符组成,两个数字后跟一个字母。第一个数字表示格式中 16 位代码单元的数量。第二个数字表示格式包含的最大寄存器数量(最大值,因为某些格式可以容纳可变数量的寄存器),特殊指定“r”表示编码了一系列寄存器。最后一个字母半助记地指示格式编码的任何额外数据的类型。例如,格式“21t”的长度为 2,包含一个寄存器引用,并且还包含一个分支目标。

建议的静态链接格式具有额外的“s”后缀,使其总共为四个字符。同样,建议的“内联”链接格式具有额外的“i”后缀。(在此上下文中,内联链接类似于静态链接,只是与机器实现的直接联系更多。)最后,一些古怪的建议格式(例如,“20bc”)包含两个数据,这两个数据都在其格式 ID 中表示。

类型代码字母的完整列表如下。请注意,某些形式具有不同的大小,具体取决于格式

助记符 位大小 含义
b 8 立即有符号byte
c 16, 32 c常量池索引
f 16 f口常量(仅用于静态链接格式)
h 16 立即有符号 hat(32 位或 64 位值的高位;低位均为 0
i 32 立即有符号 int,或 32 位浮点数
l 64 立即有符号 long,或 64 位双精度浮点数
m 16 m方法常量(仅用于静态链接格式)
n 4 立即有符号 nibble
s 16 立即有符号 short
t 8, 16, 32 分支t目标
x 0 无附加数据

语法

格式表的第三列指示了使用指定格式的指令的人类可读语法。每条指令都以命名的操作码开头,并可选择后跟一个或多个参数,参数之间用逗号分隔。

只要参数引用第一列中的字段,语法中就会指示该字段的字母,对于字段的每四个位重复一次。例如,第一列中标记为“BB”的八位字段在语法列中也将标记为“BB”。

指示寄存器的参数具有“vX”的形式。选择前缀“v”而不是更常见的“r”,正是为了避免与 Dalvik Executable 格式可能实现的(非虚拟)架构上的冲突,这些架构本身使用前缀“r”表示其寄存器。(也就是说,此决定使得可以同时讨论虚拟寄存器和真实寄存器,而无需使用迂回说法。)

指示字面值的参数具有“#+X”的形式。某些格式指示字面值仅在其高位中具有非零位;对于这些字面值,即使它们不出现在按位表示中,零也会在语法中显式表示。

指示相对指令地址偏移量的参数具有“+X”的形式。

指示字面常量池索引的参数具有“kind@X”的形式,其中“kind”指示所引用的常量池类型。每个使用此类格式的操作码都显式地只允许一种常量类型;请参阅操作码参考以了解对应关系。常量池的类型为“string”(字符串池索引)、“type”(类型池索引)、“field”(字段池索引)、“meth”(方法池索引)和“site”(调用点索引)。

与常量池索引的表示类似,还有指示预链接偏移量或索引的建议(可选)形式。有两种建议的预链接值类型:vtable 偏移量(表示为“vtaboff”)和字段偏移量(表示为“fieldoff”)。

在格式值不是语法的显式部分而是选择变体的情况下,每个变体都列出了前缀“[X=N]”(例如,“[A=2]”),以指示对应关系。

格式

格式 ID 语法 包含的著名操作码
不适用 00x 不适用 用于未使用的操作码的伪格式;建议用作断点操作码的名义格式
ØØ|op 10x op  
B|A|op 12x op vA, vB  
11n op vA, #+B  
AA|op 11x op vAA  
10t op +AA goto
ØØ|op AAAA 20t op +AAAA goto/16
AA|op BBBB 20bc op AA, kind@BBBB 建议用于静态确定的验证错误的格式;A 是错误类型,B 是类型适当表(例如,用于 no-such-method 错误的方法引用)的索引
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
op vAA, field@BBBB
op vAA, method_handle@BBBB
op vAA, proto@BBBB
op vAA, string@BBBB
check-cast
const-class
const-method-handle
const-method-type
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
op vA, vB, field@CCCC
instance-of
22cs op vA, vB, fieldoff@CCCC 建议用于格式为 22c 的静态链接字段访问指令的格式
ØØ|op AAAAlo AAAAhi 30t op +AAAAAAAA goto/32
ØØ|op AAAA BBBB 32x op vAAAA, vBBBB  
AA|op BBBBlo BBBBhi 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=1] op {vC}, kind@BBBB
[A=0] op {}, kind@BBBB

此处字母选择的特殊性反映了希望使计数和引用索引与格式 3rc 中的标签相同。

 
35ms [A=5] op {vC, vD, vE, vF, vG}, vtaboff@BBBB
[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 中的标签相同。

建议用于格式为 35c 的静态链接 invoke-virtualinvoke-super 指令的格式
35mi [A=5] op {vC, vD, vE, vF, vG}, inline@BBBB
[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 中的标签相同。

建议用于格式为 35c 的内联链接 invoke-staticinvoke-virtual 指令的格式
AA|op BBBB CCCC 3rc op {vCCCC .. vNNNN}, meth@BBBB
op {vCCCC .. vNNNN}, site@BBBB
op {vCCCC .. vNNNN}, type@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-virtualinvoke-super 指令的格式
3rmi op {vCCCC .. vNNNN}, inline@BBBB

其中 NNNN = CCCC+AA-1,即 A 确定计数 0..255,而 C 确定第一个寄存器

建议用于格式为 3rc 的内联链接 invoke-staticinvoke-virtual 指令的格式
A|G|op BBBB F|E|D|C HHHH45cc [A=5] op {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH
[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
invoke-polymorphic
AA|op BBBB CCCC HHHH4rcc op> {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH

其中 NNNN = CCCC+AA-1,即 A 确定计数 0..255,而 C 确定第一个寄存器

invoke-polymorphic/range
AA|op BBBBlo BBBB BBBB BBBBhi 51l op vAA, #+BBBBBBBBBBBBBBBB const-wide