Bytecode Dalvik

Desain umum

  • Model mesin dan konvensi pemanggilan dimaksudkan untuk meniru arsitektur nyata umum dan konvensi pemanggilan gaya-C:
    • Mesin ini berbasis register, dan ukuran frame tetap pada saat pembuatan. Setiap frame terdiri dari sejumlah register tertentu (ditentukan oleh metode) serta data tambahan yang diperlukan untuk menjalankan metode, seperti (tetapi tidak terbatas pada) penghitung program dan referensi ke file .dex yang berisi metode .
    • Ketika digunakan untuk nilai bit (seperti bilangan bulat dan bilangan floating point), register dianggap lebar 32 bit. Pasangan register yang berdekatan digunakan untuk nilai 64-bit. Tidak ada persyaratan penyelarasan untuk pasangan register.
    • Ketika digunakan untuk referensi objek, register dianggap cukup lebar untuk menampung tepat satu referensi tersebut.
    • Dalam hal representasi bitwise, (Object) null == (int) 0 .
    • Argumen N ke metode mendarat di N register terakhir dari bingkai pemanggilan metode, secara berurutan. Argumen yang luas menghabiskan dua register. Metode instance diberikan referensi this sebagai argumen pertama mereka.
  • Unit penyimpanan dalam aliran instruksi adalah kuantitas 16-bit unsigned. Beberapa bit dalam beberapa instruksi diabaikan / must-be-zero.
  • Instruksi tidak hanya terbatas pada jenis tertentu. Misalnya, instruksi yang memindahkan nilai register 32-bit tanpa interpretasi tidak harus menentukan apakah mereka memindahkan int atau float.
  • Ada kumpulan konstanta yang dihitung dan diindeks secara terpisah untuk referensi ke string, tipe, bidang, dan metode.
  • Data literal bitwise diwakili in-line dalam aliran instruksi.
  • Karena, dalam praktiknya, tidak umum suatu metode membutuhkan lebih dari 16 register, dan karena memerlukan lebih dari delapan register cukup umum, banyak instruksi dibatasi hanya untuk menangani 16 register pertama. Jika memungkinkan, instruksi mengizinkan referensi hingga 256 register pertama. Selain itu, beberapa instruksi memiliki varian yang memungkinkan jumlah register yang jauh lebih besar, termasuk sepasang instruksi catch-all move yang dapat menangani register dalam rentang v0v65535 . Dalam kasus di mana varian instruksi tidak tersedia untuk menangani register yang diinginkan, diharapkan isi register dipindahkan dari register asli ke register rendah (sebelum operasi) dan/atau dipindahkan dari register hasil rendah ke register tinggi mendaftar (setelah operasi).
  • Ada beberapa "instruksi semu" yang digunakan untuk menyimpan muatan data dengan panjang variabel, yang dirujuk oleh instruksi reguler (misalnya, fill-array-data ). Instruksi tersebut tidak boleh ditemui selama aliran normal eksekusi. Selain itu, instruksi harus ditempatkan pada offset bytecode bernomor genap (yaitu, disejajarkan 4-byte). Untuk memenuhi persyaratan ini, alat pembangkit dex harus memancarkan instruksi nop tambahan sebagai pengatur jarak jika instruksi seperti itu tidak akan disejajarkan. Akhirnya, meskipun tidak diperlukan, diharapkan bahwa sebagian besar alat akan memilih untuk mengeluarkan instruksi ini di akhir metode, karena jika tidak, kemungkinan besar instruksi tambahan akan diperlukan untuk bercabang di sekitarnya.
  • Saat diinstal pada sistem yang sedang berjalan, beberapa instruksi dapat diubah, mengubah formatnya, sebagai pengoptimalan penautan statis waktu pemasangan. Ini untuk memungkinkan eksekusi yang lebih cepat setelah hubungan diketahui. Lihat dokumen format instruksi terkait untuk varian yang disarankan. Kata "disarankan" digunakan dengan bijaksana; tidak wajib untuk menerapkannya.
  • Sintaks dan mnemonik manusia:
    • Urutan tujuan-lalu-sumber untuk argumen.
    • Beberapa opcode memiliki akhiran nama yang tidak ambigu untuk menunjukkan jenis operasinya:
      • Jenis-jenis opcode 32-bit umum tidak ditandai.
      • Opcode 64-bit tipe-umum diakhiri dengan -wide .
      • Opcode khusus tipe diberi akhiran dengan tipenya (atau singkatan langsung), salah satu dari: -boolean -byte -char -short -int -long -float -double -object -class -string -void
    • Beberapa opcode memiliki sufiks disambiguasi untuk membedakan operasi yang identik yang memiliki tata letak atau opsi instruksi yang berbeda. Sufiks ini dipisahkan dari nama utama dengan garis miring (" / ") dan terutama ada sama sekali untuk membuat pemetaan satu-ke-satu dengan konstanta statis dalam kode yang menghasilkan dan menafsirkan executable (yaitu, untuk mengurangi ambiguitas untuk manusia).
    • Dalam uraian di sini, lebar suatu nilai (menunjukkan, misalnya, kisaran suatu konstanta atau jumlah register yang mungkin dialamatkan) ditekankan dengan penggunaan karakter per empat bit lebarnya.
    • Misalnya, dalam instruksi " move-wide/from16 vAA, vBBBB ":
      • " move " adalah opcode dasar, yang menunjukkan operasi dasar (memindahkan nilai register).
      • " wide " adalah akhiran nama, yang menunjukkan bahwa ia beroperasi pada data lebar (64 bit).
      • " from16 " adalah sufiks opcode, yang menunjukkan varian yang memiliki referensi register 16-bit sebagai sumber.
      • " vAA " adalah register tujuan (tersirat oleh operasi; sekali lagi, aturannya adalah bahwa argumen tujuan selalu didahulukan), yang harus dalam kisaran v0v255 .
      • " vBBBB " adalah register sumber, yang harus dalam kisaran v0v65535 .
  • Lihat dokumen format instruksi untuk detail lebih lanjut tentang berbagai format instruksi (tercantum di bawah "Op & Format") serta detail tentang sintaks opcode.
  • Lihat dokumen format file .dex untuk detail lebih lanjut tentang di mana bytecode cocok dengan gambar yang lebih besar.

