Format 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 ditetapkan pada saat pembuatan. Setiap frame terdiri dari sejumlah register tertentu (ditentukan oleh metode) serta data tambahan apa pun yang diperlukan untuk menjalankan metode, seperti (namun tidak terbatas pada) penghitung program dan referensi ke file .dex yang berisi metode tersebut .
    • Ketika digunakan untuk nilai bit (seperti bilangan bulat dan bilangan floating point), register dianggap lebarnya 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 untuk suatu metode mendarat di N register terakhir dari kerangka pemanggilan metode, secara berurutan. Argumen yang luas menggunakan dua register. Metode instan meneruskan referensi this sebagai argumen pertamanya.
  • Unit penyimpanan dalam aliran instruksi adalah kuantitas 16-bit yang tidak ditandatangani. Beberapa bit dalam beberapa instruksi diabaikan/harus nol.
  • Instruksi tidak terbatas pada tipe tertentu saja. Misalnya, instruksi yang memindahkan nilai register 32-bit tanpa interpretasi tidak harus menentukan apakah mereka memindahkan int atau float.
  • Ada kumpulan konstanta yang disebutkan dan diindeks secara terpisah untuk referensi ke string, tipe, bidang, dan metode.
  • Data literal bitwise direpresentasikan sebaris dalam aliran instruksi.
  • Karena, dalam praktiknya, jarang sekali suatu metode memerlukan lebih dari 16 register, dan karena memerlukan lebih dari delapan register adalah hal yang lumrah, 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 move yang mencakup semua yang dapat menangani register dalam rentang v0v65535 . Jika varian instruksi tidak tersedia untuk mengalamatkan register yang diinginkan, diharapkan isi register dipindahkan dari register asli ke register rendah (sebelum operasi) dan/atau dipindahkan dari register hasil rendah ke register hasil tinggi. mendaftar (setelah operasi).
  • Ada beberapa "instruksi semu" yang digunakan untuk menyimpan muatan data dengan panjang variabel, yang dirujuk dengan instruksi reguler (misalnya, fill-array-data ). Instruksi seperti itu tidak boleh ditemui selama alur eksekusi normal. Selain itu, instruksi harus ditempatkan pada offset bytecode bernomor genap (yaitu, selaras 4-byte). Untuk memenuhi persyaratan ini, alat pembangkit dex harus mengeluarkan instruksi nop tambahan sebagai pengatur jarak jika instruksi tersebut tidak selaras. Yang terakhir, meskipun tidak diwajibkan, diharapkan sebagian besar alat akan memilih untuk mengeluarkan instruksi-instruksi ini di akhir metode, karena jika tidak, kemungkinan besar instruksi tambahan akan diperlukan untuk melakukan percabangan di sekitar metode tersebut.
  • Ketika diinstal pada sistem yang sedang berjalan, beberapa instruksi mungkin diubah, mengubah formatnya, sebagai optimasi tautan statis saat instalasi. Hal ini untuk memungkinkan eksekusi lebih cepat setelah keterkaitan diketahui. Lihat dokumen format instruksi terkait untuk varian yang disarankan. Kata "disarankan" digunakan dengan bijaksana; tidak wajib untuk menerapkan hal ini.
  • Sintaks manusia dan mnemonik:
    • Urutan tujuan lalu sumber untuk argumen.
    • Beberapa opcode memiliki akhiran nama yang jelas untuk menunjukkan jenis operasinya:
      • Opcode 32-bit tipe umum tidak ditandai.
      • Opcode 64-bit tipe umum diberi akhiran -wide .
      • Opcode khusus tipe diberi akhiran dengan tipenya (atau singkatan langsungnya), salah satu dari: -boolean -byte -char -short -int -long -float -double -object -string -class -void .
    • Beberapa opcode memiliki sufiks yang membedakan operasi serupa yang memiliki tata letak atau opsi instruksi berbeda. Sufiks ini dipisahkan dari nama utama dengan garis miring (" / ") dan pada dasarnya ada 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 lebar.
    • 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 akhiran opcode, yang menunjukkan varian yang memiliki referensi register 16-bit sebagai sumbernya.
      • " vAA " adalah register tujuan (disiratkan oleh operasi; sekali lagi, aturannya adalah argumen tujuan selalu didahulukan), yang harus berada dalam rentang v0v255 .
      • " vBBBB " adalah register sumber, yang harus berada dalam rentang v0v65535 .
  • Lihat dokumen format instruksi untuk rincian lebih lanjut tentang berbagai format instruksi (terdaftar di bawah "Op & Format") serta rincian tentang sintaks opcode.
  • Lihat dokumen format file .dex untuk detail lebih lanjut tentang penempatan bytecode dalam gambaran yang lebih besar.

