Format bytecode Dalvik

Desain umum

  • Model mesin dan konvensi panggilan dimaksudkan untuk secara kasar meniru arsitektur nyata yang umum dan konvensi panggilan bergaya C:
    • Mesin ini berbasis register, dan ukuran frame ditetapkan saat pembuatan. Setiap frame terdiri dari jumlah register tertentu (ditentukan oleh metode) serta data tambahan yang diperlukan untuk mengeksekusi metode, seperti (tetapi tidak terbatas pada) penghitung program dan referensi ke file .dex yang berisi metode.
    • Saat digunakan untuk nilai bit (seperti bilangan bulat dan bilangan floating point), register dianggap memiliki lebar 32 bit. Pasangan register yang berdekatan digunakan untuk nilai 64-bit. Tidak ada persyaratan perataan untuk pasangan register.
    • Saat digunakan untuk referensi objek, register dianggap cukup lebar untuk menyimpan tepat satu referensi tersebut.
    • Dalam hal representasi bitwise, (Object) null == (int) 0.
    • Argumen N ke metode akan ditempatkan di register N terakhir dari frame pemanggilan metode, secara berurutan. Argumen lebar menggunakan dua register. Metode instance diteruskan referensi this sebagai argumen pertamanya.
  • Unit penyimpanan dalam aliran petunjuk adalah jumlah tanpa tanda tangan 16-bit. Beberapa bit dalam beberapa petunjuk diabaikan / harus nol.
  • Petunjuk tidak dibatasi secara tidak wajar untuk jenis tertentu. Misalnya, petunjuk yang memindahkan nilai register 32-bit tanpa interpretasi tidak perlu menentukan apakah petunjuk tersebut memindahkan int atau float.
  • Ada kumpulan konstanta yang dihitung dan diindeks secara terpisah untuk referensi ke string, jenis, kolom, dan metode.
  • Data literal bitwise direpresentasikan secara inline dalam aliran petunjuk.
  • Karena, dalam praktiknya, jarang sekali metode memerlukan lebih dari 16 register, dan karena memerlukan lebih dari delapan register adalah hal yang cukup umum, banyak petunjuk dibatasi hanya untuk menangani 16 register pertama. Jika memungkinkan, petunjuk memungkinkan referensi hingga 256 register pertama. Selain itu, beberapa petunjuk memiliki varian yang memungkinkan jumlah register yang jauh lebih besar, termasuk sepasang petunjuk move generik yang dapat menangani register dalam rentang v0v65535. Jika varian petunjuk tidak tersedia untuk menangani register yang diinginkan, konten register diharapkan dipindahkan dari register asli ke register rendah (sebelum operasi) dan/atau dipindahkan dari register hasil rendah ke register tinggi (setelah operasi).
  • Ada beberapa "pseudo-petunjuk" yang digunakan untuk menyimpan payload data panjang variabel, yang dirujuk oleh petunjuk reguler (misalnya, fill-array-data). Petunjuk tersebut tidak boleh ditemukan selama alur eksekusi normal. Selain itu, petunjuk harus berada di offset bytecode bernomor genap (yaitu, diselaraskan 4 byte). Untuk memenuhi persyaratan ini, alat pembuatan dex harus memunculkan petunjuk nop tambahan sebagai pengatur jarak jika petunjuk tersebut tidak selaras. Terakhir, meskipun tidak diperlukan, sebagian besar alat akan memilih untuk mengeluarkan petunjuk ini di akhir metode, karena jika tidak, kemungkinan akan diperlukan petunjuk tambahan untuk melakukan cabang di sekitarnya.
  • Saat diinstal pada sistem yang sedang berjalan, beberapa petunjuk dapat diubah, yang mengubah formatnya, sebagai pengoptimalan penautan statis saat penginstalan. Hal ini untuk memungkinkan eksekusi yang lebih cepat setelah penautan diketahui. Lihat dokumen format petunjuk terkait untuk varian yang disarankan. Kata "direkomendasikan" digunakan dengan cermat; penerapannya tidak wajib.
  • Sintaksis dan mnemonik manusia:
    • Urutan tujuan lalu sumber untuk argumen.
    • Beberapa opcode memiliki akhiran nama yang membedakan untuk menunjukkan jenis yang dioperasikannya:
      • Opcode 32-bit jenis umum tidak ditandai.
      • Opcode 64-bit umum jenis diakhiri dengan -wide.
      • Opcode khusus jenis diakhiri dengan jenisnya (atau singkatan yang mudah), salah satu dari: -boolean -byte -char -short -int -long -float -double -object -string -class -void.
    • Beberapa opcode memiliki akhiran yang membedakan untuk membedakan operasi yang identik yang memiliki tata letak atau opsi petunjuk yang berbeda. Akhiran ini dipisahkan dari nama utama dengan garis miring ("/") dan terutama ada untuk membuat pemetaan satu-satu dengan konstanta statis dalam kode yang menghasilkan dan menafsirkan file yang dapat dieksekusi (yaitu, untuk mengurangi ambiguitas bagi manusia).
    • Dalam deskripsi di sini, lebar nilai (menunjukkan, misalnya, rentang konstanta atau jumlah register yang mungkin dialamatkan) ditekankan dengan penggunaan karakter per empat bit lebar.
    • Misalnya, dalam petunjuk "move-wide/from16 vAA, vBBBB":
      • "move" adalah opcode dasar, yang menunjukkan operasi dasar (memindahkan nilai register).
      • "wide" adalah akhiran nama, yang menunjukkan bahwa nama tersebut beroperasi pada data lebar (64 bit).
      • "from16" adalah akhiran opcode, yang menunjukkan varian yang memiliki referensi register 16-bit sebagai sumber.
      • "vAA" adalah register tujuan (diisyaratkan oleh operasi; sekali lagi, aturannya adalah bahwa argumen tujuan selalu datang terlebih dahulu), yang harus berada dalam rentang v0v255.
      • "vBBBB" adalah register sumber, yang harus berada dalam rentang v0v65535.
  • Lihat dokumen format petunjuk untuk mengetahui detail selengkapnya tentang berbagai format petunjuk (tercantum di bagian "Op & Format") serta detail tentang sintaksis opcode.
  • Lihat dokumen format file .dex untuk mengetahui detail selengkapnya tentang tempat bytecode sesuai dengan gambaran yang lebih besar.