Ringkasan kumpulan bytecode

Op & Format Mnemonik / Sintaks Argumen Keterangan
00 10x tidak Siklus limbah.

Catatan: Instruksi semu pembawa data ditandai dengan opcode ini, dalam hal ini byte orde tinggi dari unit opcode menunjukkan sifat data. Lihat " Format packed-switch-payload ", " Format sparse-switch-payload ", dan " Format fill-array-data-payload " di bawah ini.

01 12x pindahkan vA, vB A: register tujuan (4 bit)
B: register sumber (4 bit)
Pindahkan isi dari satu register non-objek ke yang lain.
02 22x pindah/dari16 vAA, vBBBB A: register tujuan (8 bit)
B: register sumber (16 bit)
Pindahkan isi dari satu register non-objek ke yang lain.
03 32x pindah/16 vAAAA, vBBBB A: register tujuan (16 bit)
B: register sumber (16 bit)
Pindahkan isi dari satu register non-objek ke yang lain.
04 12x bergerak lebar vA, vB A: pasangan register tujuan (4 bit)
B: pasangan register sumber (4 bit)
Pindahkan isi dari satu pasangan register ke yang lain.

Catatan: Adalah sah untuk berpindah dari v N ke v N-1 atau v N+1 , jadi implementasi harus mengatur agar kedua bagian dari pasangan register dibaca sebelum sesuatu ditulis.

05 22x bergerak-lebar/dari16 vAA, vBBBB A: pasangan register tujuan (8 bit)
B: pasangan register sumber (16 bit)
Pindahkan isi dari satu pasangan register ke yang lain.

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

06 32x bergerak-lebar/16 vAAAA, vBBBB A: pasangan register tujuan (16 bit)
B: pasangan register sumber (16 bit)
Pindahkan isi dari satu pasangan register ke yang lain.

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

