Dalvik 可执行指令格式

本页面列出了 Dalvik 可执行格式和 Dalvik 字节码使用的指令格式。本页面需要结合字节码参考文档使用。

按位描述

格式表的第一列列出了格式的按位布局。它由一个或多个空格分隔的“单词”组成,每个单词描述一个 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,但是在按位描述中这些 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  
10t op +AA goto
ØØ|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
op vAA, field@BBBB
op vAA, string@BBBB
check-cast
const-class
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..255C 确定第一个寄存器

 
3rms op {vCCCC .. vNNNN}, vtaboff@BBBB

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

3rc 格式的静态链接 invoke-virtualinvoke-super 指令的建议格式
3rmi op {vCCCC .. vNNNN}, inline@BBBB

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

3rc 格式的内联链接 invoke-staticinvoke-virtual 指令的建议格式
A|G|op BBBB F|E|D|C HHHH 45cc [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 HHHH 4rcc op> {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH

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

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