Ringkasan kumpulan bytecode

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

Catatan: Instruksi semu yang memuat data ditandai dengan opcode ini, dalam hal ini byte tingkat 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 pindah vA, vB A: register tujuan (4 bit)
B: register sumber (4 bit)
Pindahkan isi dari satu register non-objek ke register non-objek lainnya.
02 22x pindah/dari16 vAA, vBBBB A: register tujuan (8 bit)
B: register sumber (16 bit)
Pindahkan isi dari satu register non-objek ke register non-objek lainnya.
03 32x pindah/16 vAAAA, vBBBB A: register tujuan (16 bit)
B: register sumber (16 bit)
Pindahkan isi dari satu register non-objek ke register non-objek lainnya.
04 12x vA lebar gerak, vB A: pasangan register tujuan (4 bit)
B: pasangan register sumber (4 bit)
Pindahkan isi dari satu pasangan register ke pasangan register lainnya.

Catatan: Adalah sah untuk berpindah dari v N ke v N-1 atau v N+1 , jadi implementasi harus mengatur agar kedua bagian 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 pasangan register lainnya.

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 pasangan register lainnya.

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

07 12x memindahkan objek vA, vB A: register tujuan (4 bit)
B: register sumber (4 bit)
Pindahkan isi dari satu register pembawa objek ke register lain.
08 22x memindahkan-objek/dari16 vAA, vBBBB A: register tujuan (8 bit)
B: register sumber (16 bit)
Pindahkan isi dari satu register pembawa objek ke register lain.
09 32x objek bergerak/16 vAAAA, vBBBB A: register tujuan (16 bit)
B: register sumber (16 bit)
Pindahkan isi dari satu register pembawa objek ke register lain.
0a 11x vAA hasil pindahan A: register tujuan (8 bit) Pindahkan hasil satu kata non-objek dari invoke- kind terbaru ke dalam register yang ditunjukkan. Ini harus dilakukan sebagai instruksi segera setelah invoke- kind yang hasilnya (satu kata, non-objek) tidak boleh diabaikan; di tempat lain tidak valid.
0b 11x vAA seluruh hasil perpindahan 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 hasil (kata gandanya) tidak boleh diabaikan; di tempat lain tidak valid.
0c 11x memindahkan-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 array invoke- kind atau filled-new-array yang hasil (objeknya) tidak boleh diabaikan; di tempat lain tidak valid.
0d 11x vAA pengecualian pemindahan A: register tujuan (8 bit) Simpan pengecualian yang baru ditangkap ke dalam register yang diberikan. Ini harus menjadi instruksi pertama dari setiap penangan pengecualian yang pengecualiannya tidak boleh diabaikan, dan instruksi ini hanya boleh muncul sebagai instruksi pertama dari penangan pengecualian; di tempat lain tidak valid.
0e 10x kembali-batal Kembali dari metode void .
0f 11x kembalikan vAA A: register nilai kembalian (8 bit) Kembali dari metode pengembalian nilai non-objek lebar tunggal (32-bit).
10 11x vAA seluruh pengembalian A: pasangan register nilai kembalian (8 bit) Kembali dari metode pengembalian nilai lebar ganda (64-bit).
11 11x vAA objek kembali A: register nilai kembalian (8 bit) Kembali dari metode pengembalian objek.
12 11n konstanta/4 vA, #+B A: register tujuan (4 bit)
B: masuk int (4 bit)
Pindahkan nilai literal yang diberikan (diperluas tanda hingga 32 bit) ke dalam register yang ditentukan.
13 21 detik konstanta/16 vAA, #+BBBB A: register tujuan (8 bit)
B: masuk int (16 bit)
Pindahkan nilai literal yang diberikan (diperluas tanda hingga 32 bit) ke dalam register yang ditentukan.
14 31i konstanta vAA, #+BBBBBBBB A: register tujuan (8 bit)
B: konstanta 32-bit sewenang-wenang
Pindahkan nilai literal yang diberikan ke dalam register yang ditentukan.
15 21 jam konstan/tinggi16 vAA, #+BBBB0000 A: register tujuan (8 bit)
B: masuk int (16 bit)
Pindahkan nilai literal yang diberikan (kanan-nol-diperpanjang hingga 32 bit) ke dalam register yang ditentukan.
16 21 detik lebar konstan/16 vAA, #+BBBB A: register tujuan (8 bit)
B: masuk int (16 bit)
Pindahkan nilai literal yang diberikan (diperluas tanda hingga 64 bit) ke dalam pasangan register yang ditentukan.
17 31i lebar konstan/32 vAA, #+BBBBBBBB A: register tujuan (8 bit)
B: masuk int (32 bit)
Pindahkan nilai literal yang diberikan (diperluas tanda hingga 64 bit) ke dalam pasangan register yang ditentukan.
18 51l vAA lebar konstan, #+BBBBBBBBBBBBBBBB A: register tujuan (8 bit)
B: konstanta lebar ganda (64-bit) sewenang-wenang
Pindahkan nilai literal yang diberikan ke dalam pasangan register yang ditentukan.
19 21 jam vAA lebar konstan/tinggi16, #+BBBB000000000000 A: register tujuan (8 bit)
B: masuk int (16 bit)
Pindahkan nilai literal yang diberikan (kanan-nol-diperpanjang hingga 64 bit) 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 tertentu 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 tertentu ke dalam register yang ditentukan.
1c 21c vAA kelas const, ketik@BBBB A: register tujuan (8 bit)
B: ketik indeks
Pindahkan referensi ke kelas yang ditentukan oleh indeks yang diberikan ke dalam register yang ditentukan. Jika 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 vAA keluar monitor A: register bantalan referensi (8 bit) Lepaskan monitor untuk objek yang ditunjukkan.