07 12x bergerak-objek vA, vB A: register tujuan (4 bit)
B: register sumber (4 bit)
Pindahkan isi dari satu register objek ke yang lain.
08 22x pindah-objek/dari16 vAA, vBBBB A: register tujuan (8 bit)
B: register sumber (16 bit)
Pindahkan isi dari satu register objek ke yang lain.
09 32x objek bergerak/16 vAAAA, vBBBB A: register tujuan (16 bit)
B: register sumber (16 bit)
Pindahkan isi dari satu register objek ke yang lain.
0a 11x bergerak-hasil vAA A: register tujuan (8 bit) Pindahkan hasil non-objek satu kata dari invoke- kind terbaru ke dalam register yang ditunjukkan. Ini harus dilakukan sebagai instruksi segera setelah invoke- kind yang hasilnya (kata tunggal, bukan objek) tidak boleh diabaikan; di tempat lain tidak valid.
0b 11x bergerak-hasil-lebar vAA A: pasangan register tujuan (8 bit) Pindahkan hasil kata ganda dari invoke- kind terbaru ke dalam pasangan register yang ditunjukkan. Ini harus dilakukan sebagai instruksi segera setelah invoke- kind yang hasilnya (kata ganda) tidak boleh diabaikan; di tempat lain tidak valid.
0c 11x pindah-hasil-objek vAA A: register tujuan (8 bit) Pindahkan hasil objek dari invoke- kind terbaru ke dalam register yang ditunjukkan. Ini harus dilakukan sebagai instruksi segera setelah invoke- kind atau filled-new-array (objek) yang hasilnya tidak boleh diabaikan; di tempat lain tidak valid.
0d 11x bergerak-pengecualian vAA A: register tujuan (8 bit) Simpan pengecualian yang baru saja ditangkap ke dalam register yang diberikan. Ini harus menjadi instruksi pertama dari setiap exception handler yang exception yang tertangkap tidak boleh diabaikan, dan instruksi ini hanya boleh terjadi sebagai instruksi pertama dari exception handler; di tempat lain tidak valid.
0e 10x kembali-batal Kembali dari metode void .
0f 11x kembali vAA A: register nilai kembali (8 bit) Kembali dari metode pengembalian nilai non-objek dengan lebar tunggal (32-bit).
10 11x vAA . lebar pengembalian A: nilai kembalian register-pair (8 bit) Kembali dari metode pengembalian nilai lebar ganda (64-bit).
11 11x objek kembali vAA A: register nilai kembali (8 bit) Kembali dari metode pengembalian objek.
12 11n const/4 vA, #+B A: register tujuan (4 bit)
B: int masuk (4 bit)
Pindahkan nilai literal yang diberikan (sign-extended to 32 bits) ke dalam register yang ditentukan.
13 21 detik const/16 vAA, #+BBBB A: register tujuan (8 bit)
B: int masuk (16 bit)
Pindahkan nilai literal yang diberikan (sign-extended to 32 bits) ke dalam register yang ditentukan.
14 31i const vAA, #+BBBBBBBB A: register tujuan (8 bit)
B: konstanta 32-bit sewenang-wenang
Pindahkan nilai literal yang diberikan ke dalam register yang ditentukan.
15 21j const/high16 vAA, #+BBBB0000 A: register tujuan (8 bit)
B: int masuk (16 bit)
Pindahkan nilai literal yang diberikan (right-zero-extended to 32 bits) ke dalam register yang ditentukan.
16 21 detik const-wide/16 vAA, #+BBBB A: register tujuan (8 bit)
B: int masuk (16 bit)
Pindahkan nilai literal yang diberikan (sign-extended to 64 bits) ke dalam pasangan register yang ditentukan.
17 31i const-wide/32 vAA, #+BBBBBBBB A: register tujuan (8 bit)
B: int masuk (32 bit)
Pindahkan nilai literal yang diberikan (sign-extended to 64 bits) ke dalam pasangan register yang ditentukan.
18 51l vAA const-wide, #+BBBBBBBBBBBBBBBB A: register tujuan (8 bit)
B: konstanta lebar ganda (64-bit) sewenang-wenang
Pindahkan nilai literal yang diberikan ke pasangan register yang ditentukan.
19 21j const-wide/high16 vAA, #+BBBB000000000000 A: register tujuan (8 bit)
B: int masuk (16 bit)
Pindahkan nilai literal yang diberikan (right-zero-extended to 64 bits) ke dalam 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 dalam 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 dalam register yang ditentukan.
1c 21c vAA kelas const, ketik@BBBB A: register tujuan (8 bit)
B: indeks tipe
Pindahkan referensi ke kelas yang ditentukan oleh indeks yang diberikan ke dalam register yang ditentukan. Dalam kasus di mana tipe yang ditunjukkan adalah primitif, ini akan menyimpan referensi ke kelas degenerasi tipe primitif.
1 hari 11x monitor-masukkan vAA A: register bantalan referensi (8 bit) Dapatkan monitor untuk objek yang ditunjukkan.
1e 11x monitor-keluar vAA A: register bantalan referensi (8 bit) Lepaskan monitor untuk objek yang ditunjukkan.

Catatan: Jika instruksi ini perlu mengeluarkan pengecualian, ia harus melakukannya seolah-olah pc telah maju melewati instruksi. Mungkin berguna untuk menganggap ini sebagai instruksi yang berhasil dieksekusi (dalam arti tertentu), dan pengecualian dilemparkan setelah instruksi tetapi sebelum instruksi berikutnya mendapat kesempatan untuk dijalankan. Definisi ini memungkinkan metode untuk menggunakan blok catch-all (mis., finally ) pembersihan monitor sebagai pembersihan monitor untuk blok itu sendiri, sebagai cara untuk menangani pengecualian arbitrer yang mungkin dilemparkan karena implementasi historis dari Thread.stop() , sambil tetap mengelola kebersihan monitor yang tepat.