Ringkasan set bytecode

Op & Format Mnemonik / Sintaksis Argumen Deskripsi
00 10x nop   Siklus limbah.

Catatan: Pseudo-petunjuk yang berisi data diberi tag dengan opcode ini, dengan demikian byte urutan tinggi dari unit opcode menunjukkan sifat data. Lihat "Format packed-switch-payload", "Format sparse-switch-payload", dan "Format fill-array-data-payload" di bawah.

01 12x move vA, vB A: register tujuan (4 bit)
B: register sumber (4 bit)
Memindahkan konten dari satu register non-objek ke register lainnya.
02 22x move/from16 vAA, vBBBB A: register tujuan (8 bit)
B: register sumber (16 bit)
Memindahkan konten dari satu register non-objek ke register lainnya.
03 32x move/16 vAAAA, vBBBB A: register tujuan (16 bit)
B: register sumber (16 bit)
Memindahkan konten dari satu register non-objek ke register lainnya.
04 12x move-wide vA, vB A: pasangan register tujuan (4 bit)
B: pasangan register sumber (4 bit)
Memindahkan konten dari satu pasangan register ke pasangan register lainnya.

Catatan: Anda dapat berpindah dari vN ke vN-1 atau vN+1, sehingga implementasi harus mengatur agar kedua bagian dari pasangan register dibaca sebelum apa pun ditulis.

05 22x move-wide/from16 vAA, vBBBB A: pasangan register tujuan (8 bit)
B: pasangan register sumber (16 bit)
Memindahkan konten dari satu pasangan register ke pasangan register lainnya.

Catatan: Pertimbangan penerapan sama dengan move-wide, di atas.

06 32x move-wide/16 vAAAA, vBBBB A: pasangan register tujuan (16 bit)
B: pasangan register sumber (16 bit)
Memindahkan konten dari satu pasangan register ke pasangan register lainnya.

Catatan: Pertimbangan penerapan sama dengan move-wide, di atas.

