Allgemeines Design
- Das Maschinenmodell und die Aufrufkonventionen sollen ungefähr gängige reale Architekturen und C-ähnliche Aufrufkonventionen nachahmen:
- Der Computer ist registerbasiert und Frames haben beim Erstellen eine feste Größe.
Jeder Frame besteht aus einer bestimmten Anzahl von Registern (von der Methode angegeben) sowie allen zusätzlichen Daten, die zur Ausführung der Methode erforderlich sind, z. B. dem Programmzähler und einem Verweis auf die
.dex
-Datei, die die Methode enthält. - Bei Verwendung für Bitwerte (z. B. Ganzzahlen und Gleitkommazahlen) gelten Register als 32 Bit breit. Für 64‑Bit-Werte werden benachbarte Registerpaare verwendet. Für Registerpaare gibt es keine Ausrichtungsanforderungen.
- Bei Verwendung für Objektverweise gelten Register als groß genug, um genau eine solche Referenz zu speichern.
- Binärdarstellung:
(Object) null == (int) 0
. - Die N Argumente einer Methode landen nacheinander in den letzten N Registern des Aufrufframes der Methode. Breite Argumente belegen zwei Register. Instanzmethoden wird als erstes Argument eine
this
-Referenz übergeben.
- Der Computer ist registerbasiert und Frames haben beim Erstellen eine feste Größe.
Jeder Frame besteht aus einer bestimmten Anzahl von Registern (von der Methode angegeben) sowie allen zusätzlichen Daten, die zur Ausführung der Methode erforderlich sind, z. B. dem Programmzähler und einem Verweis auf die
- Die Speichereinheit im Anweisungsstrom ist eine vorzeichenlose 16‑Bit-Quantität. Einige Bits in einigen Anweisungen werden ignoriert oder müssen null sein.
- Anleitungen sind nicht grundlos auf einen bestimmten Typ beschränkt. Bei Anweisungen, die 32‑Bit-Registerwerte ohne Interpretation verschieben, muss beispielsweise nicht angegeben werden, ob Ganzzahlen oder Gleitkommazahlen verschoben werden.
- Es gibt separate, aufgezählte und indexierte Konstantenpools für Verweise auf Strings, Typen, Felder und Methoden.
- Bitweise Literaldaten werden inline im Anweisungsstream dargestellt.
- Da in der Praxis für eine Methode in der Regel nicht mehr als 16 Register erforderlich sind und mehr als acht Register relativ häufig benötigt werden, sind viele Anweisungen auf die Adressierung der ersten 16 Register beschränkt. Soweit zumutbar, erlauben Anweisungen Verweise auf bis zu die ersten 256 Register. Außerdem gibt es Varianten einiger Anweisungen, die eine viel größere Anzahl von Registern zulassen, einschließlich zweier
move
-Anweisungen für alle Zwecke, die Register im Bereichv0
–v65535
adressieren können. Wenn keine Anweisungsvariante zur Adressierung eines gewünschten Registers verfügbar ist, wird der Inhalt des Registers vor dem Vorgang aus dem ursprünglichen Register in ein Low-Register und/oder nach dem Vorgang aus einem Low-Ergebnisregister in ein High-Register verschoben. - Es gibt mehrere „Pseudoanweisungen“, die zum Speichern von Datennutzlasten mit variabler Länge verwendet werden, auf die durch reguläre Anweisungen verwiesen wird (z. B.
fill-array-data
). Solche Anweisungen dürfen während des normalen Ablaufs der Ausführung niemals auftreten. Außerdem müssen sich die Anweisungen an geraden Bytecode-Offset-Positionen befinden, d. h. sie müssen auf 4-Byte-Grenze ausgerichtet sein. Um diese Anforderung zu erfüllen, müssen Tools zur DeX-Generierung eine zusätzlichenop
-Anweisung als Spacer ausgeben, wenn eine solche Anweisung andernfalls nicht ausgerichtet wäre. Obwohl es nicht erforderlich ist, wird bei den meisten Tools davon ausgegangen, dass diese Anweisungen am Ende von Methoden ausgegeben werden, da andernfalls wahrscheinlich zusätzliche Anweisungen erforderlich wären, um um sie herum zu verzweigen. - Bei der Installation auf einem laufenden System werden einige Anweisungen möglicherweise geändert, um die statische Verknüpfung bei der Installation zu optimieren. So kann die Ausführung nach der Verknüpfung schneller erfolgen. Die vorgeschlagenen Varianten finden Sie im zugehörigen Dokument zu Anleitungsformaten. Das Wort „vorgeschlagen“ wird mit Bedacht verwendet. Die Implementierung dieser Empfehlungen ist nicht obligatorisch.
- Syntax und Merkhilfen für Menschen:
- Die Reihenfolge „Ziel dann Quelle“ für Argumente.
- Einige Opcodes haben ein eindeutigen Namenssuffix, das den Typ angibt, auf den sie angewendet werden:
- Typübergreifende 32‑Bit-Opcodes sind nicht gekennzeichnet.
- Typübergreifende 64‑Bit-Opcodes haben das Suffix
-wide
. - Typspezifische Opcodes werden mit ihrem Typ (oder einer einfachen Abkürzung) abgeschlossen:
-boolean
,-byte
,-char
,-short
,-int
,-long
,-float
,-double
,-object
,-string
,-class
oder-void
.
- Einige Opcodes haben ein eindeutig identifizierendes Suffix, um ansonsten identische Vorgänge mit unterschiedlichen Anweisungslayouts oder Optionen zu unterscheiden. Diese Suffixe werden durch einen Schrägstrich („
/
“) von den Hauptnamen getrennt und dienen hauptsächlich dazu, eine Eins-zu-Eins-Zuordnung zu statischen Konstanten im Code zu ermöglichen, der ausführbare Dateien generiert und interpretiert, also Mehrdeutigkeiten für Menschen zu reduzieren. - In den Beschreibungen hier wird die Breite eines Werts (z.B. der Bereich einer Konstante oder die Anzahl der möglicherweise adressierten Register) durch die Verwendung eines Zeichens pro vier Bit Breite hervorgehoben.
- Beispiel: In der Anleitung „
move-wide/from16 vAA, vBBBB
“:- „
move
“ ist der Basis-Opcode, der den Basisvorgang angibt (Verschieben des Werts eines Registers). - „
wide
“ ist das Namenssuffix, das angibt, dass mit großen (64‑Bit) Daten gearbeitet wird. - „
from16
“ ist das Opcode-Suffix, das eine Variante mit einer 16‑Bit-Registerreferenz als Quelle angibt. - „
vAA
“ ist das Zielregister (implizit durch den Vorgang; noch einmal: Zielargumente stehen immer zuerst), das sich im Bereichv0
–v255
befinden muss. - „
vBBBB
“ ist das Quellregister, das sich im Bereichv0
–v65535
befinden muss.
- „
- Weitere Informationen zu den verschiedenen Befehlsformaten (unter „Op & Format“ aufgeführt) sowie zur Opcode-Syntax finden Sie im Dokument zu Befehlsformaten.
- Weitere Informationen dazu, wo der Bytecode in das Gesamtbild passt, finden Sie im Dokument zum
.dex
-Dateiformat.
Zusammenfassung des Bytecode-Sets
Op & Format | Tastenkombination / Syntax | Argumente | Beschreibung |
---|---|---|---|
00 10x | nop | Abfallzyklen.
Hinweis:Datenhaltige Pseudoanweisungen sind mit diesem Opcode getaggt. In diesem Fall gibt das höchste Byte der Opcode-Einheit die Art der Daten an. Weitere Informationen finden Sie unten unter „ |
|
01 12x | move vA, vB | A: Zielregister (4 Bit)B: Quellregister (4 Bit) |
Verschieben Sie den Inhalt eines Nichtobjektregisters in ein anderes. |
02 22x | move/from16 vAA, vBBBB | A: Zielregister (8 Bit)B: Quellregister (16 Bit) |
Verschieben Sie den Inhalt eines Nichtobjektregisters in ein anderes. |
03 32x | move/16 vAAAA, vBBBB | A: Zielregister (16 Bit)B: Quellregister (16 Bit) |
Verschieben Sie den Inhalt eines Nichtobjektregisters in ein anderes. |
04 12x | move-wide vA, vB | A: Zielregisterpaar (4 Bit)B: Quellregisterpaar (4 Bit) |
Verschieben Sie den Inhalt eines Registerpaars in ein anderes.
Hinweis:Es ist zulässig, von |
05 22x | move-wide/from16 vAA, vBBBB | A: Zielregisterpaar (8 Bit)B: Quellregisterpaar (16 Bit) |
Verschieben Sie den Inhalt eines Registerpaars in ein anderes.
Hinweis:Die Implementierungsüberlegungen sind dieselben wie bei |
06 32x | move-wide/16 vAAAA, vBBBB | A: Zielregisterpaar (16 Bit)B: Quellregisterpaar (16 Bit) |
Verschieben Sie den Inhalt eines Registerpaars in ein anderes.
Hinweis:Die Implementierungsüberlegungen sind dieselben wie bei |
07 12x | move-object vA, vB | A: Zielregister (4 Bit)B: Quellregister (4 Bit) |
Verschieben des Inhalts eines Registers mit Objekten in ein anderes. |
08 22x | move-object/from16 vAA, vBBBB | A: Zielregister (8 Bit)B: Quellregister (16 Bit) |
Verschieben des Inhalts eines Registers mit Objekten in ein anderes. |
09 32x | move-object/16 vAAAA, vBBBB | A: Zielregister (16 Bit)B: Quellregister (16 Bit) |
Verschieben des Inhalts eines Registers mit Objekten in ein anderes. |
0a 11x | move-result vAA | A: Zielregister (8 Bit) |
Verschieben Sie das einsilbige Nichtobjektergebnis der letzten invoke-kind in das angegebene Register.
Dies muss als Anweisung unmittelbar nach einer invoke-kind erfolgen, deren (einwortiges, kein Objekt) Ergebnis nicht ignoriert werden soll. An anderer Stelle ist dies ungültig. |
0b 11x | move-result-wide vAA | A: -Zielregisterpaar (8 Bit) |
Verschieben Sie das Doppelwortergebnis der letzten invoke-kind in das angegebene Registerpaar.
Dies muss als Anweisung unmittelbar nach einer invoke-kind erfolgen, deren (Zweiwort-)Ergebnis nicht ignoriert werden soll. An anderer Stelle ist dies ungültig. |
0c 11x | move-result-object vAA | A: Zielregister (8 Bit) |
Verschieben Sie das Objektergebnis des letzten invoke-kind in das angegebene Register. Dies muss als Anweisung unmittelbar nach einer invoke-kind oder filled-new-array erfolgen, deren (Objekt-)Ergebnis nicht ignoriert werden soll. An anderer Stelle ist dies ungültig. |
0 Tage, 11-fach | move-exception vAA | A: Zielregister (8 Bit) |
Speichert eine gerade aufgetretene Ausnahme im angegebenen Register. Dies muss die erste Anweisung eines jeden Ausnahme-Handlers sein, dessen aufgefangene Ausnahme nicht ignoriert werden soll. Außerdem darf diese Anweisung nur als erste Anweisung eines Ausnahme-Handlers vorkommen. An anderer Stelle ist sie ungültig. |
0e 10x | return-void | Rückkehr aus einer void -Methode |
|
0f 11x | return vAA | A: -Rückgabewertregister (8 Bit) |
Rückgabe von einer Methode mit einer einzelnen Breite (32 Bit), die keinen Objektwert zurückgibt. |
10 11x | return-wide vAA | A: Rückgabewertregisterpaar (8 Bit) |
Rückgabe von einer Methode mit doppelter Breite (64 Bit), die einen Wert zurückgibt. |
11 11x | return-object vAA | A: -Rückgabewertregister (8 Bit) |
Rückgabe aus einer Methode, die ein Objekt zurückgibt. |
12 11n | const/4 vA, #+B | A: Zielregister (4 Bit)B: signierte Ganzzahl (4 Bit) |
Verschiebt den angegebenen Literalwert (auf 32 Bit erweitert) in das angegebene Register. |
13 21 s | const/16 vAA, #+BBBB | A: Zielregister (8 Bit)B: Ganzzahl mit Vorzeichen (16 Bit) |
Verschiebt den angegebenen Literalwert (auf 32 Bit erweitert) in das angegebene Register. |
14 31i | const vAA, #+BBBBBBBB | A: Zielregister (8 Bit)B: beliebige 32‑Bit-Konstante |
Verschiebt den angegebenen Literalwert in das angegebene Register. |
15 21 Uhr | const/high16 vAA, #+BBBB0000 | A: Zielregister (8 Bit)B: Ganzzahl mit Vorzeichen (16 Bit) |
Verschiebt den angegebenen Literalwert (nach rechts auf 32 Bit erweitert) in das angegebene Register. |
16 21 s | const-wide/16 vAA, #+BBBB | A: Zielregister (8 Bit)B: Ganzzahl mit Vorzeichen (16 Bit) |
Verschiebt den angegebenen Literalwert (auf 64 Bit erweitert mit Vorzeichen) in das angegebene Registerpaar. |
17 31i | const-wide/32 vAA, #+BBBBBBBB | A: Zielregister (8 Bit)B: Ganzzahl mit Vorzeichen (32 Bit) |
Verschiebt den angegebenen Literalwert (auf 64 Bit erweitert mit Vorzeichen) in das angegebene Registerpaar. |
18 51 l | const-wide vAA, #+BBBBBBBBBBBBBBBB | A: Zielregister (8 Bit)B: beliebige Konstante mit doppelter Breite (64 Bit) |
Verschiebt den angegebenen Literalwert in das angegebene Registerpaar. |
19 21 Uhr | const-wide/high16 vAA, #+BBBB000000000000 | A: Zielregister (8 Bit)B: Ganzzahl mit Vorzeichen (16 Bit) |
Verschiebt den angegebenen Literalwert (nach rechts auf 64 Bit erweitert) in das angegebene Registerpaar. |
1a 21c | const-string vAA, string@BBBB | A: Zielregister (8 Bit)B: Stringindex |
Verschiebt einen Verweis auf den String, der durch den angegebenen Index angegeben ist, in das angegebene Register. |
1b 31c | const-string/jumbo vAA, string@BBBBBBBB | A: Zielregister (8 Bit)B: Stringindex |
Verschiebt einen Verweis auf den String, der durch den angegebenen Index angegeben ist, in das angegebene Register. |
1c 21c | const-class vAA, type@BBBB | A: -Zielregister (8 Bit)B: -Typindex |
Verschiebt einen Verweis auf die durch den angegebenen Index angegebene Klasse in das angegebene Register. Wenn der angegebene Typ primitiv ist, wird ein Verweis auf die degenerierte Klasse des primitiven Typs gespeichert. |
1d 11x | monitor-enter vAA | A: Referenzregister (8 Bit) |
Den Monitor für das angegebene Objekt erfassen. |
1e 11x | monitor-exit vAA | A: Referenzregister (8 Bit) |
Monitor für das angegebene Objekt freigeben
Hinweis:Wenn diese Anweisung eine Ausnahme auslösen muss, muss dies so erfolgen, als wäre der PC bereits über die Anweisung hinausgekommen.
Man kann sich das so vorstellen, dass die Anweisung (in gewissem Sinne) erfolgreich ausgeführt wird und die Ausnahme nach der Anweisung, aber bevor die nächste Anweisung ausgeführt werden kann, ausgelöst wird. Diese Definition ermöglicht es einer Methode, einen All-Catch-Monitor zur Bereinigung zu verwenden (z.B. |
1f 21c | check-cast vAA, type@BBBB | A: Referenzregister (8 Bit)B: Typindex (16 Bit) |
Eine ClassCastException wird geworfen, wenn die Referenz im angegebenen Register nicht in den angegebenen Typ umgewandelt werden kann.
Hinweis:Da |
20 22c | instance-of vA, vB, type@CCCC | A: Zielregister (4 Bit)B: Referenzregister (4 Bit)C: Typindex (16 Bit) |
Speichern Sie im angegebenen Zielregister 1 , wenn die angegebene Referenz eine Instanz des angegebenen Typs ist, oder 0 , wenn nicht.
Hinweis:Da |
21 12x | array-length vA, vB | A: Zielregister (4 Bit)B: Register mit Arrayreferenz (4 Bit) |
Speichert die Länge des angegebenen Arrays in Einträgen im angegebenen Zielregister. |
22 21c | new-instance vAA, type@BBBB | A: -Zielregister (8 Bit)B: -Typindex |
Eine neue Instanz des angegebenen Typs erstellen und einen Verweis darauf im Ziel speichern. Der Typ muss sich auf eine Nicht-Array-Klasse beziehen. |
23 22c | new-array vA, vB, type@CCCC | A: Zielregister (4 Bit)B: GrößeregisterC: Typindex |
Erstellt ein neues Array mit dem angegebenen Typ und der angegebenen Größe. Der Typ muss ein Arraytyp sein. |
24 35c | filled-new-array {vC, vD, vE, vF, vG}, type@BBBB |
A: Arraygröße und Anzahl der Argumentwörter (4 Bit)B: Typindex (16 Bit)C..G: Argumentregister (jeweils 4 Bit)
|
Erstellt ein Array des angegebenen Typs und der angegebenen Größe und füllt es mit den angegebenen Inhalten. Der Typ muss ein Arraytyp sein. Der Inhalt des Arrays muss aus einem einzelnen Wort bestehen. Das heißt, es dürfen keine Arrays von long oder double verwendet werden, aber Referenztypen sind zulässig. Die erstellte Instanz wird als „Ergebnis“ gespeichert, genau wie die Anweisungen zur Methodenaufruf ihre Ergebnisse speichern. Daher muss die erstellte Instanz mit einer unmittelbar nachfolgenden move-result-object -Anweisung in ein Register verschoben werden, wenn sie verwendet werden soll. |
25. 3. c | filled-new-array/range {vCCCC .. vNNNN}, type@BBBB | A: Arraygröße und Wortanzahl des Arguments (8 Bit)B: Typindex (16 Bit)C: Erstes Argumentregister (16 Bit)N = A + C - 1 |
Erstellt ein Array des angegebenen Typs und der angegebenen Größe und füllt es mit dem angegebenen Inhalt. Erläuterungen und Einschränkungen entsprechen denen für filled-new-array , wie oben beschrieben. |
26 31t | fill-array-data vAA, +BBBBBBBB (mit ergänzenden Daten wie unten unter „fill-array-data-payload Format“ angegeben) |
A: -Arrayreferenz (8 Bit)B: vorzeichenbehafteter „Branch“-Offset zu Pseudo-Anweisung für Tabellendaten (32 Bit)
|
Füllen Sie das angegebene Array mit den angegebenen Daten. Die Referenz muss auf ein Array von Primitiven verweisen. Die Datentabelle muss mit dem Typ übereinstimmen und darf nicht mehr Elemente enthalten, als in das Array passen. Das Array kann also größer als die Tabelle sein. In diesem Fall werden nur die ersten Elemente des Arrays festgelegt und der Rest bleibt unverändert. |
27 11x | vAA auswerfen | A: Ausnahmeregister (8 Bit) |
Die angegebene Ausnahme auslösen. |
28 10t | goto +AA | A: Vorzeichenbehafteter Verzweigungsoffset (8 Bit) |
Unbedingt zur angegebenen Anweisung springen.
Hinweis:Der Verzweigungsoffset darf nicht |
29 20t | goto/16 +AAAA | A: signed branch offset (16 Bit) |
Unbedingt zur angegebenen Anweisung springen.
Hinweis:Der Verzweigungsoffset darf nicht |
2a 30t | goto/32 +AAAAAAAA | A: Vorzeichenbehafteter Verzweigungsoffset (32 Bit) |
Unbedingt zur angegebenen Anweisung springen. |
2b 31t | packed-switch vAA, +BBBBBBBB (mit ergänzenden Daten wie unten unter „packed-switch-payload Format“ angegeben) |
A: -Register zum TestenB: vorzeichenbehafteter „Branch“-Offset zu Pseudo-Anweisung für Tabellendaten (32 Bit)
|
Springt basierend auf dem Wert im angegebenen Register mithilfe einer Tabelle mit Offsetwerten zu einer neuen Anweisung, die jedem Wert in einem bestimmten Ganzzahlbereich entspricht, oder geht zur nächsten Anweisung über, wenn keine Übereinstimmung gefunden wird. |
2c 31t | sparse-switch vAA, +BBBBBBBB (mit ergänzenden Daten wie unten unter „sparse-switch-payload Format“ angegeben) |
A: -Register zum TestenB: vorzeichenbehafteter „Branch“-Offset zu Pseudo-Anweisung für Tabellendaten (32 Bit)
|
Springt je nach Wert im angegebenen Register mithilfe einer sortierten Tabelle von Wert-Offset-Paaren zu einer neuen Anweisung oder geht zur nächsten Anweisung über, wenn keine Übereinstimmung gefunden wird. |
2d..31 23x | cmpkind vAA, vBB, vCC 2d: cmpl-float (lt bias) 2e: cmpg-float (gt bias) 2f: cmpl-double (lt bias) 30: cmpg-double (gt bias) 31: cmp-long |
A: Zielregister (8 Bit)B: erstes Quellregister oder ‑paarC: zweites Quellregister oder ‑paar |
Führen Sie den angegebenen Vergleich mit Gleitkommazahlen oder long aus. Legen Sie a auf 0 fest, wenn b == c , auf 1 , wenn b > c , oder auf -1 , wenn b < c .
Die für die Gleitkommaoperationen aufgeführte „Abweichung“ gibt an, wie NaN -Vergleiche behandelt werden: Anweisungen vom Typ „gt bias“ geben bei NaN -Vergleichen 1 zurück und Anweisungen vom Typ „lt bias“ geben -1 zurück.
Wenn Sie beispielsweise prüfen möchten, ob ein Gleitkommawert |
32..37 22t | if-test vA, vB, +CCCC 32: if-eq 33: if-ne 34: if-lt 35: if-ge 36: if-gt 37: if-le |
A: erstes zu testendes Register (4 Bit)B: zweites zu testendes Register (4 Bit)C: vorzeichenbehafteter Verzweigungsoffset (16 Bit) |
Springt zum angegebenen Ziel, wenn die Werte der beiden angegebenen Register den angegebenen Vergleichsbedingungen entsprechen.
Hinweis:Der Verzweigungsoffset darf nicht |
38..3d 21t | if-testz vAA, +BBBB 38: if-eqz 39: if-nez 3a: if-ltz 3b: if-gez 3c: if-gtz 3d: if-lez |
A: -Register zum Testen (8 Bit)B: vorzeichenbehafteter Verzweigungsoffset (16 Bit) |
Springt zum angegebenen Ziel, wenn der Wert des angegebenen Registers wie angegeben mit 0 verglichen wird.
Hinweis:Der Verzweigungsoffset darf nicht |
3e..43 10x | (nicht verwendet) | (nicht verwendet) | |
44..51 23x | arrayop vAA, vBB, vCC 44: aget 45: aget-wide 46: aget-object 47: aget-boolean 48: aget-byte 49: aget-char 4a: aget-short 4b: aput 4c: aput-wide 4d: aput-object 4e: aput-boolean 4f: aput-byte 50: aput-char 51: aput-short |
A: -Wertregister oder ‑Paar; kann „Quelle“ oder „Ziel“ sein (8 Bit)B: -Arrayregister (8 Bit)C: -Indexregister (8 Bit) |
Führen Sie den angegebenen Arrayvorgang am angegebenen Index des angegebenen Arrays aus und laden Sie ihn in das Wertregister. |
52..5f 22c | iinstanceop vA, vB, field@CCCC 52: iget 53: iget-wide 54: iget-object 55: iget-boolean 56: iget-byte 57: iget-char 58: iget-short 59: iput 5a: iput-wide 5b: iput-object 5c: iput-boolean 5d: iput-byte 5e: iput-char 5f: iput-short |
A: -Wertregister oder ‑Paar; kann „Quelle“ oder „Ziel“ sein (4 Bit)B: -Objektregister (4 Bit)C: -Referenzindex des Instanzfelds (16 Bit) |
Führen Sie den Feldvorgang für die identifizierte Objektinstanz mit dem entsprechenden Feld aus und laden Sie den Wert in das Wertregister.
Hinweis:Diese Opcodes sind geeignete Kandidaten für die statische Verknüpfung, wobei das Feldargument in einen direkteren Offset geändert wird. |
60..6d 21c | sstaticop vAA, field@BBBB 60: sget 61: sget-wide 62: sget-object 63: sget-boolean 64: sget-byte 65: sget-char 66: sget-short 67: sput 68: sput-wide 69: sput-object 6a: sput-boolean 6b: sput-byte 6c: sput-char 6d: sput-short |
A: -Wertregister oder ‑Paar; kann „Quelle“ oder „Ziel“ sein (8 Bit)B: -Index für den Verweis auf ein statisches Feld (16 Bit) |
Führen Sie den Vorgang für das identifizierte statische Objektfeld mit dem identifizierten statischen Feld aus und laden Sie es in das Wertregister.
Hinweis:Diese Opcodes sind geeignete Kandidaten für die statische Verknüpfung, wobei das Feldargument in einen direkteren Offset geändert wird. |
6e..72 35c | invoke-kind {vC, vD, vE, vF, vG}, meth@BBBB 6e: invoke-virtual 6f: invoke-super 70: invoke-direct 71: invoke-static 72: invoke-interface |
A: Anzahl der Argumentwörter (4 Bit)B: Methodenreferenzindex (16 Bit)C..G: Argumentregister (jeweils 4 Bit)
|
Rufen Sie die angegebene Methode auf. Das Ergebnis (falls vorhanden) kann mit einer geeigneten move-result* -Variante als unmittelbar nachfolgende Anweisung gespeichert werden.
Wenn Wenn sich
Hinweis:Diese Opcodes sind geeignete Kandidaten für die statische Verknüpfung, da das Methodenargument in einen direkteren Offset (oder ein Paar davon) geändert wird. |
73 10x | (nicht verwendet) | (nicht verwendet) | |
74..78 3rc | invoke-kind/range {vCCCC .. vNNNN}, meth@BBBB 74: invoke-virtual/range 75: invoke-super/range 76: invoke-direct/range 77: invoke-static/range 78: invoke-interface/range |
A: Argumentwortanzahl (8 Bit)B: Methodenreferenzindex (16 Bit)C: Erstes Argumentregister (16 Bit)N = A + C - 1 |
Rufen Sie die angegebene Methode auf. Weitere Informationen, Hinweise und Vorschläge finden Sie in der ersten invoke-kind -Beschreibung oben.
|
79..7a 10x | (nicht verwendet) | (nicht verwendet) | |
7b..8f 12x | unop vA, vB 7b: neg-int 7c: not-int 7d: neg-long 7e: not-long 7f: neg-float 80: neg-double 81: int-to-long 82: int-to-float 83: int-to-double 84: long-to-int 85: long-to-float 86: long-to-double 87: float-to-int 88: float-to-long 89: float-to-double 8a: double-to-int 8b: double-to-long 8c: double-to-float 8d: int-to-byte 8e: int-to-char 8f: int-to-short |
A: Zielregister oder ‑paar (4 Bit)B: Quellregister oder ‑paar (4 Bit) |
Führen Sie den identifizierten unary-Vorgang auf dem Quellregister aus und speichern Sie das Ergebnis im Zielregister. |
90..af 23x | binop vAA, vBB, vCC 90: add-int 91: sub-int 92: mul-int 93: div-int 94: rem-int 95: and-int 96: or-int 97: xor-int 98: shl-int 99: shr-int 9a: ushr-int 9b: add-long 9c: sub-long 9d: mul-long 9e: div-long 9f: rem-long a0: and-long a1: or-long a2: xor-long a3: shl-long a4: shr-long a5: ushr-long a6: add-float a7: sub-float a8: mul-float a9: div-float aa: rem-float ab: add-double ac: sub-double ad: mul-double ae: div-double af: rem-double |
A: Zielregister oder ‑paar (8 Bit)B: erstes Quellregister oder ‑paar (8 Bit)C: zweites Quellregister oder ‑paar (8 Bit) |
Führen Sie den identifizierten Binärvorgang auf den beiden Quellregistern aus und speichern Sie das Ergebnis im Zielregister.
Hinweis:Im Gegensatz zu anderen |
b0..cf 12x | binop/2addr vA, vB b0: add-int/2addr b1: sub-int/2addr b2: mul-int/2addr b3: div-int/2addr b4: rem-int/2addr b5: and-int/2addr b6: or-int/2addr b7: xor-int/2addr b8: shl-int/2addr b9: shr-int/2addr ba: ushr-int/2addr bb: add-long/2addr bc: sub-long/2addr bd: mul-long/2addr be: div-long/2addr bf: rem-long/2addr c0: and-long/2addr c1: or-long/2addr c2: xor-long/2addr c3: shl-long/2addr c4: shr-long/2addr c5: ushr-long/2addr c6: add-float/2addr c7: sub-float/2addr c8: mul-float/2addr c9: div-float/2addr ca: rem-float/2addr cb: add-double/2addr cc: sub-double/2addr cd: mul-double/2addr ce: div-double/2addr cf: rem-double/2addr |
A: Ziel- und erstes Quellregister oder ‑paar (4 Bit)B: zweites Quellregister oder ‑paar (4 Bit) |
Führen Sie den identifizierten Binärvorgang auf den beiden Quellregistern aus und speichern Sie das Ergebnis im ersten Quellregister.
Hinweis:Im Gegensatz zu anderen |
d0..d7 22s | binop/lit16 vA, vB, #+CCCC d0: add-int/lit16 d1: rsub-int (RSUB – umgekehrte Subtraktion) d2: mul-int/lit16 d3: div-int/lit16 d4: rem-int/lit16 d5: and-int/lit16 d6: or-int/lit16 d7: xor-int/lit16 |
A: Zielregister (4 Bit)B: Quellregister (4 Bit)C: Vorzeichenbehaftete Ganzzahlkonstante (16 Bit) |
Führt die angegebene binäre Operation auf dem angegebenen Register (erstes Argument) und dem Literalwert (zweites Argument) aus und speichert das Ergebnis im Zielregister.
Hinweis: |
d8..e2 22b | binop/lit8 vAA, vBB, #+CC d8: add-int/lit8 d9: rsub-int/lit8 da: mul-int/lit8 db: div-int/lit8 dc: rem-int/lit8 dd: and-int/lit8 de: or-int/lit8 df: xor-int/lit8 e0: shl-int/lit8 e1: shr-int/lit8 e2: ushr-int/lit8 |
A: Zielregister (8 Bit)B: Quellregister (8 Bit)C: Ganzzahlkonstante mit Vorzeichen (8 Bit) |
Führt die angegebene binäre Operation auf dem angegebenen Register (erstes Argument) und dem Literalwert (zweites Argument) aus und speichert das Ergebnis im Zielregister.
Hinweis:Weitere Informationen zur Semantik von |
e3..f9 10x | (nicht verwendet) | (nicht verwendet) | |
fa 45 cm³ | invoke-polymorphic {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH |
A: Argumentwortanzahl (4 Bit) B: Methodenreferenzindex (16 Bit) C: Empfänger (4 Bit) D..G: Argumentregister (jeweils 4 Bit) H: Prototypreferenzindex (16 Bit)
|
Rufen Sie die angegebene polymorphe Methode auf. Das Ergebnis (falls vorhanden) kann mit einer geeigneten move-result* -Variante als unmittelbar nachfolgende Anweisung gespeichert werden.Die Methodenreferenz muss auf eine signaturpolymorphe Methode verweisen, z. B. java.lang.invoke.MethodHandle.invoke oder java.lang.invoke.MethodHandle.invokeExact .Der Empfänger muss ein Objekt sein, das die aufgerufene signaturpolymorphe Methode unterstützt. In der Prototypreferenz werden die angegebenen Argumenttypen und der erwartete Rückgabetyp beschrieben. Der invoke-polymorphic -Bytecode kann bei der Ausführung Ausnahmen auslösen. Die Ausnahmen werden in der API-Dokumentation für die aufgerufene signaturpolymorphe Methode beschrieben.In Dex-Dateien ab Version 038 vorhanden.
|
fb 4rcc | invoke-polymorphic/range {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH |
A: Anzahl der Argumentwörter (8 Bit) B: Methodenreferenzindex (16 Bit) C: Empfänger (16 Bit) H: Prototypreferenzindex (16 Bit) N = A + C - 1
|
Rufen Sie den angegebenen Methoden-Handle auf. Weitere Informationen finden Sie in der Beschreibung von invoke-polymorphic oben.In Dex-Dateien ab Version 038 vorhanden.
|
fc 35c | invoke-custom {vC, vD, vE, vF, vG}, call_site@BBBB |
A: Anzahl der Argumentwörter (4 Bit) B: Index der Verweisstelle des Aufrufs (16 Bit) C..G: Argumentregister (jeweils 4 Bit)
|
Die angegebene Aufruf-Website wird aufgelöst und aufgerufen.
Das Ergebnis des Aufrufs (falls vorhanden) kann mit einer geeigneten move-result* -Variante als unmittelbar nachfolgende Anweisung gespeichert werden.Diese Anweisung wird in zwei Phasen ausgeführt: Aufrufswebsite-Auflösung und Aufrufswebsite-Aufruf. Bei der Auflösung der Anruf-Website wird geprüft, ob der angegebenen Anruf-Website eine java.lang.invoke.CallSite -Instanz zugeordnet ist.
Andernfalls wird die Bootstrap-Linker-Methode für die angegebene Aufrufstelle mit Argumenten aufgerufen, die in der DEX-Datei vorhanden sind (siehe call_site_item). Die Bootstrap-Linker-Methode gibt eine java.lang.invoke.CallSite -Instanz zurück, die dann der angegebenen Aufrufstelle zugeordnet wird, falls keine Verknüpfung vorhanden ist. Möglicherweise hat ein anderer Thread die Verknüpfung bereits hergestellt. In diesem Fall wird die Ausführung der Anweisung mit der ersten verknüpften java.lang.invoke.CallSite -Instanz fortgesetzt.Der Aufruf der Aufrufstelle erfolgt auf dem java.lang.invoke.MethodHandle -Ziel der aufgelösten java.lang.invoke.CallSite -Instanz. Das Ziel wird aufgerufen, als würde invoke-polymorphic (siehe oben) mit dem Methoden-Handle und den Argumenten für die invoke-custom -Anweisung als Argumente für eine genaue Methoden-Handle-Aufruf ausgeführt.Ausnahmen, die von der Bootstrap-Linker-Methode ausgelöst werden, werden in einen java.lang.BootstrapMethodError eingekapselt. Eine BootstrapMethodError wird auch in folgenden Fällen ausgelöst:
038 vorhanden.
|
fd 3rc | invoke-custom/range {vCCCC .. vNNNN}, call_site@BBBB |
A: Anzahl der Argumentwörter (8 Bit) B: Referenzindex der Aufrufstelle (16 Bit) C: Register für das erste Argument (16 Bit) N = A + C - 1
|
Eine Aufruf-Website auflösen und aufrufen. Weitere Informationen finden Sie in der Beschreibung von invoke-custom oben.In Dex-Dateien ab Version 038 vorhanden.
|
fe 21c | const-method-handle vAA, method_handle@BBBB | A: Zielregister (8 Bit)B: Methode-Handle-Index (16 Bit) |
Verschieben Sie einen Verweis auf den Methoden-Handle, der durch den angegebenen Index angegeben ist, in das angegebene Register. In Dex-Dateien ab Version 039 vorhanden.
|
ff 21c | const-method-type vAA, proto@BBBB | A: Zielregister (8 Bit)B: Referenz zum Methodenprototyp (16 Bit) |
Verschiebt einen Verweis auf den Methodeprototyp, der durch den angegebenen Index angegeben ist, in das angegebene Register. In Dex-Dateien ab Version 039 vorhanden.
|
packed-switch-payload-Format
Name | Format | Beschreibung |
---|---|---|
ident | ushort = 0x0100 | Pseudo-Opcode identifizieren |
Größe | ushort | Anzahl der Einträge in der Tabelle |
first_key | int | Erster (und niedrigster) Switch-Case-Wert |
Ziele | int[] | Liste mit size relativen Verzweigungszielen. Die Ziele beziehen sich auf die Adresse des Switch-Opcodes, nicht auf diese Tabelle.
|
Hinweis:Die Gesamtzahl der Code-Einheiten für eine Instanz dieser Tabelle beträgt (size * 2) + 4
.
Sparse-Switch-Nutzlastformat
Name | Format | Beschreibung |
---|---|---|
ident | ushort = 0x0200 | Pseudo-Opcode identifizieren |
Größe | ushort | Anzahl der Einträge in der Tabelle |
Schlüssel | int[] | Liste der size -Schlüsselwerte, absteigend sortiert |
Ziele | int[] | Liste von size relativen Verzweigungszielen, die jeweils dem Schlüsselwert am selben Index entsprechen. Die Ziele beziehen sich auf die Adresse des Switch-Opcodes, nicht auf diese Tabelle.
|
Hinweis:Die Gesamtzahl der Code-Einheiten für eine Instanz dieser Tabelle beträgt (size * 4) + 2
.
fill-array-data-payload-Format
Name | Format | Beschreibung |
---|---|---|
ident | ushort = 0x0300 | Pseudo-Opcode identifizieren |
element_width | ushort | Anzahl der Byte in jedem Element |
Größe | uint | Anzahl der Elemente in der Tabelle |
Daten | ubyte[] | Datenwerte |
Hinweis:Die Gesamtzahl der Code-Einheiten für eine Instanz dieser Tabelle beträgt (size * element_width + 1) / 2 + 4
.
Details zur mathematischen Operation
Hinweis:Gleitkommaoperationen müssen den IEEE 754-Regeln entsprechen und mit der Rundung auf den nächsten Wert und dem graduellen Unterlauf arbeiten, sofern nicht anders angegeben.
Opcode | C-Semantik | Hinweise |
---|---|---|
neg-int | int32 a; int32 result = -a; |
Einäres Zweierkomplement. |
not-int | int32 a; int32 result = ~a; |
Einäres Eins-Komplement. |
neg-long | int64 a; int64 result = -a; |
Einer-Komplementarzeichenfolge. |
not-long | int64 a; int64 result = ~a; |
Einäres Eins-Komplement. |
neg-float | float a; float result = -a; |
Gleitkommanegation. |
neg-double | double a; double result = -a; |
Gleitkommanegation. |
int-to-long | int32 a; int64 result = (int64) a; |
Signaturerweiterung von int32 in int64 . |
int-to-float | int32 a; float result = (float) a; |
Umwandlung von int32 in float mit Aufrundung auf die nächste ganze Zahl Dadurch geht bei einigen Werten die Genauigkeit verloren.
|
int-to-double | int32 a; double result = (double) a; |
Umwandlung von int32 in double . |
long-to-int | int64 a; int32 result = (int32) a; |
Kürzung von int64 auf int32 |
long-to-float | int64 a; float result = (float) a; |
Umwandlung von int64 in float mit Aufrundung auf die nächste ganze Zahl Dadurch geht bei einigen Werten die Genauigkeit verloren.
|
long-to-double | int64 a; double result = (double) a; |
Umwandlung von int64 in double mit Aufrundung auf die nächste ganze Zahl Dadurch geht bei einigen Werten die Genauigkeit verloren.
|
float-to-int | float a; int32 result = (int32) a; |
Umwandlung von float in int32 mit der Methode „auf Null aufrunden“. NaN und -0.0 (negative Null) werden in die Ganzzahl 0 umgewandelt. Unendliche Werte und Werte mit zu großer Größe, um dargestellt zu werden, werden je nach Vorzeichen in 0x7fffffff oder -0x80000000 umgewandelt.
|
float-to-long | float a; int64 result = (int64) a; |
Umwandlung von float in int64 mit der Methode „auf Null aufrunden“. Hier gelten dieselben Sonderfallregeln wie für float-to-int , mit der Ausnahme, dass Werte außerhalb des zulässigen Bereichs je nach Vorzeichen in 0x7fffffffffffffff oder -0x8000000000000000 umgewandelt werden.
|
float-to-double | float a; double result = (double) a; |
Umwandlung von float in double , wobei der Wert genau beibehalten wird.
|
double-to-int | double a; int32 result = (int32) a; |
Umwandlung von double in int32 mit der Methode „auf Null aufrunden“. Hier gelten dieselben Sonderfallregeln wie für float-to-int .
|
double-to-long | double a; int64 result = (int64) a; |
Umwandlung von double in int64 mit der Methode „auf Null aufrunden“. Hier gelten dieselben Sonderfallregeln wie für float-to-long .
|
double-to-float | double a; float result = (float) a; |
Umwandlung von double in float mit Aufrundung auf die nächste ganze Zahl Dadurch geht bei einigen Werten die Genauigkeit verloren.
|
int-to-byte | int32 a; int32 result = (a << 24) >> 24; |
Kürzung von int32 auf int8 , Zeichen, das das Ergebnis erweitert.
|
int-to-char | int32 a; int32 result = a & 0xffff; |
Kürzung von int32 auf uint16 ohne Vorzeichenerweiterung.
|
int-to-short | int32 a; int32 result = (a << 16) >> 16; |
Kürzung von int32 auf int16 , Zeichen, das das Ergebnis erweitert.
|
add-int | int32 a, b; int32 result = a + b; |
Addition im Zweierkomplementarformat. |
sub-int | int32 a, b; int32 result = a - b; |
Subtraktion im Zweierkomplementarformat. |
rsub-int | int32 a, b; int32 result = b - a; |
Inverser Subtraktionsvorgang im Zweierkomplementarformat. |
mul-int | int32 a, b; int32 result = a * b; |
Multiplikation im Zweierkomplementarformat |
div-int | int32 a, b; int32 result = a / b; |
Division im Zweierkomplementarformat, auf null abgerundet (d. h. auf Ganzzahl gekürzt). Dies führt zu ArithmeticException , wenn b == 0 .
|
rem-int | int32 a, b; int32 result = a % b; |
Der Rest nach der Division im Zweierkomplementarformat. Das Vorzeichen des Ergebnisses ist mit dem von a identisch und wird genauer als result == a - (a / b) * b definiert. Dies führt zu ArithmeticException , wenn b == 0 .
|
and-int | int32 a, b; int32 result = a & b; |
Bitweises AND. |
or-int | int32 a, b; int32 result = a | b; |
Bitweises OR. |
xor-int | int32 a, b; int32 result = a ^ b; |
Bitweises XOR. |
shl-int | int32 a, b; int32 result = a << (b & 0x1f); |
Bitweise Linksverschiebung (mit maskiertem Argument). |
shr-int | int32 a, b; int32 result = a >> (b & 0x1f); |
Bitweise Rechtsverschiebung mit Signatur (mit maskiertem Argument). |
ushr-int | uint32 a, b; int32 result = a >> (b & 0x1f); |
Bitweise Rechtsverschiebung ohne Vorzeichen (mit maskiertem Argument). |
add-long | int64 a, b; int64 result = a + b; |
Addition im Zweierkomplementarformat. |
sub-long | int64 a, b; int64 result = a - b; |
Subtraktion im Zweierkomplementarformat. |
mul-long | int64 a, b; int64 result = a * b; |
Multiplikation im Zweierkomplementarformat |
div-long | int64 a, b; int64 result = a / b; |
Division im Zweierkomplementarformat, auf null abgerundet (d. h. auf Ganzzahl gekürzt). Dies führt zu ArithmeticException , wenn b == 0 .
|
rem-long | int64 a, b; int64 result = a % b; |
Rest nach Division im Zweierkomplementarformat. Das Vorzeichen des Ergebnisses ist mit dem von a identisch und wird genauer als result == a - (a / b) * b definiert. Dies führt zu ArithmeticException , wenn b == 0 .
|
and-long | int64 a, b; int64 result = a & b; |
Bitweises AND. |
or-long | int64 a, b; int64 result = a | b; |
Bitweises OR. |
xor-long | int64 a, b; int64 result = a ^ b; |
Bitweises XOR. |
shl-long | int64 a; int32 b; int64 result = a << (b & 0x3f); |
Bitweise Linksverschiebung (mit maskiertem Argument). |
shr-long | int64 a; int32 b; int64 result = a >> (b & 0x3f); |
Bitweise Rechtsverschiebung mit Signatur (mit maskiertem Argument). |
ushr-long | uint64 a; int32 b; int64 result = a >> (b & 0x3f); |
Bitweise Rechtsverschiebung ohne Vorzeichen (mit maskiertem Argument). |
add-float | float a, b; float result = a + b; |
Gleitkommaaddition |
sub-float | float a, b; float result = a - b; |
Gleitkommasubtraktion. |
mul-float | float a, b; float result = a * b; |
Gleitkommamultiplikation. |
div-float | float a, b; float result = a / b; |
Gleitkommadivision. |
rem-float | float a, b; float result = a % b; |
Der Rest nach der Division im Gleitkommaformat. Diese Funktion unterscheidet sich vom IEEE 754-Rest und ist als result == a - roundTowardZero(a / b) * b definiert.
|
add-double | double a, b; double result = a + b; |
Gleitkommaaddition |
Unterdoppelbett | double a, b; double result = a - b; |
Gleitkommasubtraktion. |
mul-double | double a, b; double result = a * b; |
Gleitkommamultiplikation. |
div-double | double a, b; double result = a / b; |
Gleitkommadivision. |
rem-double | double a, b; double result = a % b; |
Der Rest nach der Division im Gleitkommaformat. Diese Funktion unterscheidet sich vom IEEE 754-Rest und ist als result == a - roundTowardZero(a / b) * b definiert.
|