1f 21c cek-cast vAA, ketik@BBBB A: register bantalan referensi (8 bit)
B: tipe indeks (16 bit)
Lempar ClassCastException jika referensi dalam register yang diberikan tidak dapat dilemparkan ke tipe yang ditunjukkan.

Catatan: Karena A harus selalu menjadi referensi (dan bukan nilai primitif), ini pasti akan gagal saat runtime (yaitu, akan mengeluarkan pengecualian) jika B merujuk ke tipe primitif.

20 22c contoh-dari vA, vB, ketik@CCCC A: register tujuan (4 bit)
B: register bantalan referensi (4 bit)
C: ketik indeks (16 bit)
Simpan di register tujuan yang diberikan 1 jika referensi yang ditunjukkan adalah turunan dari tipe yang diberikan, atau 0 jika tidak.

Catatan: Karena B harus selalu menjadi referensi (dan bukan nilai primitif), ini akan selalu menghasilkan 0 disimpan jika C mengacu pada tipe primitif.

21 12x panjang larik vA, vB A: register tujuan (4 bit)
B: register bantalan referensi array (4 bit)
Simpan di tujuan yang diberikan, daftarkan panjang array yang ditunjukkan, dalam entri
22 21c vAA instance baru, ketik@BBBB A: register tujuan (8 bit)
B: indeks tipe
Buat instance baru dari tipe yang ditunjukkan, simpan referensinya di tujuan. Jenis harus merujuk ke kelas non-array.
23 22c array baru vA, vB, ketik@CCCC A: register tujuan (4 bit)
B: register ukuran
C: ketik indeks
Buat array baru dengan tipe dan ukuran yang ditunjukkan. Tipenya harus tipe array.
24 35c array baru yang terisi {vC, vD, vE, vF, vG}, ketik@BBBB A: ukuran array dan jumlah kata argumen (4 bit)
B: tipe indeks (16 bit)
C..G: register argumen (masing-masing 4 bit)
Buat array dengan tipe dan ukuran tertentu, isi dengan konten yang disediakan. Tipenya harus tipe array. Isi larik harus berupa kata tunggal (yaitu, tidak ada larik long atau double , tetapi tipe referensi dapat diterima). Instance yang dibangun disimpan sebagai "hasil" dengan cara yang sama seperti instruksi pemanggilan metode menyimpan hasilnya, sehingga instance yang dibangun harus dipindahkan ke register dengan instruksi move-result-object yang segera berikutnya (jika akan digunakan ).
25 3rc fill-new-array/range {vCCCC .. vNNNN}, ketik@BBBB A: ukuran array dan jumlah kata argumen (8 bit)
B: tipe indeks (16 bit)
C: register argumen pertama (16 bit)
N = A + C - 1
Buat array dengan tipe dan ukuran tertentu, isi dengan konten yang disediakan. Klarifikasi dan pembatasan sama dengan filled-new-array , yang dijelaskan di atas.
26 31t fill-array-data vAA, +BBBBBBBB (dengan data tambahan seperti yang ditentukan di bawah ini dalam " Format fill-array-data-payload ") A: referensi array (8 bit)
B: ditandatangani "cabang" offset ke tabel data pseudo-instruksi (32 bit)
Isi array yang diberikan dengan data yang ditunjukkan. Referensi harus ke array primitif, dan tabel data harus cocok dengan tipenya dan tidak boleh mengandung lebih banyak elemen daripada yang sesuai dengan array. Artinya, array mungkin lebih besar dari tabel, dan jika demikian, hanya elemen awal array yang ditetapkan, meninggalkan sisanya saja.
27 11x lempar vAA A: register exception-bearing (8 bit)
Lempar pengecualian yang ditunjukkan.
28 10t masuk +AA A: offset cabang bertanda (8 bit) Lompat tanpa syarat ke instruksi yang ditunjukkan.

Catatan: Cabang offset tidak boleh 0 . (Spin loop dapat dibuat secara legal baik dengan goto/32 atau dengan memasukkan nop sebagai target sebelum cabang.)

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

Catatan: Cabang offset tidak boleh 0 . (Spin loop dapat dibuat secara legal baik dengan goto/32 atau dengan memasukkan nop sebagai target sebelum cabang.)