07 12x move-object vA, vB A: register tujuan (4 bit)
B: register sumber (4 bit)
Memindahkan konten dari satu register yang berisi objek ke register lain.
08 22x move-object/from16 vAA, vBBBB A: register tujuan (8 bit)
B: register sumber (16 bit)
Memindahkan konten dari satu register yang berisi objek ke register lain.
09 32x move-object/16 vAAAA, vBBBB A: register tujuan (16 bit)
B: register sumber (16 bit)
Memindahkan konten dari satu register yang berisi objek ke register lain.
0a 11x move-result vAA A: register tujuan (8 bit) Pindahkan hasil non-objek satu kata dari invoke-kind terbaru ke dalam register yang ditunjukkan. Hal ini harus dilakukan sebagai petunjuk segera setelah invoke-kind yang hasilnya (satu kata, non-objek) tidak boleh diabaikan; di tempat lain tidak valid.
0b 11x vAA move-result-wide Pasangan register tujuan A: (8 bit) Pindahkan hasil kata ganda dari invoke-kind terbaru ke dalam pasangan register yang ditunjukkan. Hal ini harus dilakukan sebagai petunjuk segera setelah invoke-kind yang hasilnya (kata ganda) tidak boleh diabaikan; di tempat lain tidak valid.
0c 11x move-result-object vAA A: register tujuan (8 bit) Pindahkan hasil objek dari invoke-kind terbaru ke dalam register yang ditunjukkan. Hal ini harus dilakukan sebagai petunjuk segera setelah invoke-kind atau filled-new-array yang hasilnya (objek) tidak boleh diabaikan; di tempat lain tidak valid.
0d 11x move-exception vAA A: register tujuan (8 bit) Menyimpan pengecualian yang baru saja tertangkap ke dalam register yang diberikan. Ini harus menjadi petunjuk pertama pengendali pengecualian yang pengecualian yang tertangkapnya tidak boleh diabaikan, dan petunjuk ini harus hanya terjadi sebagai petunjuk pertama pengendali pengecualian; di tempat lain tidak valid.
0e 10x return-void   Kembali dari metode void.
0f 11x return vAA Register nilai hasil A: (8 bit) Kembali dari metode yang menampilkan nilai non-objek lebar tunggal (32-bit).
10 11x vAA seluruh nilai yang ditampilkan Pasangan register nilai yang ditampilkan A: (8 bit) Kembali dari metode yang menampilkan nilai lebar ganda (64-bit).
11 11x vAA return-object Register nilai yang ditampilkan A: (8 bit) Kembali dari metode yang menampilkan objek.
12 11n const/4 vA, #+B A: register tujuan (4 bit)
B: int bertanda (4 bit)
Pindahkan nilai literal yang diberikan (sign-extended ke 32 bit) ke register yang ditentukan.
13 21 const/16 vAA, #+BBBB A: register tujuan (8 bit)
B: int bertanda (16 bit)
Pindahkan nilai literal yang diberikan (sign-extended ke 32 bit) ke register yang ditentukan.
14 31i const vAA, #+BBBBBBBB A: register tujuan (8 bit)
B: konstanta 32-bit arbitrer
Pindahkan nilai literal yang diberikan ke register yang ditentukan.
15 21h const/high16 vAA, #+BBBB0000 A: register tujuan (8 bit)
B: int bertanda (16 bit)
Pindahkan nilai literal yang diberikan (right-zero-extended ke 32 bit) ke register yang ditentukan.
16 21 const-wide/16 vAA, #+BBBB A: register tujuan (8 bit)
B: int bertanda (16 bit)
Pindahkan nilai literal yang diberikan (sign-extended ke 64 bit) ke pasangan register yang ditentukan.
17 31i const-wide/32 vAA, #+BBBBBBBB A: register tujuan (8 bit)
B: int bertanda (32 bit)
Pindahkan nilai literal yang diberikan (sign-extended ke 64 bit) ke pasangan register yang ditentukan.
18 51l vAA lebar const, #+BBBBBBBBBBBBBBBB A: register tujuan (8 bit)
B: konstanta lebar ganda (64-bit) arbitrer
Pindahkan nilai literal yang diberikan ke pasangan register yang ditentukan.
19 21h const-wide/high16 vAA, #+BBBB000000000000 A: register tujuan (8 bit)
B: int bertanda (16 bit)
Pindahkan nilai literal yang diberikan (right-zero-extended ke 64 bit) ke pasangan register yang ditentukan.
1a 21c const-string vAA, string@BBBB A: register tujuan (8 bit)
B: indeks string
Pindahkan referensi ke string yang ditentukan oleh indeks yang diberikan ke register yang ditentukan.
1b 31c const-string/jumbo vAA, string@BBBBBBBB A: register tujuan (8 bit)
B: indeks string
Pindahkan referensi ke string yang ditentukan oleh indeks yang diberikan ke register yang ditentukan.
1c 21c const-class vAA, type@BBBB A: register tujuan (8 bit)
B: indeks jenis
Pindahkan referensi ke class yang ditentukan oleh indeks yang diberikan ke dalam register yang ditentukan. Jika jenis yang ditunjukkan bersifat primitif, tindakan ini akan menyimpan referensi ke class degenerate jenis primitif.
1d 11x monitor-enter vAA A: register yang berisi referensi (8 bit) Dapatkan monitor untuk objek yang ditunjukkan.
1e 11x monitor-exit vAA A: register yang berisi referensi (8 bit) Lepaskan monitor untuk objek yang ditunjukkan.

Catatan: Jika petunjuk ini perlu menampilkan pengecualian, petunjuk tersebut harus melakukannya seolah-olah PC telah melewati petunjuk tersebut. Sebaiknya anggap ini sebagai petunjuk yang berhasil dieksekusi (dalam arti tertentu), dan pengecualian ditampilkan setelah petunjuk, tetapi sebelum petunjuk berikutnya mendapatkan peluang untuk dijalankan. Definisi ini memungkinkan metode menggunakan semua pembersihan monitor (misalnya, finally) sebagai pembersihan monitor untuk blok itu sendiri, sebagai cara untuk menangani pengecualian arbitrer yang mungkin ditampilkan karena implementasi historis Thread.stop(), sambil tetap mengelola untuk memiliki kebersihan monitor yang tepat.

1f 21c check-cast vAA, type@BBBB A: register yang berisi referensi (8 bit)
B: indeks jenis (16 bit)
Tampilkan ClassCastException jika referensi dalam register yang diberikan tidak dapat ditransmisikan ke jenis yang ditunjukkan.

Catatan: Karena A harus selalu berupa referensi (dan bukan nilai primitif), hal ini pasti akan gagal saat runtime (yaitu, akan menampilkan pengecualian) jika B merujuk ke jenis primitif.

20 22c instance-of vA, vB, type@CCCC A: register tujuan (4 bit)
B: register yang berisi referensi (4 bit)
C: indeks jenis (16 bit)
Simpan di register tujuan yang diberikan 1 jika referensi yang ditunjukkan adalah instance dari jenis yang diberikan, atau 0 jika tidak.

Catatan: Karena B harus selalu berupa referensi (dan bukan nilai primitif), hal ini akan selalu menyebabkan 0 disimpan jika C merujuk ke jenis primitif.