Catatan: Jika instruksi ini perlu mengeluarkan pengecualian, instruksi tersebut harus dilakukan seolah-olah pc telah melewati instruksi tersebut. 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 suatu metode untuk menggunakan blok catch-all pembersihan monitor (misalnya, finally ) sebagai pembersihan monitor untuk blok itu sendiri, sebagai cara untuk menangani pengecualian sewenang-wenang yang mungkin terjadi karena implementasi historis dari Thread.stop() , sambil tetap menjaga kebersihan monitor dengan baik.

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

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

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

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

21 12x vA dengan panjang array, vB A: register tujuan (4 bit)
B: register bantalan referensi array (4 bit)
Simpan di tujuan tertentu, daftarkan panjang array yang ditunjukkan, dalam entri
22 21c vAA contoh baru, ketik@BBBB A: register tujuan (8 bit)
B: ketik indeks
Buat instance baru dari tipe yang ditunjukkan, simpan referensi ke sana di tujuan. Tipenya harus mengacu pada kelas non-array.
23 22c vA array baru, vB, ketik@CCCC A: register tujuan (4 bit)
B: daftar ukuran
C: ketik indeks
Buatlah array baru dengan tipe dan ukuran yang ditunjukkan. Tipenya harus berupa tipe array.
24 35c terisi-array baru {vC, vD, vE, vF, vG}, ketik@BBBB A: ukuran array dan jumlah kata argumen (4 bit)
B: ketik indeks (16 bit)
C..G: register argumen (masing-masing 4 bit)
Buatlah array dengan tipe dan ukuran tertentu, isi dengan konten yang disediakan. Tipenya harus berupa tipe array. Isi array harus berupa satu kata (yaitu, tidak ada array 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 menyusul (jika ingin digunakan ).
25 3rc terisi-array/rentang baru {vCCCC .. vNNNN}, ketik@BBBB A: ukuran array dan jumlah kata argumen (8 bit)
B: ketik indeks (16 bit)
C: register argumen pertama (16 bit)
N = A + C - 1
Buatlah array dengan tipe dan ukuran tertentu, isi dengan konten yang disediakan. Klarifikasi dan pembatasannya sama dengan 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" yang ditandatangani ke instruksi semu data tabel (32 bit)
Isi array yang diberikan dengan data yang ditunjukkan. Referensinya harus ke array primitif, dan tabel data harus cocok dengan tipenya dan tidak boleh mengandung lebih banyak elemen daripada yang bisa ditampung dalam array. Artinya, array mungkin lebih besar dari tabel, dan jika demikian, hanya elemen awal array yang ditetapkan, meninggalkan sisanya.
27 11x membuang vAA A: register yang mengandung pengecualian (8 bit)
Lemparkan pengecualian yang ditunjukkan.
28 10t pergi +AA A: offset cabang yang ditandatangani (8 bit) Lompat tanpa syarat ke instruksi yang ditunjukkan.

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

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

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

2a 30t buka/32+AAAAAAAA A: offset cabang bertanda tangan (32 bit)
Lompat tanpa syarat ke instruksi yang ditunjukkan.
2b 31t vAA packet-switch, +BBBBBBBB (dengan data tambahan seperti yang ditentukan di bawah dalam " Formatpacked packed-switch-payload ") A: mendaftar untuk menguji
B: offset "cabang" yang ditandatangani ke instruksi semu data tabel (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 lanjutkan 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: offset "cabang" yang ditandatangani ke instruksi semu data tabel (32 bit)
Lompat ke instruksi baru berdasarkan nilai dalam register yang diberikan, menggunakan tabel urutan pasangan nilai-offset, atau lanjutkan ke instruksi berikutnya jika tidak ada yang cocok.
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 pengujian tersebut benar, dan nilai lainnya menunjukkan bahwa pengujian tersebut salah 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: registrasi pertama untuk menguji (4 bit)
B: register kedua untuk diuji (4 bit)
C: offset cabang bertanda tangan (16 bit)
Cabang ke tujuan tertentu jika nilai dua register yang diberikan sebanding seperti yang ditentukan.

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

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 tangan (16 bit)
Bercabang ke tujuan tertentu jika nilai register yang diberikan sebanding dengan 0 seperti yang ditentukan.

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

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

Catatan: Opcode ini adalah kandidat yang masuk akal untuk penautan statis, mengubah argumen bidang menjadi offset yang lebih langsung.

60..6d 21c s staticop vAA, bidang@BBBB
60: sial
61: lebar-lebar
62: objek-sget
63: sget-boolean
64: sget-byte
65: karakter-karakter
66: pendek
67: muncrat
68: lebar sput
69: objek sput
6a: sput-boolean
6b: sput-byte
6c: sput-char
6d: sput-pendek
A: register atau pasangan nilai; 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 penautan statis, mengubah argumen bidang menjadi offset yang lebih langsung.

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

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-antarmuka, invoke-super digunakan untuk memanggil metode virtual superclass terdekat (sebagai lawan dari metode yang memiliki method_id yang sama di kelas pemanggil). Pembatasan metode yang sama berlaku untuk invoke-virtual .

Dalam file Dex versi 037 atau lebih baru, jika method_id mengacu pada metode antarmuka, invoke-super digunakan untuk memanggil versi paling spesifik dan tidak diganti dari metode yang ditentukan pada antarmuka tersebut. Pembatasan metode yang sama berlaku 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 instan yang sifatnya tidak dapat ditimpa, yaitu metode instan 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 konkritnya tidak diketahui, menggunakan method_id yang merujuk ke interface .

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

73 10x (tidak terpakai) (tidak terpakai)
74..78 3rc panggil- jenis /rentang {vCCCC .. vNNNN}, meth@BBBB
74: pemanggilan-virtual/rentang
75: panggil-super/rentang
76: pemanggilan langsung/rentang
77: pemanggilan-statis/rentang
78: antarmuka/rentang pemanggilan
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 batalkan operasi vA, vB
7b: negatif-int
7c: tidak-int
7d: neg-panjang
7e: tidak lama
7f: neg-float
80: negatif-ganda
81: ke dalam ke panjang
82: ke dalam mengambang
83: ke dalam ke ganda
84: panjang ke int
85: panjang untuk mengapung
86: panjang ke ganda
87: mengapung ke int
88: melayang-ke-panjang
89: mengambang ke ganda
8a: ganda-ke-int
8b: ganda-ke-panjang
8c: ganda menjadi mengambang
8d: int-ke-byte
8e: int-ke-char
8f: int-ke-pendek
A: register atau pasangan tujuan (4 bit)
B: register sumber atau pasangan (4 bit)
Lakukan operasi unary yang teridentifikasi pada register sumber, simpan hasilnya di register tujuan.
90..af 23x binop vAA, vBB, vCC
90: tambahan
91: sub-int
92: multi-int
93: div-int
94: rem-int
95: dan-int
96: atau-int
97: xor-int
98: sial
99: sial
9a: ushr-int
9b: tambah panjang
9c: sub-panjang
9d: mul-panjang
9e: panjang div
9f: rem-panjang
a0: dan-panjang
a1: atau-panjang
a2: xor-panjang
a3: panjang sekali
a4: panjang sekali
a5 : ushr-panjang
a6: tambahkan-float
a7: sub-mengapung
a8: mul-mengapung
a9: div-float
aa: rem-mengapung
ab: tambah-ganda
ac: sub-ganda
iklan: mul-ganda
ae: div-ganda
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: Berbeda dengan operasi matematika -long lainnya (yang mengambil pasangan register untuk sumber pertama dan kedua), shl-long , shr-long , dan ushr-long mengambil pasangan register untuk sumber pertamanya (nilai yang akan digeser ), tetapi register tunggal untuk sumber keduanya (jarak perpindahan).

b0..cf 12x binop /2addr vA, vB
b0: tambahkan-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: tambah-panjang/2addr
bc: sub-panjang/2addr
bd: mul-panjang/2addr
menjadi: div-long/2addr
bf: rem-panjang/2addr
c0: dan-panjang/2addr
c1: atau-panjang/2addr
c2: xor-long/2addr
c3: shl-long/2addr
c4: shr-long/2addr
c5: ushr-long/2addr
c6: tambahkan-float/2addr
c7: sub-float/2addr
c8: mul-float/2addr
c9: div-float/2addr
ca: rem-float/2addr
cb: tambahkan-ganda/2addr
cc: sub-ganda/2addr
CD: mul-double/2addr
ce: div-double/2addr
lih: 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 di register sumber pertama.

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

d0..d7 22s binop /lit16 vA, vB, #+CCCC
d0: tambahkan-int/lit16
d1: rsub-int (pengurangan terbalik)
d2: mul-int/lit16
d3: div-int/lit16
d4: rem-int/lit16
d5: dan-int/lit16
d6: atau-int/lit16
d7: xor-int/lit16
A: register tujuan (4 bit)
B: register sumber (4 bit)
C: konstanta int yang ditandatangani (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: tambahkan-int/lit8
d9: rsub-int/lit8
da: mul-int/lit8
db: div-int/lit8
dc: rem-int/lit8
dd: dan-int/lit8
de: atau-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 panggil-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 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 tipe argumen yang diberikan dan tipe pengembalian yang diharapkan.

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

Hadir dalam file Dex mulai versi 038 dan seterusnya.
fb 4rcc panggil-polimorfik/rentang {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 mulai 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 berikutnya.

Instruksi ini dijalankan dalam dua tahap: resolusi situs panggilan dan pemanggilan situs panggilan.

Resolusi 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 mengembalikan instance java.lang.invoke.CallSite yang kemudian akan dikaitkan dengan situs panggilan yang ditunjukkan jika tidak ada kaitan. Thread lain mungkin telah membuat pengaitan terlebih dahulu, dan jika demikian, eksekusi instruksi 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 diselesaikan. Target dipanggil seolah-olah mengeksekusi invoke-polymorphic (dijelaskan di atas) menggunakan pegangan metode dan argumen pada instruksi invoke-custom sebagai argumen untuk pemanggilan pegangan metode yang tepat.

Pengecualian yang diajukan 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 .
  • target penanganan metode bukan tipe yang diminta.
Hadir dalam file Dex mulai versi 038 dan seterusnya.
fd 3rc panggil-kustom/rentang {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
Selesaikan dan aktifkan situs panggilan. Lihat deskripsi invoke-custom di atas untuk detailnya.

Hadir dalam file Dex mulai versi 038 dan seterusnya.
fe 21c const-metode-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 mulai 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 mulai versi 039 dan seterusnya.

format paket-saklar-muatan

Nama Format Keterangan
identitas ushort = 0x0100 mengidentifikasi pseudo-opcode
ukuran pendek jumlah entri dalam tabel
kunci_pertama ke dalam nilai switch case pertama (dan terendah).
target ke dalam[] daftar size target cabang relatif. Targetnya relatif terhadap alamat opcode sakelar, bukan pada tabel ini.

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

format muatan saklar jarang

Nama Format Keterangan
identitas ushort = 0x0200 mengidentifikasi pseudo-opcode
ukuran pendek jumlah entri dalam tabel
kunci ke dalam[] daftar nilai kunci size , diurutkan dari rendah ke tinggi
target ke dalam[] daftar target cabang relatif size , masing-masing sesuai dengan nilai kunci pada indeks yang sama. Targetnya relatif terhadap alamat opcode sakelar, bukan pada 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 pendek jumlah byte di setiap elemen
ukuran tidak jumlah elemen dalam tabel
data ubita[] nilai data

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

Detail operasi matematika

Catatan: Pengoperasian floating point harus mengikuti aturan IEEE 754, menggunakan aliran bawah bulat ke terdekat dan bertahap, kecuali dinyatakan sebaliknya.

Kode op C Semantik Catatan
negatif-int int32a;
int32 hasil = -a;
Komplemen berpasangan unary.
tidak-int int32a;
int32 hasil = ~a;
Komplemen-unary.
neg-panjang int64a;
int64 hasil = -a;
Komplemen berpasangan unary.
tidak lama int64a;
int64 hasil = ~a;
Komplemen-unary.
neg-float mengapung a;
hasil mengambang = -a;
Negasi titik mengambang.
neg-ganda ganda a;
hasil ganda = -a;
Negasi titik mengambang.
ke dalam ke panjang int32a;
int64 hasil = (int64)a;
Tanda tangani ekstensi int32 ke int64 .
int-to-float int32a;
hasil mengambang = (mengambang) a;
Konversi int32 ke float , menggunakan pembulatan ke terdekat. Ini kehilangan ketepatan untuk beberapa nilai.
int-to-double int32 a;
Hasil ganda = (ganda) a;
Konversi int32 menjadi double .
sudah lama masuk int64 a;
INT32 hasil = (int32) a;
Pemotongan int64 menjadi int32 .
lama mengapung int64 a;
float hasil = (float) a;
Konversi int64 untuk float , menggunakan bulat-ke-nearest. Ini kehilangan ketepatan untuk beberapa nilai.
lama sampai double int64 a;
Hasil ganda = (ganda) a;
Konversi int64 menjadi double , menggunakan bulat-ke-nearest. Ini kehilangan ketepatan untuk beberapa nilai.
float-to-in-in mengapung a;
INT32 hasil = (int32) a;
Konversi float ke int32 , menggunakan round-toward-nol. NaN dan -0.0 (Nol Negatif) Konversi ke Integer 0 . Infinitas dan nilai dengan magnitudo yang terlalu besar untuk diwakili dapat dikonversi menjadi 0x7fffffff atau -0x80000000 tergantung pada tanda.
float to-long mengapung a;
int64 hasil = (int64) a;
Konversi float ke int64 , menggunakan round-toward-nol. Aturan kasus khusus yang sama seperti untuk float-to-int di sini, kecuali bahwa nilai out-of-range dikonversi ke 0x7fffffffffffffff atau -0x8000000000000000 tergantung pada tanda.
float to double mengapung a;
Hasil ganda = (ganda) a;
Konversi float menjadi double , menjaga nilainya dengan tepat.
double-to-cint ganda a;
INT32 hasil = (int32) a;
Konversi double ke int32 , menggunakan Round-Toward-Zero. Aturan kasus khusus yang sama seperti untuk float-to-int berlaku di sini.
ganda ke panjang ganda a;
int64 hasil = (int64) a;
Konversi double ke int64 , menggunakan Round-Toward-Zero. Aturan kasus khusus yang sama seperti untuk float-to-long berlaku di sini.
Double-to-Float ganda a;
float hasil = (float) a;
Konversi double to float , menggunakan Round-to-Nearest. Ini kehilangan ketepatan untuk beberapa nilai.
int-to-byte int32 a;
INT32 hasil = (a << 24) >> 24;
Pemotongan int32 ke int8 , tanda tangani memperluas hasilnya.
int-to-char int32 a;
INT32 Hasil = A & 0XFFFF;
Pemotongan int32 ke uint16 , tanpa ekstensi tanda.
int-to-short int32 a;
INT32 hasil = (a << 16) >> 16;
Pemotongan int32 ke int16 , menandatangani memperluas hasilnya.
Tambah-untuk int32 a, b;
Hasil int32 = a + b;
Penambahan dua pelengkap.
sub-int int32 a, b;
Hasil int32 = a - b;
Pengurangan dua pelengkap.
rsub-int int32 a, b;
Hasil int32 = b - a;
Two-complement reverse pengurangan.
MUL-INT int32 a, b;
Hasil int32 = a * b;
Perkalian dua-pelengkap.
Div-int int32 a, b;
Hasil INT32 = A / B;
Divisi dua pelengkap, dibulatkan ke nol (yaitu, terpotong ke integer). Ini melempar ArithmeticException jika b == 0 .
rem-int int32 a, b;
Hasil INT32 = A % B;
Sisa pelengkap two setelah divisi. Tanda hasilnya sama dengan a , dan lebih tepat didefinisikan sebagai result == a - (a / b) * b . Ini melempar ArithmeticException jika b == 0 .
dan-tidak int32 a, b;
Hasil INT32 = A & B;
Sedikit demi sedikit DAN.
Or-int int32 a, b;
Hasil int32 = a | B;
Sedikit demi sedikit ATAU.
xor-int int32 a, b;
Hasil int32 = a ^ b;
XOR sedikit demi sedikit.
SHL-INT int32 a, b;
INT32 hasil = a << (b & 0x1f);
Bitwise shift kiri (dengan argumen bertopeng).
shr-int int32 a, b;
INT32 hasil = a >> (b & 0x1f);
Bitwise ditandatangani shift kanan (dengan argumen bertopeng).
USHR-INT uint32 a, b;
INT32 hasil = a >> (b & 0x1f);
Bitwise unsigned shift kanan (dengan argumen bertopeng).
tambahkan panjang int64 a, b;
Hasil int64 = a + b;
Penambahan dua pelengkap.
sub-panjang int64 a, b;
Hasil int64 = a - b;
Pengurangan dua pelengkap.
Mul-Long int64 a, b;
Hasil int64 = a * b;
Perkalian dua-pelengkap.
Div panjang int64 a, b;
Hasil int64 = a / b;
Divisi dua pelengkap, dibulatkan ke nol (yaitu, terpotong ke integer). Ini melempar ArithmeticException jika b == 0 .
rem-panjang int64 a, b;
Hasil int64 = a % b;
Sisa pelengkap two setelah divisi. Tanda hasilnya sama dengan a , dan lebih tepat didefinisikan sebagai result == a - (a / b) * b . Ini melempar ArithmeticException jika b == 0 .
dan panjang int64 a, b;
Int64 Hasil = A & B;
Sedikit demi sedikit DAN.
atau panjang int64 a, b;
Int64 Hasil = A | B;
Sedikit demi sedikit ATAU.
xor-panjang int64 a, b;
int64 hasil = a ^ b;
XOR sedikit demi sedikit.
SHL-Long int64 a;
int32 b;
INT64 hasil = a << (b & 0x3f);
Bitwise shift kiri (dengan argumen bertopeng).
shr-panjang int64 a;
int32 b;
INT64 hasil = a >> (b & 0x3f);
Bitwise ditandatangani shift kanan (dengan argumen bertopeng).
Ushr-panjang uint64 a;
int32 b;
INT64 hasil = a >> (b & 0x3f);
Bitwise unsigned shift kanan (dengan argumen bertopeng).
tambahkan float mengapung a, b;
Hasil pelampung = a + b;
Penambahan titik mengambang.
sub-float mengapung a, b;
Hasil pelampung = a - b;
Pengurangan titik mengambang.
MUL-FLOAT mengapung a, b;
Hasil pelampung = A * B;
Perkalian titik mengambang.
Div-float mengapung a, b;
Hasil pelampung = A / B;
Pembagian titik mengambang.
Rem-float mengapung a, b;
Hasil pelampung = A % b;
Sisa titik mengambang setelah divisi. Fungsi ini berbeda dari sisa IEEE 754 dan didefinisikan sebagai result == a - roundTowardZero(a / b) * b .
Tambah double ganda a,b;
Hasil ganda = a + b;
Penambahan titik mengambang.
sub-double ganda a,b;
Hasil ganda = a - b;
Pengurangan titik mengambang.
Mul-double ganda a,b;
Hasil ganda = A * B;
Perkalian titik mengambang.
Div-double ganda a,b;
Hasil ganda = A / B;
Pembagian titik mengambang.
rem-double ganda a,b;
Hasil ganda = a % b;
Sisa titik mengambang setelah divisi. Fungsi ini berbeda dari sisa IEEE 754 dan didefinisikan sebagai result == a - roundTowardZero(a / b) * b .