2a 30t goto/32 +AAAAAAAAA A: offset cabang yang ditandatangani (32 bit)
Lompat tanpa syarat ke instruksi yang ditunjukkan.
2b 31t paket-switch vAA, +BBBBBBBB (dengan data tambahan sebagaimana ditentukan di bawah ini dalam " Format paket packed-switch-payload ") A: mendaftar untuk menguji
B: ditandatangani "cabang" offset ke tabel data pseudo-instruksi (32 bit)
Lompat ke instruksi baru berdasarkan nilai dalam register yang diberikan, menggunakan tabel offset yang sesuai dengan setiap nilai dalam rentang integral tertentu, atau turun ke instruksi berikutnya jika tidak ada kecocokan.
2c 31t vAA sparse-switch, +BBBBBBBB (dengan data tambahan sebagaimana ditentukan di bawah dalam " Format sparse-switch-payload ") A: mendaftar untuk menguji
B: ditandatangani "cabang" offset ke tabel data pseudo-instruksi (32 bit)
Lompat ke instruksi baru berdasarkan nilai dalam register yang diberikan, menggunakan tabel terurut dari pasangan nilai-offset, atau turun ke instruksi berikutnya jika tidak ada kecocokan.
2d..31 23x cmp jenis vAA, vBB, vCC
2d: cmpl-float (bias lt)
2e: cmpg-float (bias gt)
2f: cmpl-double (bias lt)
30: cmpg-ganda (bias gt)
31: panjang cmp
A: register tujuan (8 bit)
B: register atau pasangan sumber pertama
C: register atau pasangan sumber kedua
Lakukan perbandingan titik mengambang atau long yang ditunjukkan, atur a ke 0 jika b == c , 1 jika b > c , atau -1 jika b < c . "Bias" yang tercantum untuk operasi floating point menunjukkan bagaimana perbandingan NaN diperlakukan: instruksi "gt bias" mengembalikan 1 untuk perbandingan NaN , dan instruksi "lt bias" mengembalikan -1 .

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

32..37 22t jika- uji vA, vB, +CCCC
32: jika-persamaan
33: jika-ne
34: jika-lt
35: jika-ge
36: jika-gt
37: jika-le
A: pertama mendaftar untuk menguji (4 bit)
B: register kedua untuk menguji (4 bit)
C: offset cabang bertanda (16 bit)
Bercabang ke tujuan yang diberikan jika nilai dua register yang diberikan dibandingkan dengan yang ditentukan.

Catatan: Cabang offset tidak boleh 0 . (Spin loop dapat dibuat secara legal baik dengan percabangan di sekitar goto mundur atau dengan memasukkan nop sebagai target sebelum percabangan.)