21 12x panjang array vA, vB A: register tujuan (4 bit)
B: register yang berisi referensi array (4 bit)
Menyimpan di tujuan yang diberikan, catat panjang array yang ditunjukkan, dalam entri
22 21c new-instance vAA, type@BBBB A: register tujuan (8 bit)
B: indeks jenis
Buat instance baru dari jenis yang ditunjukkan, yang menyimpan referensi ke instance tersebut di tujuan. Jenisnya harus merujuk ke class non-array.
23 22c new-array vA, vB, type@CCCC A: register tujuan (4 bit)
B: register ukuran
C: indeks jenis
Buat array baru dari jenis dan ukuran yang ditunjukkan. Jenisnya harus berupa jenis array.
24 35c filled-new-array {vC, vD, vE, vF, vG}, type@BBBB A: ukuran array dan jumlah kata argumen (4 bit)
B: indeks jenis (16 bit)
C..G: register argumen (masing-masing 4 bit)
Buat array dari jenis dan ukuran yang ditentukan, isi dengan konten yang disediakan. Jenis harus berupa jenis array. Konten array harus berupa satu kata (yaitu, tidak ada array long atau double, tetapi jenis referensi dapat diterima). Instance yang dibuat disimpan sebagai "hasil" dengan cara yang sama seperti petunjuk pemanggilan metode menyimpan hasilnya, sehingga instance yang dibuat harus dipindahkan ke register dengan petunjuk move-result-object berikutnya (jika akan digunakan).
25 3rc filled-new-array/range {vCCCC .. vNNNN}, type@BBBB A: ukuran array dan jumlah kata argumen (8 bit)
B: indeks jenis (16 bit)
C: register argumen pertama (16 bit)
N = A + C - 1
Buat array dari jenis dan ukuran yang ditentukan, isi dengan konten yang disediakan. Klarifikasi dan batasan sama seperti filled-new-array, yang dijelaskan di atas.
26 31t fill-array-data vAA, +BBBBBBBB (dengan data tambahan seperti yang ditentukan di bawah dalam "Format fill-array-data-payload") A: referensi array (8 bit)
B: offset "cabang" bertanda ke pseudo-petunjuk data tabel (32 bit)
Isi array yang diberikan dengan data yang ditunjukkan. Referensi harus berupa array primitif, dan tabel data harus cocok dengan jenisnya dan tidak boleh berisi lebih banyak elemen daripada yang akan muat dalam array. Artinya, array mungkin lebih besar dari tabel, dan jika demikian, hanya elemen awal array yang ditetapkan, sehingga sisanya tidak akan diubah.
27 11x menampilkan vAA A: register yang berisi pengecualian (8 bit)
Menampilkan pengecualian yang ditunjukkan.
28 10t goto +AA A: offset cabang bertanda tangan (8 bit) Langsung ke petunjuk yang ditunjukkan tanpa syarat.

Catatan: Offset cabang tidak boleh 0. (Loop putaran dapat dibuat secara sah dengan goto/32 atau dengan menyertakan nop sebagai target sebelum cabang.)

29 20t goto/16 +AAAA A: offset cabang bertanda (16 bit)
Langsung ke petunjuk yang ditunjukkan tanpa syarat.

Catatan: Offset cabang tidak boleh 0. (Loop putaran dapat dibuat secara sah dengan goto/32 atau dengan menyertakan nop sebagai target sebelum cabang.)

2a 30t goto/32 +AAAAAAAA A: offset cabang bertanda (32 bit)
Langsung ke petunjuk yang ditunjukkan tanpa syarat.
2b 31t packed-switch vAA, +BBBBBBBB (dengan data tambahan seperti yang ditentukan di bawah dalam "Format packed-switch-payload") A: mendaftar untuk menguji
offset "cabang" bertanda B: ke pseudo-petunjuk data tabel (32 bit)
Melompat ke petunjuk baru berdasarkan nilai dalam register tertentu, menggunakan tabel offset yang sesuai dengan setiap nilai dalam rentang integral tertentu, atau melanjutkan ke petunjuk berikutnya jika tidak ada kecocokan.
2c 31t sparse-switch vAA, +BBBBBBBB (dengan data tambahan seperti yang ditentukan di bawah dalam "Format sparse-switch-payload") A: mendaftar untuk menguji
offset "cabang" bertanda B: ke pseudo-petunjuk data tabel (32 bit)
Melompat ke petunjuk baru berdasarkan nilai dalam register tertentu, menggunakan tabel pasangan nilai-offset yang diurutkan, atau melanjutkan ke petunjuk berikutnya jika tidak ada kecocokan.
2d..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: register tujuan (8 bit)
B: register atau pasangan sumber pertama
C: register atau pasangan sumber kedua
Lakukan perbandingan floating point atau long yang ditunjukkan, dengan menetapkan a ke 0 jika b == c, 1 jika b > c, atau -1 jika b < c. "Bias" yang tercantum untuk operasi floating point menunjukkan cara perbandingan NaN diperlakukan: instruksi "gt bias" menampilkan 1 untuk perbandingan NaN, dan instruksi "lt bias" menampilkan -1.

