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.
- 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
- 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 rentangv0
–v65535
. 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 instruksinop
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 kisaranv0
–v255
. - "
vBBBB
" adalah register sumber, yang harus dalam kisaranv0
–v65535
.
- "
- 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 | |
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 |
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 |
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 |
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., |
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 |
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 |
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 ukuranC: 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 |
29 20t | goto/16 +AAAA | A: offset cabang bertanda (16 bit) | Lompat tanpa syarat ke instruksi yang ditunjukkan. Catatan: Cabang offset tidak boleh |
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 mengujiB: 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 mengujiB: 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 pertamaC: 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 |
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 |
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 |
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. Ketika Dalam file Dex versi 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 |
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 |
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: |
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 |
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:
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 . |