38..3d 21t jika- uji z vAA, +BBBB
38: jika-persamaan
39: jika-nez
3a: jika-ltz
3b: jika-gez
3c: jika-gtz
3d: jika-lez
A: mendaftar untuk menguji (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: Cabang offset tidak boleh 0 . (Spin loop dapat dibuat secara legal baik dengan percabangan di sekitar goto mundur atau dengan memasukkan nop sebagai target sebelum percabangan.)

3e..43 10x (tidak terpakai) (tidak terpakai)
44..51 23x arrayop vAA, vBB, vCC
44: usia
45: usia-lebar
46: usia-objek
47: usia-boolean
48: usia-byte
49: usia-char
4a: usia-pendek
4b: aput
4c: lebar aput
4d: aput-objek
4e: aput-boolean
4f: aput-byte
50: aput-char
51: aput-pendek
A: register nilai atau pasangan; mungkin sumber atau tujuan (8 bit)
B: register array (8 bit)
C: register indeks (8 bit)
Lakukan operasi larik yang teridentifikasi pada indeks yang teridentifikasi dari larik yang diberikan, memuat atau menyimpan ke dalam register nilai.
52.5f 22c saya instanceop vA, vB, field@CCCC
52: saya
53: lebar iget
54: iget-objek
55: iget-boolean
56: iget-byte
57: iget-char
58: iget-pendek
59: iput
5a: lebar-iput
5b: iput-objek
5c: iput-boolean
5d: iput-byte
5e: iput-char
5f: iput-short
A: register nilai atau pasangan; mungkin sumber atau tujuan (4 bit)
B: register objek (4 bit)
C: indeks referensi bidang instance (16 bit)
Lakukan operasi bidang instance objek yang diidentifikasi dengan bidang yang diidentifikasi, memuat atau menyimpan ke dalam register nilai.

Catatan: Opcode ini adalah kandidat yang masuk akal untuk static linking, mengubah argumen field menjadi offset yang lebih langsung.

60.6d 21c s staticop vAA, bidang@BBBB
60: sget
61: lebar sget
62: objek-sget
63: sget-boolean
64: sget-byte
65: sget-char
66: sget-short
67: sput
68: lebar sput
69: sput-objek
6a: sput-boolean
6b: sput-byte
6c: sput-char
6d: sput-pendek
A: register nilai atau pasangan; mungkin sumber atau tujuan (8 bit)
B: indeks referensi bidang statis (16 bit)
Lakukan operasi bidang statis objek yang diidentifikasi dengan bidang statis yang diidentifikasi, memuat atau menyimpan ke dalam register nilai.

Catatan: Opcode ini adalah kandidat yang masuk akal untuk static linking, mengubah argumen field menjadi offset yang lebih langsung.

6e..72 35c jenis panggilan {vC, vD, vE, vF, vG}, meth@BBBB
6e: memanggil-virtual
6f: memanggil-super
70: memanggil-langsung
71: memanggil-statis
72: memanggil-antarmuka
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 instruksi selanjutnya.

invoke-virtual digunakan untuk memanggil metode virtual normal (metode yang bukan private , static , atau final , dan juga bukan konstruktor).

Ketika method_id mereferensikan metode kelas non-interface, invoke-super digunakan untuk memanggil metode virtual superclass terdekat (sebagai lawan dari metode dengan method_id yang sama di kelas 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 yang paling spesifik dan tidak diganti yang ditentukan pada antarmuka itu. Pembatasan metode yang sama berlaku seperti untuk invoke-virtual . Dalam file Dex sebelum versi 037 , memiliki antarmuka method_id adalah ilegal dan tidak terdefinisi.

invoke-direct digunakan untuk memanggil metode langsung non- static (yaitu, metode instans yang menurut sifatnya tidak dapat ditimpa, yaitu metode instans 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 kelas konkretnya tidak diketahui, menggunakan method_id yang merujuk ke interface .

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

73 10x (tidak terpakai) (tidak terpakai)
74..78 3rc jenis panggilan /range {vCCCC .. vNNNN}, meth@BBBB
74: panggilan-virtual/rentang
75: memanggil-super/rentang
76: panggil-langsung/jangkauan
77: aktifkan-statis/rentang
78: panggil-antarmuka/jangkauan
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 detail, peringatan, dan saran.
79..7a 10x (tidak terpakai) (tidak terpakai)
7b..8f 12x buka vA, vB
7b: neg-int
7c: tidak-int
7d: neg-long
7e: tidak lama
7f: neg-float
80: neg-ganda
81: int-ke-panjang
82: int-to-float
83: int-ke-ganda
84: panjang-ke-int
85: panjang-untuk-mengambang
86: panjang-ke-ganda
87: mengambang-ke-int
88: mengambang-ke-panjang
89: mengambang-ke-ganda
8a: ganda-ke-int
8b: ganda-ke-panjang
8c: double-to-float
8d: int-ke-byte
8e: int-to-char
8f: int-to-short
A: register atau pasangan tujuan (4 bit)
B: register sumber atau pasangan (4 bit)
Lakukan operasi unary yang teridentifikasi pada register sumber, simpan hasilnya dalam register tujuan.
90..af 23x binop vAA, vBB, vCC
90: tambahan
91: sub-int
92: multi-int
93: div-int
94: ingat kembali
95: dan-ke
96: or-int
97: xor-int
98: shl-int
99: shr-int
9a: ushr-int
9b: tambah panjang
9c: sub-panjang
9d: mul-long
9e: panjang div
9f: rem-long
a0: dan-panjang
a1: atau-panjang
a2: xor-panjang
a3: shl-panjang
a4: shr-panjang
a5: ushr-long
a6: add-float
a7: kapal selam
a8: mul-float
a9: div-float
aa: rem-float
ab: tambah-ganda
ac: sub-ganda
iklan: mul-ganda
ae: div-double
af: rem-ganda
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 teridentifikasi pada dua register sumber, simpan hasilnya di register tujuan.

Catatan: Berlawanan dengan operasi matematika -long lainnya (yang mengambil pasangan register untuk sumber pertama dan kedua mereka), shl-long , shr- shr-long , dan ushr-long mengambil pasangan register untuk sumber pertama mereka (nilai yang akan digeser ), tetapi satu register untuk sumber kedua mereka (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: dan-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-panjang/2addr
bd: mul-long/2addr
menjadi: div-long/2addr
bf: rem-long/2addr
c0: dan-panjang/2addr
c1: atau-panjang/2addr
c2: xor-panjang/2addr
c3: shl-panjang/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-ganda/2 tambahan
cd: mul-double/2addr
ce: div-double/2addr
cf: rem-double/2addr
A: register atau pasangan tujuan dan sumber pertama (4 bit)
B: register atau pasangan sumber kedua (4 bit)
Lakukan operasi biner yang teridentifikasi pada dua register sumber, simpan hasilnya dalam register sumber pertama.

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

d0..d7 22s binop /lit16 vA, vB, #+CCCC
d0: add-int/lit16
d1: rsub-int (pengurangan terbalik)
d2: mul-int/lit16
d3: div-int/lit16
d4: rem-int/lit16
d5: dan-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), simpan hasilnya di register tujuan.

Catatan: rsub-int tidak memiliki akhiran karena versi ini adalah opcode utama dari keluarganya. Juga, lihat di bawah untuk detail tentang 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: dan-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 yang ditandatangani (8 bit)
Lakukan operasi biner yang ditunjukkan pada register yang ditunjukkan (argumen pertama) dan nilai literal (argumen kedua), simpan hasilnya di register tujuan.

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

e3..f9 10x (tidak terpakai) (tidak terpakai)
fa 45cc panggilan-polimorfik {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 instruksi selanjutnya.

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 tipe argumen yang disediakan dan tipe pengembalian yang diharapkan.

invoke-polymorphic dapat menimbulkan pengecualian saat dijalankan. Pengecualian dijelaskan dalam dokumentasi API untuk metode polimorfik tanda tangan yang dipanggil.

Hadir dalam file Dex dari versi 038 dan seterusnya.
fb 4rcc panggil-polimorfik/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 pegangan metode yang ditunjukkan. Lihat deskripsi invoke-polymorphic di atas untuk detailnya.

Hadir dalam file Dex dari versi 038 dan seterusnya.
fc 35c panggil-kustom {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)
Menyelesaikan dan memanggil situs panggilan yang ditunjukkan. Hasil dari pemanggilan (jika ada) dapat disimpan dengan varian move-result* yang sesuai sebagai instruksi selanjutnya.

Instruksi ini dijalankan dalam dua fase: resolusi panggilan situs dan panggilan situs panggilan.

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

Pemanggilan situs panggilan dilakukan pada target java.lang.invoke.MethodHandle dari instance java.lang.invoke.CallSite yang diselesaikan. Target dipanggil seolah-olah mengeksekusi invoke-polymorphic (dijelaskan di atas) menggunakan pegangan metode dan argumen ke instruksi invoke-custom sebagai argumen ke metode yang tepat menangani pemanggilan.

Pengecualian yang dimunculkan oleh metode bootstrap linker dibungkus dalam java.lang.BootstrapMethodError . BootstrapMethodError juga dimunculkan jika:
  • metode bootstrap linker gagal mengembalikan instance java.lang.invoke.CallSite .
  • java.lang.invoke.CallSite yang dikembalikan memiliki target penanganan metode null .
  • metode menangani target bukan dari jenis yang diminta.
Hadir dalam file Dex dari versi 038 dan seterusnya.
fd 3rc panggil-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
Menyelesaikan dan memanggil situs panggilan. Lihat deskripsi invoke-custom di atas untuk detailnya.

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

Hadir dalam file Dex dari versi 039 dan seterusnya.
ff 21c vAA tipe metode const, 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 dalam register yang ditentukan.

Hadir dalam file Dex dari versi 039 dan seterusnya.

format paket-switch-payload

Nama Format Keterangan
identitas ushort = 0x0100 mengidentifikasi pseudo-opcode
ukuran ushort jumlah entri dalam tabel
first_key ke dalam nilai kasus sakelar pertama (dan terendah)
target int[] daftar size target cabang relatif. Target relatif terhadap alamat opcode switch, bukan dari tabel ini.

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

format sparse-switch-payload

Nama Format Keterangan
identitas 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 size target cabang relatif, masing-masing sesuai dengan nilai kunci pada indeks yang sama. Target relatif terhadap alamat opcode switch, bukan dari tabel ini.

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

format isi-array-data-payload

Nama Format Keterangan
identitas ushort = 0x0300 mengidentifikasi pseudo-opcode
elemen_lebar ushort jumlah byte di setiap elemen
ukuran uint jumlah elemen dalam tabel
data ubit[] nilai data

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

Detail operasi matematika

Catatan: Pengoperasian titik mengambang harus mengikuti aturan IEEE 754, menggunakan aliran bawah putaran-ke-terdekat dan bertahap, kecuali dinyatakan lain.

kode op Semantik C Catatan
neg-int int32 a;
hasil int32 = -a;
Unary twos-complement.
tidak-int int32 a;
hasil int32 = ~a;
Pelengkap yang unary.
panjang lebar int64 a;
hasil int64 = -a;
Unary twos-complement.
tidak lama int64 a;
hasil int64 = ~a;
Pelengkap yang unary.
neg-float mengapung;
float result = -a;
Floating point negation.
neg-double double a;
double result = -a;
Floating point negation.
int-to-long int32 a;
int64 result = (int64) a;
Sign extension of int32 into int64 .
int-to-float int32 a;
float result = (float) a;
Conversion of int32 to float , using round-to-nearest. This loses precision for some values.
int-to-double int32 a;
double result = (double) a;
Conversion of int32 to double .
long-to-int int64 a;
int32 result = (int32) a;
Truncation of int64 into int32 .
long-to-float int64 a;
float result = (float) a;
Conversion of int64 to float , using round-to-nearest. This loses precision for some values.
long-to-double int64 a;
double result = (double) a;
Conversion of int64 to double , using round-to-nearest. This loses precision for some values.
float-to-int float a;
int32 result = (int32) a;
Conversion of float to int32 , using round-toward-zero. NaN and -0.0 (negative zero) convert to the integer 0 . Infinities and values with too large a magnitude to be represented get converted to either 0x7fffffff or -0x80000000 depending on sign.
float-to-long float a;
int64 result = (int64) a;
Conversion of float to int64 , using round-toward-zero. The same special case rules as for float-to-int apply here, except that out-of-range values get converted to either 0x7fffffffffffffff or -0x8000000000000000 depending on sign.
float-to-double float a;
double result = (double) a;
Conversion of float to double , preserving the value exactly.
double-to-int double a;
int32 result = (int32) a;
Conversion of double to int32 , using round-toward-zero. The same special case rules as for float-to-int apply here.
double-to-long double a;
int64 result = (int64) a;
Conversion of double to int64 , using round-toward-zero. The same special case rules as for float-to-long apply here.
double-to-float double a;
float result = (float) a;
Conversion of double to float , using round-to-nearest. This loses precision for some values.
int-to-byte int32 a;
int32 result = (a << 24) >> 24;
Truncation of int32 to int8 , sign extending the result.
int-to-char int32 a;
int32 result = a & 0xffff;
Truncation of int32 to uint16 , without sign extension.
int-to-short int32 a;
int32 result = (a << 16) >> 16;
Truncation of int32 to int16 , sign extending the result.
add-int int32 a, b;
int32 result = a + b;
Twos-complement addition.
sub-int int32 a, b;
int32 result = a - b;
Twos-complement subtraction.
rsub-int int32 a, b;
int32 result = b - a;
Twos-complement reverse subtraction.
mul-int int32 a, b;
int32 result = a * b;
Twos-complement multiplication.
div-int int32 a, b;
int32 result = a / b;
Twos-complement division, rounded towards zero (that is, truncated to integer). This throws ArithmeticException if b == 0 .
rem-int int32 a, b;
int32 result = a % b;
Twos-complement remainder after division. The sign of the result is the same as that of a , and it is more precisely defined as result == a - (a / b) * b . This throws ArithmeticException if b == 0 .
and-int int32 a, b;
int32 result = a & b;
Bitwise AND.
or-int int32 a, b;
int32 result = a | b;
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 (with masked argument).
shr-int int32 a, b;
int32 result = a >> (b & 0x1f);
Bitwise signed shift right (with masked argument).
ushr-int uint32 a, b;
int32 result = a >> (b & 0x1f);
Bitwise unsigned shift right (with masked argument).
add-long int64 a, b;
int64 result = a + b;
Twos-complement addition.
sub-long int64 a, b;
int64 result = a - b;
Twos-complement subtraction.
mul-long int64 a, b;
int64 result = a * b;
Twos-complement multiplication.
div-long int64 a, b;
int64 result = a / b;
Twos-complement division, rounded towards zero (that is, truncated to integer). This throws ArithmeticException if b == 0 .
rem-long int64 a, b;
int64 result = a % b;
Twos-complement remainder after division. The sign of the result is the same as that of a , and it is more precisely defined as result == a - (a / b) * b . This throws ArithmeticException if b == 0 .
and-long int64 a, b;
int64 result = a & b;
Bitwise AND.
or-long int64 a, b;
int64 result = a | b;
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 (with masked argument).
shr-long int64 a;
int32 b;
int64 result = a >> (b & 0x3f);
Bitwise signed shift right (with masked argument).
ushr-long uint64 a;
int32 b;
int64 result = a >> (b & 0x3f);
Bitwise unsigned shift right (with masked argument).
add-float float a, b;
float result = a + b;
Floating point addition.
sub-float float a, b;
float result = a - b;
Floating point subtraction.
mul-float float a, b;
float result = a * b;
Floating point multiplication.
div-float float a, b;
float result = a / b;
Floating point division.
rem-float float a, b;
float result = a % b;
Floating point remainder after division. This function is different than IEEE 754 remainder and is defined as result == a - roundTowardZero(a / b) * b .
add-double double a, b;
double result = a + b;
Floating point addition.
sub-double double a, b;
double result = a - b;
Floating point subtraction.
mul-double double a, b;
double result = a * b;
Floating point multiplication.
div-double double a, b;
double result = a / b;
Floating point division.
rem-double double a, b;
double result = a % b;
Floating point remainder after division. This function is different than IEEE 754 remainder and is defined as result == a - roundTowardZero(a / b) * b .