Misalnya, untuk memeriksa apakah floating point x < y sebaiknya gunakan cmpg-float; hasil -1 menunjukkan bahwa pengujiannya benar, dan nilai lainnya menunjukkan bahwa pengujiannya salah karena perbandingan yang valid atau karena salah satu nilainya adalah NaN.

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: register pertama yang akan diuji (4 bit)
B: register kedua yang akan diuji (4 bit)
C: offset cabang bertanda (16 bit)
Cabang ke tujuan yang diberikan jika nilai dua register yang diberikan dibandingkan seperti yang ditentukan.

Catatan: Offset cabang tidak boleh 0. (Loop putaran dapat dibuat secara sah dengan melakukan cabang di sekitar goto mundur atau dengan menyertakan nop sebagai target sebelum cabang.)

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: register untuk pengujian (8 bit)
B: offset cabang bertanda (16 bit)
Cabang ke tujuan yang diberikan jika nilai register yang diberikan dibandingkan dengan 0 seperti yang ditentukan.

Catatan: Offset cabang tidak boleh 0. (Loop putaran dapat dibuat secara sah dengan melakukan cabang di sekitar goto mundur atau dengan menyertakan nop sebagai target sebelum cabang.)

3e..43 10x (tidak digunakan)   (tidak digunakan)
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: register atau pasangan nilai; dapat berupa sumber atau tujuan (8 bit)
B: register array (8 bit)
C: register indeks (8 bit)
Lakukan operasi array yang diidentifikasi pada indeks array tertentu yang diidentifikasi, yang memuat atau menyimpan ke register nilai.
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: register atau pasangan nilai; dapat berupa sumber atau tujuan (4 bit)
B: register objek (4 bit)
C: indeks referensi kolom instance (16 bit)
Lakukan operasi kolom instance objek yang diidentifikasi dengan kolom yang diidentifikasi, memuat atau menyimpan ke register nilai.

Catatan: Opcode ini adalah kandidat yang wajar untuk penautan statis, yang mengubah argumen kolom menjadi offset yang lebih langsung.

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: register atau pasangan nilai; dapat berupa sumber atau tujuan (8 bit)
B: indeks referensi kolom statis (16 bit)
Lakukan operasi kolom statis objek yang diidentifikasi dengan kolom statis yang diidentifikasi, yang memuat atau menyimpan ke dalam register nilai.

Catatan: Opcode ini adalah kandidat yang wajar untuk penautan statis, yang mengubah argumen kolom menjadi offset yang lebih langsung.

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: jumlah kata argumen (4 bit)
B: indeks referensi metode (16 bit)
C..G: register argumen (masing-masing 4 bit)
Panggil metode yang ditunjukkan. Hasilnya (jika ada) dapat disimpan dengan varian move-result* yang sesuai sebagai petunjuk berikutnya.

invoke-virtual digunakan untuk memanggil metode virtual normal yang merupakan metode yang bukan static, private, atau konstruktor.

Jika method_id mereferensikan metode class non-antarmuka, invoke-super digunakan untuk memanggil metode virtual superclass terdekat (bukan yang memiliki method_id yang sama di class panggilan). Pembatasan metode yang sama berlaku seperti untuk invoke-virtual.

Dalam file Dex versi 037 atau yang lebih baru, jika method_id merujuk ke metode antarmuka, invoke-super digunakan untuk memanggil versi metode tersebut yang paling spesifik dan tidak diganti yang ditentukan di antarmuka tersebut. Pembatasan metode yang sama berlaku seperti untuk invoke-virtual. Dalam file Dex sebelum versi 037, memiliki antarmuka method_id adalah ilegal dan tidak ditentukan.

invoke-direct digunakan untuk memanggil metode langsung non-static (yaitu, metode instance yang secara alami tidak dapat diganti, yaitu metode instance private atau konstruktor).

invoke-static digunakan untuk memanggil metode static (yang selalu dianggap sebagai metode langsung).

invoke-interface digunakan untuk memanggil metode interface, yaitu, pada objek yang class konkretnya tidak diketahui, menggunakan method_id yang merujuk ke interface.

Catatan: Opcode ini adalah kandidat yang wajar untuk penautan statis, mengubah argumen metode menjadi offset yang lebih langsung (atau pasangannya).

73 10x (tidak digunakan)   (tidak digunakan)
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: jumlah kata argumen (8 bit)
B: indeks referensi metode (16 bit)
C: register argumen pertama (16 bit)
N = A + C - 1
Panggil metode yang ditunjukkan. Lihat deskripsi invoke-kind pertama di atas untuk mengetahui detail, peringatan, dan saran.
79..7a 10x (tidak digunakan)   (tidak digunakan)
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: register atau pasangan tujuan (4 bit)
B: register atau pasangan sumber (4 bit)
Lakukan operasi uner yang diidentifikasi pada register sumber, yang menyimpan hasilnya di register tujuan.
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: register atau pasangan tujuan (8 bit)
B: register atau pasangan sumber pertama (8 bit)
C: register atau pasangan sumber kedua (8 bit)
Lakukan operasi biner yang diidentifikasi pada dua register sumber, yang menyimpan hasilnya di register tujuan.

