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