Dalvik 実行可能ファイルの命令形式

このページには、Dalvik 実行可能ファイル(DEX)形式と Dalvik バイトコードで使用される命令形式のリストを掲載しています。このドキュメントは、バイトコードのリファレンス ドキュメントと合わせて使用することを意図しています。

ビット単位の説明

形式表の最初の列は、形式のビット単位のレイアウトを示しています。レイアウトは 1 つまたは複数のスペースで区切られた「ワード」で構成され、各ワードは 16 ビットのコード単位を記述します。ワード内の各文字は 4 ビットを表し、上位ビットから下位ビットの順に並んでいます。見やすくするために、間に縦棒(「|」)が挿入されています。「A」から始まって順番に並んでいる大文字の英字は、形式内のフィールドを示します(詳細な定義は構文の列にあります)。「op」という語句は、形式内の 8 ビットのオペコードの位置を示すために使用されています。スラッシュ入りのゼロ(「Ø」)は、すべてのビットがゼロでなければならない位置を示すのに使用されます。

ほとんどの場合、文字の記述は前のコード単位から後のコード単位に向かって進み、コード単位内では下位から上位に向かって進みます。ただし、各種の命令形式で意味が類似する部分を同じ名前にするために、この一般原則にはいくつかの例外があります。そうしたケースについては、形式の説明の中で明記しています。

たとえば、形式「B|A|op CCCC」は、2 つの 16 ビットコード単位で形式が構成されることを示します。最初のワードは下位 8 ビットのオペコードと、上位 8 ビットの 4 ビット値のペアで構成されます。2 番目のワードは単一の 16 ビット値で構成されます。

形式 ID

形式表の 2 番目の列は、形式の短い識別子を示しています。これは、他のドキュメントと、形式を識別するコード内で使用されます。

ほとんどの形式 ID は 3 つの文字(2 桁の数字の後に英字が 1 つ続く)で構成されます。1 つ目の数字は、形式内の 16 ビットのコード単位の数を示します。2 つ目の数字は、形式に含まれるレジスタの最大数を示します(最大数を使用するのは、一部の形式は可変数のレジスタに対応できるためです)。特別な文字「r」は、レジスタの範囲がエンコードされていることを示します。最後の英字は、一種のニーモニックとして、該当の形式でエンコードされた追加データのタイプを示します。たとえば、形式「21t」は、長さが 2 で、レジスタ参照を 1 つ含み、さらには分岐ターゲットを含むことを示します。

推奨される静的リンク形式は追加の「s」サフィックスを持ち、合計で 4 文字になります。同様に、推奨される「インライン」リンク形式は追加の「i」サフィックスを持ちます(この点でインライン リンクは静的リンクと似ていますが、マシンの実装により直接的に関係する点で異なります)。最後に、いくつかの風変わりな推奨形式(たとえば、「20bc」)があります。これは、どちらも形式 ID で表される 2 つのデータを含みます。

タイプコード文字の完全なリストは次のとおりです。一部の文字では、形式に応じてサイズが異なります。

ニーモニック ビットサイズ 意味
b 8 符号付きイミディエイト バイト(byte)
c 16、32 定数(constant)プール インデックス
f 16 インターフェース(interface)定数(静的にリンクされる形式でのみ使用)
h 16 符号付きイミディエイト hat(32 ビット値または 64 ビット値の上位ビット。下位ビットはすべて 0
i 32 符号付きイミディエイト int、または 32 ビット float
l 64 符号付きイミディエイト long、または 64 ビット double
m 16 メソッド(method)定数(静的にリンクされる形式でのみ使用)
n 4 符号付きイミディエイト nibble
s 16 符号付きイミディエイト short
t 8、16、32 分岐ターゲット(target)
x 0 追加データなし

構文

形式表の 3 番目の列は、そこで示されている形式を使用する命令の人間にわかりやすい構文を示しています。各命令は名前付きオペコードで始まり、その後にオプションとして、カンマで区切られた 1 つ以上の引数が続きます。

引数が最初の列のフィールドを参照する場合は、常にそのフィールドを表す文字が構文内で示され、フィールドの 4 ビットごとに 1 回繰り返されます。たとえば、最初の列で「BB」というラベルが付いている 8 ビットのフィールドには、構文の列でも「BB」というラベルが付けられます。

レジスタの名前を指定する引数は「vX」という形を取ります。より一般的な「r」の代わりにプレフィックス「v」が選ばれたのは、レジスタを表すプレフィックス「r」を使用する Dalvik 実行可能ファイル形式が実装された(仮想でない)アーキテクチャとの競合を回避するためです(これにより、遠回しな表現をせずに仮想レジスタと実レジスタの両方に言及することが可能になります)。

リテラル値を示す引数は「#+X」という形を取ります。一部の形式は上位ビットにゼロ以外のビットのみを持つリテラルを表しますが、その場合、ゼロはビット単位の表現で示されていなくても、構文で明示的に表現されます。

相対命令アドレス オフセットを示す引数は、「+X」という形を取ります。

リテラル定数プール インデックスを示す引数は、「kind@X」という形を取ります。ここで、「kind」はどの定数プールが参照されているかを示します。このような形式を使用するオペコードは、それぞれ 1 種類の定数のみを許容します。対応関係を理解するには、オペコードのリファレンスをご覧ください。定数プールの種類は、「string」(文字列プール インデックス)、「type」(型プール インデックス)、「field」(フィールド プール インデックス)、「meth」(メソッドプール インデックス)、「site」(コールサイト インデックス)です。

定数プール インデックスの表現と同様に、事前リンクされるオフセットまたはインデックスを示す推奨される(オプションの)形態もあります。事前リンクされる推奨値には、vtable オフセット(「vtaboff」として示される)とフィールド オフセット(「fieldoff」として示される)の 2 つの種類があります。

形式値が明示的に構文に含まれず、バリアントの形を取る場合、各バリアントは対応関係を示すプレフィックス「[X=N]」(例: 「[A=2]」)で示されます。

フォーマット

形式 ID 構文 カバーされる重要なオペコード
N/A 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 は型に応じた表に対するインデックスです(例: 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-virtual および invoke-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-static および invoke-virtual 命令の推奨形式
AA|op BBBB CCCC 3rc op {vCCCC .. vNNNN}, meth@BBBB
op {vCCCC .. vNNNN}, site@BBBB
op {vCCCC .. vNNNN}, type@BBBB

ここで、NNNN = CCCC+AA-1A であり、これによってカウント 0..255 が決定され、C によって第 1 レジスタが決定されます

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

ここで、NNNN = CCCC+AA-1A であり、これによってカウント 0..255 が決定され、C によって第 1 レジスタが決定されます

形式 3rc の静的にリンクされた invoke-virtual および invoke-super 命令の推奨形式
3rmi op {vCCCC .. vNNNN}, inline@BBBB

ここで、NNNN = CCCC+AA-1A であり、これによってカウント 0..255 が決定され、C によって第 1 レジスタが決定されます

形式 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
[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-1A であり、これによってカウント 0..255 が決定され、C によって第 1 レジスタが決定されます

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