Catatan: Tidak seperti operasi matematika -long lainnya (yang menggunakan pasangan register untuk sumber pertama dan kedua), shl-long, shr-long, dan ushr-long menggunakan pasangan register untuk sumber pertama (nilai yang akan digeser), tetapi satu register untuk sumber kedua (jarak pergeseran).

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: tujuan dan register atau pasangan sumber pertama (4 bit)
B: register atau pasangan sumber kedua (4 bit)
Lakukan operasi biner yang diidentifikasi pada dua register sumber, yang menyimpan hasilnya di register sumber pertama.

Catatan: Tidak seperti operasi matematika -long/2addr lainnya (yang menggunakan pasangan register untuk tujuan/sumber pertama dan sumber kedua), shl-long/2addr, shr-long/2addr, dan ushr-long/2addr menggunakan pasangan register untuk tujuan/sumber pertama (nilai yang akan digeser), tetapi satu register untuk sumber kedua (jarak pergeseran).

d0..d7 22s binop/lit16 vA, vB, #+CCCC
d0: add-int/lit16
d1: rsub-int (reverse subtract)
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: register tujuan (4 bit)
B: register sumber (4 bit)
C: konstanta int bertanda (16 bit)
Lakukan operasi biner yang ditunjukkan pada register yang ditunjukkan (argumen pertama) dan nilai literal (argumen kedua), yang menyimpan hasilnya di register tujuan.

Catatan: rsub-int tidak memiliki akhiran karena versi ini adalah opcode utama dari keluarganya. Selain itu, lihat di bawah untuk mengetahui detail semantiknya.

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: register tujuan (8 bit)
B: register sumber (8 bit)
C: konstanta int bertanda (8 bit)
Lakukan operasi biner yang ditunjukkan pada register yang ditunjukkan (argumen pertama) dan nilai literal (argumen kedua), yang menyimpan hasilnya di register tujuan.

Catatan: Lihat di bawah untuk mengetahui detail semantik rsub-int.

e3..f9 10x (tidak digunakan)   (tidak digunakan)
fa 45cc invoke-polymorphic {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH A: jumlah kata argumen (4 bit)
B: indeks referensi metode (16 bit)
C: penerima (4 bit)
D..G: register argumen (masing-masing 4 bit)
H: indeks referensi prototipe (16 bit)
Panggil metode polimorfik tanda tangan yang ditunjukkan. Hasilnya (jika ada) dapat disimpan dengan varian move-result* yang sesuai sebagai petunjuk berikutnya.

Referensi metode harus ke metode polimorfik tanda tangan, seperti java.lang.invoke.MethodHandle.invoke atau java.lang.invoke.MethodHandle.invokeExact.

Penerima harus berupa objek yang mendukung metode polimorfik tanda tangan yang dipanggil.

Referensi prototipe menjelaskan jenis argumen yang diberikan dan jenis nilai yang ditampilkan yang diharapkan.

Bytecode invoke-polymorphic dapat memunculkan pengecualian saat dieksekusi. Pengecualian dijelaskan dalam dokumentasi API untuk metode polimorfik tanda tangan yang dipanggil.

Ada dalam file Dex dari versi 038 dan seterusnya.
fb 4rcc invoke-polymorphic/range {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH A: jumlah kata argumen (8 bit)
B: indeks referensi metode (16 bit)
C: penerima (16 bit)
H: indeks referensi prototipe (16 bit)
N = A + C - 1
Panggil handle metode yang ditunjukkan. Lihat deskripsi invoke-polymorphic di atas untuk mengetahui detailnya.

Ada dalam file Dex dari versi 038 dan seterusnya.
fc 35c invoke-custom {vC, vD, vE, vF, vG}, call_site@BBBB A: jumlah kata argumen (4 bit)
B: indeks referensi situs panggilan (16 bit)
C..G: register argumen (masing-masing 4 bit)
Me-resolve dan memanggil situs panggilan yang ditunjukkan. Hasil dari pemanggilan (jika ada) dapat disimpan dengan varian move-result* yang sesuai sebagai petunjuk berikutnya.

Petunjuk ini dijalankan dalam dua fase: resolusi situs panggilan dan pemanggilan situs panggilan.

Resolution situs panggilan memeriksa apakah situs panggilan yang ditunjukkan memiliki instance java.lang.invoke.CallSite terkait. Jika tidak, metode bootstrap linker untuk situs panggilan yang ditunjukkan akan dipanggil menggunakan argumen yang ada dalam file DEX (lihat call_site_item). Metode bootstrap linker menampilkan instance java.lang.invoke.CallSite yang kemudian akan dikaitkan dengan situs panggilan yang ditunjukkan jika tidak ada pengaitan yang ada. Thread lain mungkin telah membuat pengaitan terlebih dahulu, dan jika demikian, eksekusi petunjuk akan dilanjutkan dengan instance java.lang.invoke.CallSite pertama yang terkait.

Pemanggilan situs panggilan dilakukan pada target java.lang.invoke.MethodHandle dari instance java.lang.invoke.CallSite yang di-resolve. Target dipanggil sebagai jika menjalankan invoke-polymorphic (dijelaskan di atas) menggunakan handle metode dan argumen ke petunjuk invoke-custom sebagai argumen untuk pemanggilan handle metode yang tepat.

Pengecualian yang diangkat oleh metode bootstrap linker digabungkan dalam java.lang.BootstrapMethodError. BootstrapMethodError juga akan ditampilkan jika:
  • metode bootstrap linker gagal menampilkan instance java.lang.invoke.CallSite.
  • java.lang.invoke.CallSite yang ditampilkan memiliki target handle metode null.
  • target handle metode bukan dari jenis yang diminta.
Ada di file Dex dari versi 038 dan seterusnya.
fd 3rc invoke-custom/range {vCCCC .. vNNNN}, call_site@BBBB A: jumlah kata argumen (8 bit)
B: indeks referensi situs panggilan (16 bit)
C: register argumen pertama (16-bit)
N = A + C - 1
Me-resolve dan memanggil situs panggilan. Lihat deskripsi invoke-custom di atas untuk mengetahui detailnya.

Ada di file Dex dari versi 038 dan seterusnya.
fe 21c const-method-handle vAA, method_handle@BBBB A: register tujuan (8 bit)
B: indeks handle metode (16 bit)
Pindahkan referensi ke handle metode yang ditentukan oleh indeks yang diberikan ke register yang ditentukan.

Ada di file Dex dari versi 039 dan seterusnya.
ff 21c const-method-type vAA, proto@BBBB A: register tujuan (8 bit)
B: referensi prototipe metode (16 bit)
Pindahkan referensi ke prototipe metode yang ditentukan oleh indeks yang diberikan ke register yang ditentukan.

Ada di file Dex dari versi 039 dan seterusnya.

format payload switch yang dikemas

Nama Format Deskripsi
ident ushort = 0x0100 mengidentifikasi pseudo-opcode
ukuran ushort jumlah entri dalam tabel
first_key int nilai kasus tombol pertama (dan terendah)
target int[] daftar size target cabang relatif. Target bersifat relatif terhadap alamat opcode tombol, bukan tabel ini.

Catatan: Jumlah total unit kode untuk instance tabel ini adalah (size * 2) + 4.

format payload-switch-sparse

Nama Format Deskripsi
ident ushort = 0x0200 mengidentifikasi pseudo-opcode
ukuran ushort jumlah entri dalam tabel
kunci int[] daftar nilai kunci size, diurutkan dari rendah ke tinggi
target int[] daftar target cabang relatif size, masing-masing sesuai dengan nilai kunci pada indeks yang sama. Targetnya relatif terhadap alamat opcode tombol, bukan tabel ini.

Catatan: Jumlah total unit kode untuk instance tabel ini adalah (size * 4) + 2.

format fill-array-data-payload

Nama Format Deskripsi
ident ushort = 0x0300 mengidentifikasi pseudo-opcode
element_width ushort jumlah byte dalam setiap elemen
ukuran uint jumlah elemen dalam tabel
data ubyte[] nilai data

Catatan: Jumlah total unit kode untuk instance tabel ini adalah (size * element_width + 1) / 2 + 4.

Detail operasi matematika

Catatan: Operasi floating point harus mengikuti aturan IEEE 754, menggunakan round-to-nearest dan underflow bertahap, kecuali jika dinyatakan lain.

Opcode Semantik C Catatan
neg-int int32 a;
int32 result = -a;
Komplemen dua biner.
not-int int32 a;
int32 result = ~a;
Komplemen satu unary.
neg-long int64 a;
int64 result = -a;
Komplemen dua biner.
not-long int64 a;
int64 result = ~a;
Komplemen satu unary.
neg-float float a;
float result = -a;
Negasi floating point.
neg-double double a;
double result = -a;
Negasi floating point.
int-to-long int32 a;
int64 result = (int64) a;
Tanda tangani ekstensi int32 ke dalam int64.
int-to-float int32 a;
float result = (float) a;
Konversi int32 ke float, menggunakan pembulatan ke terdekat. Hal ini akan mengurangi presisi untuk beberapa nilai.
int-to-double int32 a;
double result = (double) a;
Konversi int32 ke double.
long-to-int int64 a;
int32 result = (int32) a;
Pemotongan int64 menjadi int32.
long-to-float int64 a;
float result = (float) a;
Konversi int64 ke float, menggunakan pembulatan ke terdekat. Hal ini akan mengurangi presisi untuk beberapa nilai.
long-to-double int64 a;
double result = (double) a;
Konversi int64 ke double, menggunakan pembulatan ke terdekat. Hal ini akan mengurangi presisi untuk beberapa nilai.
float-to-int float a;
int32 result = (int32) a;
Konversi float ke int32, menggunakan pembulatan ke nol. NaN dan -0.0 (nol negatif) dikonversi menjadi bilangan bulat 0. Nilai tak hingga dan nilai dengan magnitudo yang terlalu besar untuk direpresentasikan akan dikonversi menjadi 0x7fffffff atau -0x80000000, bergantung pada tandanya.
float-to-long float a;
int64 result = (int64) a;
Konversi float ke int64, menggunakan pembulatan ke nol. Aturan kasus khusus yang sama seperti untuk float-to-int berlaku di sini, kecuali bahwa nilai di luar rentang akan dikonversi menjadi 0x7fffffffffffffff atau -0x8000000000000000, bergantung pada tandanya.
float-to-double float a;
double result = (double) a;
Konversi float menjadi double, yang mempertahankan nilai secara tepat.
double-to-int double a;
int32 result = (int32) a;
Konversi double ke int32, menggunakan pembulatan ke nol. Aturan kasus khusus yang sama seperti untuk float-to-int berlaku di sini.
double-to-long double a;
int64 result = (int64) a;
Konversi double ke int64, menggunakan pembulatan ke nol. Aturan kasus khusus yang sama seperti untuk float-to-long berlaku di sini.
double-to-float double a;
float result = (float) a;
Konversi double ke float, menggunakan pembulatan ke terdekat. Hal ini akan mengurangi presisi untuk beberapa nilai.
int-to-byte int32 a;
int32 result = (a << 24) >> 24;
Pemotongan int32 menjadi int8, tanda yang memperluas hasilnya.
int-to-char int32 a;
int32 result = a & 0xffff;
Pemotongan int32 menjadi uint16, tanpa perluasan tanda.
int-to-short int32 a;
int32 result = (a << 16) >> 16;
Pemotongan int32 menjadi int16, tanda yang memperluas hasilnya.
add-int int32 a, b;
int32 result = a + b;
Penambahan twos-complement.
sub-int int32 a, b;
int32 result = a - b;
Pengurangan twos-complement.
rsub-int int32 a, b;
int32 result = b - a;
Pengurangan terbalik twos-complement.
mul-int int32 a, b;
int32 result = a * b;
Perkalian komplemen dua.
div-int int32 a, b;
int32 result = a / b;
Pembagian twos-complement, dibulatkan ke nol (yaitu, dipangkas ke bilangan bulat). Tindakan ini akan menampilkan ArithmeticException jika b == 0.
rem-int int32 a, b;
int32 result = a % b;
Sisa komplemen dua setelah pembagian. Tanda hasilnya sama dengan a, dan lebih tepat ditentukan sebagai result == a - (a / b) * b. Tindakan ini akan menampilkan ArithmeticException jika b == 0.
and-int int32 a, b;
int32 result = a & b;
Bitwise AND.
or-int int32 a, b;
int32 result = a | b;
Operasi bitwise OR.
xor-int int32 a, b;
int32 result = a ^ b;
Bitwise XOR.
shl-int int32 a, b;
int32 result = a << (b & 0x1f);
Bitwise shift left (dengan argumen yang disamarkan).
shr-int int32 a, b;
int32 result = a >> (b & 0x1f);
Bitwise signed shift right (dengan argumen yang disamarkan).
ushr-int uint32 a, b;
int32 result = a >> (b & 0x1f);
Bitwise unsigned shift right (dengan argumen yang disamarkan).
add-long int64 a, b;
int64 result = a + b;
Penambahan twos-complement.
sub-panjang int64 a, b;
int64 result = a - b;
Pengurangan twos-complement.
mul-long int64 a, b;
int64 result = a * b;
Perkalian komplemen dua.
div-long int64 a, b;
int64 result = a / b;
Pembagian twos-complement, dibulatkan ke nol (yaitu, dipangkas ke bilangan bulat). Tindakan ini akan menampilkan ArithmeticException jika b == 0.
rem-long int64 a, b;
int64 result = a % b;
Sisa komplemen dua setelah pembagian. Tanda hasilnya sama dengan tanda a, dan lebih tepat ditentukan sebagai result == a - (a / b) * b. Tindakan ini akan menampilkan ArithmeticException jika b == 0.
and-long int64 a, b;
int64 result = a & b;
Bitwise AND.
or-long int64 a, b;
int64 result = a | b;
Operasi bitwise OR.
xor-long int64 a, b;
int64 result = a ^ b;
Bitwise XOR.
shl-long int64 a;
int32 b;
int64 result = a << (b & 0x3f);
Bitwise shift left (dengan argumen yang disamarkan).
shr-long int64 a;
int32 b;
int64 result = a >> (b & 0x3f);
Bitwise signed shift right (dengan argumen yang disamarkan).
ushr-long uint64 a;
int32 b;
int64 result = a >> (b & 0x3f);
Bitwise unsigned shift right (dengan argumen yang disamarkan).
add-float float a, b;
float result = a + b;
Penambahan floating point.
sub-float float a, b;
float result = a - b;
Pengurangan floating point.
mul-float float a, b;
float result = a * b;
Perkalian floating point.
div-float float a, b;
float result = a / b;
Pembagian floating point.
rem-float float a, b;
float result = a % b;
Sisa floating point setelah pembagian. Fungsi ini berbeda dengan sisa IEEE 754 dan ditentukan sebagai result == a - roundTowardZero(a / b) * b.
add-double double a, b;
double result = a + b;
Penambahan floating point.
sub-ganda double a, b;
double result = a - b;
Pengurangan floating point.
mul-double double a, b;
double result = a * b;
Perkalian floating point.
div-double double a, b;
double result = a / b;
Pembagian floating point.
rem-double double a, b;
double result = a % b;
Sisa floating point setelah pembagian. Fungsi ini berbeda dengan sisa IEEE 754 dan ditentukan sebagai result == a - roundTowardZero(a / b) * b.