Allgemeines Design
- Das Maschinenmodell und die Aufrufkonventionen sollen gängige reale Architekturen und Aufrufkonventionen im C-Stil annähernd imitieren:
- Die Maschine ist registerbasiert und die Größe der Rahmen wird bei der Erstellung festgelegt. Jeder Frame besteht aus einer bestimmten Anzahl von Registern (durch die Methode angegeben) sowie allen Zusatzdaten, die zum Ausführen der Methode erforderlich sind, wie z. B. (aber nicht beschränkt auf) 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) werden Register als 32 Bit breit betrachtet. Für 64-Bit-Werte werden benachbarte Registerpaare verwendet. Es gibt keine Ausrichtungsanforderung für Registerpaare.
- Bei der Verwendung für Objektreferenzen gelten Register als breit genug, um genau eine solche Referenz aufzunehmen.
- In Bezug auf die bitweise Darstellung
(Object) null == (int) 0
. - Die N Argumente einer Methode landen der Reihe nach in den letzten N Registern des Aufrufrahmens der Methode. Breite Argumente verbrauchen zwei Register. Instanzmethoden erhalten
this
Referenz als erstes Argument.
- Die Maschine ist registerbasiert und die Größe der Rahmen wird bei der Erstellung festgelegt. Jeder Frame besteht aus einer bestimmten Anzahl von Registern (durch die Methode angegeben) sowie allen Zusatzdaten, die zum Ausführen der Methode erforderlich sind, wie z. B. (aber nicht beschränkt auf) dem Programmzähler und einem Verweis auf die
- Die Speichereinheit im Befehlsstrom ist eine vorzeichenlose 16-Bit-Größe. Einige Bits in einigen Anweisungen werden ignoriert/müssen Null sein.
- Anweisungen sind nicht unnötig auf einen bestimmten Typ beschränkt. Beispielsweise müssen Anweisungen, die 32-Bit-Registerwerte ohne Interpretation verschieben, nicht angeben, ob es sich um Ints oder Floats handelt.
- Es gibt separat aufgezählte und indizierte Konstantenpools für Verweise auf Zeichenfolgen, Typen, Felder und Methoden.
- Bitweise Literaldaten werden im Befehlsstrom inline dargestellt.
- Da es in der Praxis selten vorkommt, dass eine Methode mehr als 16 Register benötigt, und da die Notwendigkeit von mehr als acht Registern durchaus üblich ist , beschränken sich viele Anweisungen darauf, nur die ersten 16 Register zu adressieren. Wenn dies vernünftigerweise möglich ist, erlauben Anweisungen Verweise auf bis zu den ersten 256 Registern. Darüber hinaus verfügen einige Befehle über Varianten, die eine viel größere Registeranzahl ermöglichen, einschließlich eines Paars von Catch-All-
move
, die Register im Bereichv0
–v65535
adressieren können. In Fällen, in denen eine Befehlsvariante nicht verfügbar ist, um ein gewünschtes Register anzusprechen, wird erwartet, dass der Registerinhalt vom ursprünglichen Register in ein niedriges Register (vor der Operation) und/oder von einem niedrigen Ergebnisregister in ein hohes verschoben wird registrieren (nach der Operation). - Es gibt mehrere „Pseudoanweisungen“, die zum Speichern von Datennutzlasten 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 Ausführungsablaufs niemals angetroffen werden. Darüber hinaus müssen sich die Anweisungen auf geraden Bytecode-Offsets befinden (d. h. 4-Byte-ausgerichtet). Um diese Anforderung zu erfüllen, müssen Dex-Generierungstools eine zusätzlichenop
Anweisung als Abstandszeichen ausgeben, wenn eine solche Anweisung andernfalls nicht ausgerichtet wäre. Obwohl dies nicht erforderlich ist, wird erwartet, dass sich die meisten Tools schließlich dafür entscheiden, diese Anweisungen am Ende der Methoden auszugeben, da andernfalls wahrscheinlich zusätzliche Anweisungen erforderlich wären, um sie zu umgehen. - Bei der Installation auf einem laufenden System können einige Anweisungen geändert und ihr Format geändert werden, um die statische Verknüpfung während der Installation zu optimieren. Dies soll eine schnellere Ausführung ermöglichen, sobald die Verknüpfung bekannt ist. Die vorgeschlagenen Varianten finden Sie im zugehörigen Dokument zu den Anweisungsformaten . Das Wort „empfohlen“ wird mit Bedacht verwendet; es ist nicht zwingend erforderlich, diese umzusetzen.
- Menschliche Syntax und Mnemonik:
- Ziel-dann-Quelle-Reihenfolge für Argumente.
- Einige Opcodes haben ein eindeutiges Namenssuffix, um den Typ bzw. die Typen anzugeben, mit denen sie arbeiten:
- Typallgemeine 32-Bit-Opcodes sind nicht markiert.
- Typallgemeine 64-Bit-Opcodes werden mit dem Suffix
-wide
versehen. - Typspezifischen Opcodes wird ihr Typ (oder eine einfache Abkürzung) angehängt, einer der folgenden:
-boolean
-byte
-char
-short
-int
-long
-float
-double
-object
-string
-class
-void
.
- Einige Opcodes verfügen über ein eindeutiges Suffix, um ansonsten identische Operationen mit unterschiedlichen Befehlslayouts oder Optionen zu unterscheiden. Diese Suffixe werden durch einen Schrägstrich („
/
“) von den Hauptnamen getrennt und existieren hauptsächlich überhaupt, um eine Eins-zu-Eins-Zuordnung mit statischen Konstanten im Code zu ermöglichen, der ausführbare Dateien generiert und interpretiert (d. h. um Mehrdeutigkeiten zu reduzieren). für den Menschen). - In den Beschreibungen hier wird die Breite eines Werts (der beispielsweise den Bereich einer Konstante oder die Anzahl der möglicherweise adressierten Register angibt) durch die Verwendung eines Zeichens pro vier Bit Breite hervorgehoben.
- Beispielsweise in der Anweisung „
move-wide/from16 vAA, vBBBB
“:- „
move
“ ist der Basis-Opcode, der die Basisoperation angibt (den Wert eines Registers verschieben). - „
wide
“ ist das Namenssuffix, das darauf hinweist, dass es mit Wide-Daten (64 Bit) arbeitet. - „
from16
“ ist das Opcode-Suffix, das eine Variante angibt, die eine 16-Bit-Registerreferenz als Quelle hat. - „
vAA
“ ist das Zielregister (durch die Operation impliziert; auch hier gilt die Regel, dass Zielargumente immer an erster Stelle stehen), das im Bereichv0
–v255
liegen muss. - „
vBBBB
“ ist das Quellregister, das im Bereichv0
–v65535
liegen muss.
- „
- Weitere Informationen zu den verschiedenen Befehlsformaten (aufgelistet unter „Op & Format“) sowie Einzelheiten zur Opcode-Syntax finden Sie im Dokument „ Anweisungsformate“.
- Weitere Informationen dazu, wo der Bytecode in das Gesamtbild passt, finden Sie im Dokument
.dex
Dateiformat .
Zusammenfassung des Bytecodesatzes
Betrieb und Format | Mnemonik / Syntax | Argumente | Beschreibung |
---|---|---|---|
00 10x | Nein | Abfallkreisläufe. Hinweis: Datentragende Pseudoanweisungen werden mit diesem Opcode gekennzeichnet. In diesem Fall gibt das höherwertige Byte der Opcode-Einheit die Art der Daten an. Siehe „ | |
01 12x | bewegen vA, vB | A: Zielregister (4 Bits)B: Quellregister (4 Bits) | Verschieben Sie den Inhalt eines Nichtobjektregisters in ein anderes. |
02 22x | Umzug/von16 vAA, vBBBB | A: Zielregister (8 Bit)B: Quellregister (16 Bit) | Verschieben Sie den Inhalt eines Nichtobjektregisters in ein anderes. |
03 32x | Zug/16 vAAAA, vBBBB | A: Zielregister (16 Bit)B: Quellregister (16 Bit) | Verschieben Sie den Inhalt eines Nichtobjektregisters in ein anderes. |
04 12x | zugweit vA, vB | A: Zielregisterpaar (4 Bits)B: Quellregisterpaar (4 Bits) | Verschieben Sie den Inhalt eines Registerpaars in ein anderes. Hinweis: Es ist zulässig, von |
05 22x | zugweit/ab 16 vAA, vBBBB | A: Zielregisterpaar (8 Bits)B: Quellregisterpaar (16 Bit) | Verschieben Sie den Inhalt eines Registerpaars in ein anderes. Hinweis: Die Überlegungen zur Implementierung sind die gleichen wie oben bei |
06 32x | zugweit/16 vAAAA, vBBBB | A: Zielregisterpaar (16 Bit)B: Quellregisterpaar (16 Bit) | Verschieben Sie den Inhalt eines Registerpaars in ein anderes. Hinweis: Die Überlegungen zur Implementierung sind die gleichen wie oben bei |
07 12x | Objekt bewegen vA, vB | A: Zielregister (4 Bits)B: Quellregister (4 Bits) | Verschieben Sie den Inhalt eines objekttragenden Registers in ein anderes. |
08 22x | move-object/from16 vAA, vBBBB | A: Zielregister (8 Bit)B: Quellregister (16 Bit) | Verschieben Sie den Inhalt eines objekttragenden Registers in ein anderes. |
09 32x | Objekt bewegen/16 vAAAA, vBBBB | A: Zielregister (16 Bit)B: Quellregister (16 Bit) | Verschieben Sie den Inhalt eines objekttragenden Registers in ein anderes. |
0a 11x | Umzugsergebnis vAA | A: Zielregister (8 Bit) | Verschieben Sie das Einzelwort-Nicht-Objekt-Ergebnis des letzten invoke- kind in das angegebene Register. Dies muss als Anweisung unmittelbar nach einem invoke- kind erfolgen, dessen (Einzelwort-, Nicht-Objekt-)Ergebnis nicht ignoriert werden darf; irgendwo anders ist ungültig. |
0b 11x | verschiebungsergebnisweite vAA | A: Zielregisterpaar (8 Bits) | Verschieben Sie das Doppelwortergebnis des letzten invoke- kind in das angegebene Registerpaar. Dies muss als Anweisung unmittelbar nach einem invoke- kind erfolgen, dessen (Doppelwort-)Ergebnis nicht ignoriert werden darf; irgendwo anders ist 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 einem invoke- kind oder filled-new-array erfolgen, dessen (Objekt-)Ergebnis nicht ignoriert werden darf; irgendwo anders ist ungültig. |
0d 11x | Bewegungsausnahme vAA | A: Zielregister (8 Bit) | Speichern Sie eine gerade abgefangene Ausnahme im angegebenen Register. Dies muss die erste Anweisung eines Ausnahmebehandlers sein, dessen abgefangene Ausnahme nicht ignoriert werden soll, und diese Anweisung darf immer nur als erste Anweisung eines Ausnahmebehandlers auftreten; irgendwo anders ist ungültig. |
0e 10x | Rückkehr-nichtig | Rückkehr von einer void Methode. | |
0f 11x | Rückkehr vAA | A: Rückgabewertregister (8 Bit) | Rückgabe von einer Methode mit einfacher Breite (32 Bit), die keinen Objektwert zurückgibt. |
10 11x | Renditeweites vAA | A: Rückgabewert Registerpaar (8 Bits) | Rückgabe von einer Wertrückgabemethode mit doppelter Breite (64 Bit). |
11 11x | Rückgabeobjekt vAA | A: Rückgabewertregister (8 Bit) | Rückkehr von einer Objekt zurückgebenden Methode. |
12 11n | const/4 vA, #+B | A: Zielregister (4 Bits)B: vorzeichenbehafteter int (4 Bit) | Verschieben Sie den angegebenen Literalwert (vorzeichenerweitert auf 32 Bit) in das angegebene Register. |
13 21s | const/16 vAA, #+BBBB | A: Zielregister (8 Bit)B: signierter int (16 Bit) | Verschieben Sie den angegebenen Literalwert (vorzeichenerweitert auf 32 Bit) in das angegebene Register. |
14 31i | const vAA, #+BBBBBBBB | A: Zielregister (8 Bit)B: beliebige 32-Bit-Konstante | Verschieben Sie den angegebenen Literalwert in das angegebene Register. |
15 21 Uhr | const/high16 vAA, #+BBBB0000 | A: Zielregister (8 Bit)B: signierter int (16 Bit) | Verschieben Sie den angegebenen Literalwert (rechte Null, erweitert auf 32 Bit) in das angegebene Register. |
16 21s | const-wide/16 vAA, #+BBBB | A: Zielregister (8 Bit)B: signierter int (16 Bit) | Verschieben Sie den angegebenen Literalwert (vorzeichenerweitert auf 64 Bit) in das angegebene Registerpaar. |
17 31i | const-wide/32 vAA, #+BBBBBBBB | A: Zielregister (8 Bit)B: signierter int (32 Bit) | Verschieben Sie den angegebenen Literalwert (vorzeichenerweitert auf 64 Bit) in das angegebene Registerpaar. |
18 51l | const-wide vAA, #+BBBBBBBBBBBBBBBB | A: Zielregister (8 Bit)B: beliebige Konstante mit doppelter Breite (64 Bit). | Verschieben Sie den angegebenen Literalwert in das angegebene Registerpaar. |
19 21 Uhr | const-wide/high16 vAA, #+BBBB000000000000 | A: Zielregister (8 Bit)B: signierter int (16 Bit) | Verschieben Sie den angegebenen Literalwert (rechte Null, erweitert auf 64 Bit) in das angegebene Registerpaar. |
1a 21c | const-string vAA, string@BBBB | A: Zielregister (8 Bit)B: String-Index | Verschieben Sie einen Verweis auf die durch den angegebenen Index angegebene Zeichenfolge in das angegebene Register. |
1b 31c | const-string/jumbo vAA, string@BBBBBBBB | A: Zielregister (8 Bit)B: String-Index | Verschieben Sie einen Verweis auf die durch den angegebenen Index angegebene Zeichenfolge in das angegebene Register. |
1c 21c | const-Klasse vAA, Typ@BBBB | A: Zielregister (8 Bit)B: Typindex | Verschieben Sie einen Verweis auf die durch den angegebenen Index angegebene Klasse in das angegebene Register. Wenn der angegebene Typ primitiv ist, wird hiermit ein Verweis auf die degenerierte Klasse des primitiven Typs gespeichert. |
1d 11x | Monitor-Eingabe vAA | A: Referenzlagerregister (8 Bit) | Besorgen Sie sich den Monitor für das angegebene Objekt. |
1e 11x | Monitor-Ausgang vAA | A: Referenzlagerregister (8 Bit) | Lassen Sie den Monitor für das angezeigte Objekt los. Hinweis: Wenn diese Anweisung eine Ausnahme auslösen muss, muss dies so geschehen, als ob der PC bereits über die Anweisung hinausgegangen wäre. Es kann nützlich sein, sich dies so vorzustellen, dass die Anweisung (in gewissem Sinne) erfolgreich ausgeführt wird und die Ausnahme nach der Anweisung ausgelöst wird, aber bevor die nächste ausgeführt werden kann. Diese Definition ermöglicht es einer Methode, einen Catch-All-Block für die Monitorbereinigung (z. B. „ |
1f 21c | Check-Cast vAA, Typ@BBBB | A: Referenzlagerregister (8 Bit)B: Typindex (16 Bit) | Wirft eine ClassCastException aus, wenn die Referenz im angegebenen Register nicht in den angegebenen Typ umgewandelt werden kann. Hinweis: Da |
20 22c | Instanz von vA, vB, Typ@CCCC | A: Zielregister (4 Bits)B: referenzführendes Register (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-Länge vA, vB | A: Zielregister (4 Bits)B: Array-Referenz tragendes Register (4 Bits) | Speichern Sie im angegebenen Zielregister die Länge des angegebenen Arrays in Einträgen |
22 21c | vAA mit neuer Instanz, Typ@BBBB | A: Zielregister (8 Bit)B: Typindex | Erstellen Sie eine neue Instanz des angegebenen Typs und speichern Sie einen Verweis darauf im Ziel. Der Typ muss auf eine Nicht-Array-Klasse verweisen. |
23 22c | Neues Array vA, vB, Typ@CCCC | A: Zielregister (4 Bits)B: GrößenregisterC: Typindex | Erstellen Sie ein neues Array des angegebenen Typs und der angegebenen Größe. Der Typ muss ein Array-Typ sein. |
24 35c | gefülltes neues Array {vC, vD, vE, vF, vG}, Typ@BBBB | A: Array-Größe und Argumentwortanzahl (4 Bits)B: Typindex (16 Bit)C..G: Argumentregister (jeweils 4 Bits) | Erstellen Sie ein Array des angegebenen Typs und der angegebenen Größe und füllen Sie es mit den bereitgestellten Inhalten. Der Typ muss ein Array-Typ sein. Der Inhalt des Arrays muss aus einem Einzelwort bestehen (d. h. es dürfen keine Arrays vom long oder double sein, Referenztypen sind jedoch akzeptabel). Die konstruierte Instanz wird als „Ergebnis“ auf die gleiche Weise gespeichert, wie die Methodenaufrufanweisungen ihre Ergebnisse speichern. Daher muss die konstruierte Instanz mit einer unmittelbar nachfolgenden Anweisung move-result-object “ in ein Register verschoben werden (sofern sie verwendet werden soll). ). |
25 3rc | gefülltes-neues-Array/Bereich {vCCCC .. vNNNN}, Typ@BBBB | A: Array-Größe und Argumentwortanzahl (8 Bit)B: Typindex (16 Bit)C: erstes Argumentregister (16 Bit)N = A + C - 1 | Erstellen Sie ein Array des angegebenen Typs und der angegebenen Größe und füllen Sie es mit den bereitgestellten Inhalten. Klarstellungen und Einschränkungen sind die gleichen wie oben beschrieben für filled-new-array . |
26 31t | Fill-Array-Data vAA, +BBBBBBBB (mit ergänzenden Daten wie unten im „ fill-array-data-payload Format“ angegeben) | A: Array-Referenz (8 Bit)B: vorzeichenbehafteter „Zweig“-Offset zur Tabellendaten-Pseudoanweisung (32 Bit) | Füllen Sie das angegebene Array mit den angegebenen Daten. Der Verweis muss sich auf ein Array von Grundelementen beziehen, und die Datentabelle muss vom Typ her mit diesem übereinstimmen und darf nicht mehr Elemente enthalten, als in das Array passen. Das heißt, das Array kann größer als die Tabelle sein. In diesem Fall werden nur die Anfangselemente des Arrays festgelegt, während der Rest in Ruhe bleibt. |
27 11x | vAA werfen | A: ausnahmetragendes Register (8 Bit) | Löst die angegebene Ausnahme aus. |
28 10t | Gehe zu +AA | A: vorzeichenbehafteter Verzweigungsoffset (8 Bit) | Springen Sie unbedingt zur angegebenen Anweisung. Hinweis: Der Verzweigungsoffset darf nicht |
29 20t | gehe zu/16 +AAAA | A: vorzeichenbehafteter Verzweigungsoffset (16 Bit) | Springen Sie unbedingt zur angegebenen Anweisung. Hinweis: Der Verzweigungsoffset darf nicht |
2a 30t | gehe zu/32 +AAAAAAAA | A: vorzeichenbehafteter Verzweigungsoffset (32 Bit) | Springen Sie unbedingt zur angegebenen Anweisung. |
2b 31t | gepackter Switch vAA, +BBBBBBBB (mit ergänzenden Daten wie unten im „ packed-switch-payload Format“ angegeben) | A: Registrieren Sie sich zum TestenB: vorzeichenbehafteter „Zweig“-Offset zur Tabellendaten-Pseudoanweisung (32 Bit) | Springen Sie zu einem neuen Befehl basierend auf dem Wert im angegebenen Register und verwenden Sie dabei eine Tabelle mit Offsets, die jedem Wert in einem bestimmten ganzzahligen Bereich entsprechen, oder wechseln Sie zum nächsten Befehl, wenn keine Übereinstimmung vorliegt. |
2c 31t | Sparse-Switch vAA, +BBBBBBBB (mit ergänzenden Daten wie unten im „ sparse-switch-payload Format“ angegeben) | A: Registrieren Sie sich zum TestenB: vorzeichenbehafteter „Zweig“-Offset zur Tabellendaten-Pseudoanweisung (32 Bit) | Springen Sie zu einer neuen Anweisung basierend auf dem Wert im angegebenen Register, indem Sie eine geordnete Tabelle von Wert-Offset-Paaren verwenden, oder wechseln Sie zur nächsten Anweisung, wenn es keine Übereinstimmung gibt. |
2d..31 23x | cmp Art 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-lang | A: Zielregister (8 Bit)B: erstes Quellregister oder PaarC: zweites Quellregister oder -paar | Führen Sie den angegebenen Gleitkomma- oder long Vergleich durch und setzen Sie a auf 0 , wenn b == c , 1 wenn b > c , oder -1 wenn b < c . Der für die Gleitkommaoperationen aufgeführte „Bias“ gibt an, wie NaN Vergleiche behandelt werden: „gt-Bias“-Anweisungen geben 1 für NaN Vergleiche zurück und „lt-Bias“-Anweisungen geben -1 zurück. Um beispielsweise zu prüfen, ob Gleitkomma |
32..37 22t | if- Test vA, vB, +CCCC 32: if-eq 33: wenn-nein 34: if-lt 35: if-ge 36: if-gt 37: if-le | A: erstes zu testendes Register (4 Bits)B: zweites zu testendes Register (4 Bits)C: vorzeichenbehafteter Zweigoffset (16 Bit) | Verzweigt zum angegebenen Ziel, wenn die Werte der beiden angegebenen Register wie angegeben übereinstimmen. Hinweis: Der Verzweigungsoffset darf nicht |
38..3d 21t | if- Test z vAA, +BBBB 38: if-eqz 39: if-nez 3a: if-ltz 3b: if-gez 3c: if-gtz 3d: if-lez | A: Zum Testen registrieren (8 Bit)B: vorzeichenbehafteter Zweigoffset (16 Bit) | Verzweigt zum angegebenen Ziel, wenn der Wert des angegebenen Registers wie angegeben mit 0 verglichen wird. Hinweis: Der Verzweigungsoffset darf nicht |
3e..43 10x | (ungebraucht) | (ungebraucht) | |
44..51 23x | Arrayop vAA, vBB, vCC 44: Alter 45: altersweit 46: aget-object 47: aget-boolean 48: Aget-Byte 49: aget-char 4a: alterskurz 4b: aput 4c: aput-weit 4d: aput-Objekt 4e: aput-boolean 4f: aput-byte 50: aput-char 51: aput-kurz | A: Wertregister oder -paar; kann Quelle oder Ziel sein (8 Bit)B: Array-Register (8 Bit)C: Indexregister (8 Bit) | Führen Sie die identifizierte Array-Operation am identifizierten Index des angegebenen Arrays aus und laden oder speichern Sie es im Wertregister. |
52..5f 22c | i Instanzop vA, vB, field@CCCC 52: iget 53: iget-wide 54: iget-Objekt 55: iget-boolean 56: iget-byte 57: iget-char 58: iget-short 59: iput 5a: iput-weit 5b: Iput-Objekt 5c: iput-boolean 5d: Iput-Byte 5e: iput-char 5f: iput-short | A: Wertregister oder -paar; kann Quelle oder Ziel sein (4 Bits)B: Objektregister (4 Bit)C: Instanzfeld-Referenzindex (16 Bit) | Führen Sie die Operation „Identifiziertes Objektinstanzfeld“ mit dem identifizierten Feld aus und laden oder speichern Sie es im Wertregister. Hinweis: Diese Opcodes sind sinnvolle Kandidaten für die statische Verknüpfung, da sie das Feldargument so ändern, dass es einen direkteren Offset ergibt. |
60..6d 21c | s staticop vAA, field@BBBB 60: get 61: get-wide 62: Sget-Objekt 63: sget-boolean 64: Sget-Byte 65: get-char 66: get-short 67: spucken 68: spuckweit 69: Sput-Objekt 6a: sput-boolean 6b: Sput-Byte 6c: Sput-Char 6d: Sput-Short | A: Wertregister oder -paar; kann Quelle oder Ziel sein (8 Bit)B: statischer Feldreferenzindex (16 Bit) | Führen Sie die Operation für das identifizierte statische Objektobjekt mit dem identifizierten statischen Feld aus und laden oder speichern Sie es im Wertregister. Hinweis: Diese Opcodes sind sinnvolle Kandidaten für die statische Verknüpfung, da sie das Feldargument so ändern, dass es einen direkteren Offset ergibt. |
6e..72 35c | invoke- kind {vC, vD, vE, vF, vG}, meth@BBBB 6e: invoke-virtual 6f: invoke-super 70: direkt aufrufen 71: invoke-static 72: Aufrufschnittstelle | A: Argumentwortanzahl (4 Bits)B: Methodenreferenzindex (16 Bit)C..G: Argumentregister (jeweils 4 Bits) | Rufen Sie die angegebene Methode auf. Das Ergebnis (falls vorhanden) kann mit einer entsprechenden move-result* -Variante als unmittelbar nachfolgende Anweisung gespeichert werden. Wenn die Wenn sich Hinweis: Diese Opcodes sind sinnvolle Kandidaten für die statische Verknüpfung, indem sie das Methodenargument so ändern, dass es ein direkterer Offset (oder ein Paar davon) ist. |
73 10x | (ungebraucht) | (ungebraucht) | |
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: Aufrufschnittstelle/Bereich | A: Argumentwortanzahl (8 Bits)B: Methodenreferenzindex (16 Bit)C: erstes Argumentregister (16 Bit)N = A + C - 1 | Rufen Sie die angegebene Methode auf. Einzelheiten, Vorbehalte und Vorschläge finden Sie in der Beschreibung der ersten invoke- kind oben. |
79..7a 10x | (ungebraucht) | (ungebraucht) | |
7b..8f 12x | unop vA, vB 7b: neg-int 7c: nicht-int 7d: neg-lang 7e: nicht lang 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: doppelt bis lang 8c: Double-to-Float 8d: Int-zu-Byte 8e: int-to-char 8f: int-to-short | A: Zielregister oder Zielpaar (4 Bits)B: Quellregister oder -paar (4 Bits) | Führen Sie die identifizierte unäre Operation im Quellregister aus und speichern Sie das Ergebnis im Zielregister. |
90..af 23x | binop vAA, vBB, vCC 90: Add-Int 91: Unterint 92: mul-int 93: div-int 94: rem-int 95: und-int 96: or-int 97: xor-int 98: shl-int 99: shr-int 9a: ushr-int 9b: add-long 9c: sublang 9d: mul-lang 9e: div-lang 9f: rem-lang a0: und-lang a1: oder-lang a2: xor-lang a3: Shl-lang a4: shr-lang a5: ushr-lang a6: Add-Float a7: Unterschwimmer a8: Mul-Float a9: div-float aa: rem-float ab: add-double ac: Sub-Double Anzeige: Mul-Double ae: div-double af: rem-double | A: Zielregister oder Zielpaar (8 Bits)B: erstes Quellregister oder Paar (8 Bits)C: zweites Quellregister oder -paar (8 Bits) | Führen Sie die identifizierte Binäroperation an den beiden Quellregistern durch 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 sein: 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 vgl.: rem-double/2addr | A: Ziel- und erstes Quellregister oder -paar (4 Bits)B: zweites Quellregister oder -paar (4 Bits) | Führen Sie die identifizierte Binäroperation an den beiden Quellregistern durch und speichern Sie das Ergebnis im ersten Quellregister. Hinweis: Im Gegensatz zu anderen mathematischen Operationen |
d0..d7 22s | binop /lit16 vA, vB, #+CCCC d0: add-int/lit16 d1: rsub-int (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 Bits)B: Quellregister (4 Bits)C: Vorzeichenbehaftete int-Konstante (16 Bit) | Führen Sie die angegebene binäre Operation für das angegebene Register (erstes Argument) und den Literalwert (zweites Argument) aus und speichern Sie 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: Vorzeichenbehaftete int-Konstante (8 Bit) | Führen Sie die angegebene binäre Operation für das angegebene Register (erstes Argument) und den Literalwert (zweites Argument) aus und speichern Sie das Ergebnis im Zielregister. Hinweis: Einzelheiten zur Semantik von |
e3..f9 10x | (ungebraucht) | (ungebraucht) | |
fa 45cc | invoke-polymorphic {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH | A: Argumentwortanzahl (4 Bits)B: Methodenreferenzindex (16 Bit)C: Empfänger (4 Bit)D..G: Argumentregister (jeweils 4 Bit)H: Prototyp-Referenzindex (16 Bit) | Rufen Sie die angegebene polymorphe Signaturmethode auf. Das Ergebnis (falls vorhanden) kann mit einer entsprechenden move-result* -Variante als unmittelbar nachfolgende Anweisung gespeichert werden.Der Methodenverweis muss auf eine polymorphe Signaturmethode verweisen, z. B. java.lang.invoke.MethodHandle.invoke oder java.lang.invoke.MethodHandle.invokeExact .Der Empfänger muss ein Objekt sein, das die aufgerufene polymorphe Signaturmethode unterstützt. Die Prototypreferenz beschreibt die bereitgestellten Argumenttypen und den erwarteten Rückgabetyp. Der invoke-polymorphic Bytecode kann bei seiner Ausführung Ausnahmen auslösen. Die Ausnahmen werden in der API-Dokumentation für die aufgerufene polymorphe Signaturmethode beschrieben.In Dex-Dateien ab Version 038 vorhanden. |
fb 4rcc | invoke-polymorphic/range {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH | A: Argumentwortanzahl (8 Bits)B: Methodenreferenzindex (16 Bit)C: Empfänger (16 Bit)H: Prototyp-Referenzindex (16 Bit)N = A + C - 1 | Rufen Sie das angegebene Methodenhandle auf. Weitere Informationen finden Sie in der obigen Beschreibung invoke-polymorphic .In Dex-Dateien ab Version 038 vorhanden. |
fc 35c | invoke-custom {vC, vD, vE, vF, vG}, call_site@BBBB | A: Argumentwortanzahl (4 Bits)B: Referenzindex der Aufrufstelle (16 Bit)C..G: Argumentregister (jeweils 4 Bits) | Löst die angegebene Aufrufseite auf und ruft sie auf. Das Ergebnis des Aufrufs (falls vorhanden) kann mit einer entsprechenden move-result* -Variante als unmittelbar nachfolgende Anweisung gespeichert werden.Diese Anweisung wird in zwei Phasen ausgeführt: Call-Site-Auflösung und Call-Site-Aufruf. Bei der Call-Site-Auflösung wird geprüft, ob der angegebenen Call-Site eine java.lang.invoke.CallSite Instanz zugeordnet ist. Wenn nicht, wird die Bootstrap-Linker-Methode für die angegebene Aufruf-Site mithilfe der in der DEX-Datei vorhandenen Argumente aufgerufen (siehe call_site_item ). Die Bootstrap-Linker-Methode gibt eine java.lang.invoke.CallSite Instanz zurück, die dann mit der angegebenen Aufruf-Site verknüpft wird, wenn keine Zuordnung besteht. Möglicherweise hat ein anderer Thread die Zuordnung bereits zuerst vorgenommen. Wenn dies der Fall ist, wird die Ausführung der Anweisung mit der ersten zugeordneten java.lang.invoke.CallSite Instanz fortgesetzt.Der Aufruf der Aufrufsite 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 (oben beschrieben) ausgeführt, wobei das Methodenhandle und die Argumente für die invoke-custom Anweisung als Argumente für einen exakten Methodenhandle-Aufruf verwendet werden.Von der Bootstrap-Linker-Methode ausgelöste Ausnahmen werden in einen java.lang.BootstrapMethodError eingeschlossen. Ein BootstrapMethodError wird auch ausgelöst, wenn:
038 vorhanden. |
fd 3rc | invoke-custom/range {vCCCC .. vNNNN}, call_site@BBBB | A: Argumentwortanzahl (8 Bits)B: Referenzindex der Aufrufstelle (16 Bit)C: erstes Argumentregister (16 Bit)N = A + C - 1 | Lösen Sie eine Anrufseite auf und rufen Sie sie auf. Weitere Informationen finden Sie oben in der Beschreibung invoke-custom .In Dex-Dateien ab Version 038 vorhanden. |
Fe 21c | const-method-handle vAA, method_handle@BBBB | A: Zielregister (8 Bit)B: Methodenhandle-Index (16 Bit) | Verschieben Sie einen Verweis auf das durch den angegebenen Index angegebene Methodenhandle 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) | Verschieben Sie einen Verweis auf den durch den angegebenen Index angegebenen Methodenprototyp in das angegebene Register. In Dex-Dateien ab Version 039 vorhanden. |
Packed-Switch-Payload-Format
Name | Format | Beschreibung |
---|---|---|
Ident | ushort = 0x0100 | Identifizierung von Pseudo-Opcode |
Größe | ushort | Anzahl der Einträge in der Tabelle |
erster_schlüssel | int | erster (und niedrigster) Schaltfallwert |
Ziele | int[] | Liste der size Verzweigungsziele. Die Ziele beziehen sich auf die Adresse des Switch-Opcodes, nicht auf die Adresse dieser Tabelle. |
Hinweis: Die Gesamtzahl der Codeeinheiten für eine Instanz dieser Tabelle beträgt (size * 2) + 4
.
Sparse-Switch-Payload-Format
Name | Format | Beschreibung |
---|---|---|
ident | ushort = 0x0200 | Identifizierung von Pseudo-Opcode |
Größe | ushort | Anzahl der Einträge in der Tabelle |
Schlüssel | int[] | Liste der size , sortiert von niedrig nach hoch |
Ziele | int[] | Liste der size Verzweigungsziele, die jeweils dem Schlüsselwert am gleichen Index entsprechen. Die Ziele beziehen sich auf die Adresse des Switch-Opcodes, nicht auf die Adresse dieser Tabelle. |
Hinweis: Die Gesamtzahl der Codeeinheiten für eine Instanz dieser Tabelle beträgt (size * 4) + 2
.
Fill-Array-Data-Payload-Format
Name | Format | Beschreibung |
---|---|---|
ident | ushort = 0x0300 | Identifizierung von Pseudo-Opcode |
element_width | ushort | Anzahl der Bytes in jedem Element |
Größe | uint | Anzahl der Elemente in der Tabelle |
Daten | ubyte[] | Datenwerte |
Hinweis: Die Gesamtzahl der Codeeinheiten für eine Instanz dieser Tabelle beträgt (size * element_width + 1) / 2 + 4
.
Einzelheiten zur mathematischen Operation
Hinweis: Gleitkommaoperationen müssen den IEEE 754-Regeln folgen und auf den nächsten Wert runden und einen allmählichen Unterlauf verwenden, sofern nicht anders angegeben.
Opcode | C-Semantik | Anmerkungen |
---|---|---|
neg-int | int32 a; int32 Ergebnis = -a; | Unäres Zweierkomplement. |
nicht-int | int32 a; int32 result = ~a; | Unäres Einserkomplement. |
neg-lang | int64 a; int64 Ergebnis = -a; | Unäres Zweierkomplement. |
nicht lang | int64 a; int64 result = ~a; | Unäres Einserkomplement. |
Neg-Float | float a; float result = -a; | Gleitkomma-Negation. |
neg-double | Doppel a; doppeltes Ergebnis = -a; | Gleitkomma-Negation. |
int-to-long | int32 a; int64 result = (int64) a; | Signieren Sie die Erweiterung von int32 in int64 . |
Int-to-to-to-Float | int32 a; float result = (float) a; | Umwandlung von int32 zum float mit rund-zu-Nearest. Dies verliert Präzision für einige Werte. |
int-to-double | int32 a; Doppelergebnis = (doppelt) a; | Umwandlung von int32 in double . |
lang zu int | int64 a; int32 result = (int32) a; | Kürzung von int64 in int32 . |
lang zu flotten | int64 a; float result = (float) a; | Umwandlung von int64 zum float mit rund-zu-Nearest. Dies verliert Präzision für einige Werte. |
lang zu double | int64 a; Doppelergebnis = (doppelt) a; | Umwandlung von int64 in double , unter Verwendung von rund zu Nearest. Dies verliert Präzision für einige Werte. |
float-to-in | float a; int32 result = (int32) a; | Konvertierung von float in int32 mit Rundzusammenfordern-Null. NaN und -0.0 (negativer Null) konvertieren in die Ganzzahl 0 . Unendlichkeiten und Werte mit zu großer Größe, um dargestellt zu werden, werden je nach Zeichen entweder in 0x7fffffff oder -0x80000000 umgewandelt. |
float-to-long | float a; int64 result = (int64) a; | Konvertierung von float in int64 mit Rundzusammenstellungsnull. Die gleichen Sonderfallregeln wie für float-to-int Ins jedoch jedoch jedoch, dass außerhalb des Bereichs je nach Zeichen entweder in 0x7fffffffffffffff oder -0x80000000000000 oder -0x8000000000000000 konvertiert wird. |
Float-to-Double | float a; Doppelergebnis = (doppelt) a; | Umwandlung von float zu double und genau den Wert erhalten. |
doppelt zu int | Doppel a; int32 result = (int32) a; | Umwandlung von double in int32 mit Rundzahlen-Null. Die gleichen Sonderfallregeln wie für float-to-int hier gelten hier. |
doppelt zu lang | Doppel a; int64 result = (int64) a; | Umwandlung von double in int64 mit Rundzahlen-Null. Die gleichen Sonderfallregeln wie für float-to-long hier gelten. |
doppelt flott | Doppel a; float result = (float) a; | Umwandlung von double zum float mit rund-zu-Nearst. Dies verliert Präzision für einige Werte. |
int-to-byte | int32 a; int32 result = (a << 24) >> 24; | Kürzung von int32 bis int8 , Zeichen, die das Ergebnis erweitert. |
int-to-char | int32 a; int32 result = a & 0xffff; | Kürzung von int32 bis uint16 ohne Vorzeichenverlängerung. |
int-to-Short | int32 a; int32 result = (a << 16) >> 16; | Kürzung von int32 bis int16 , Zeichen, die das Ergebnis erweitert. |
Add-Int | int32 a, b; int32 result = a + b; | Zwei-Komplement-Addition. |
sub-in | int32 a, b; int32 result = a - b; | Zwei-Komplement-Subtraktion. |
rsub-int | int32 a, b; int32 result = b - a; | Zwei-Komplement-Reverse-Subtraktion. |
Mul-in | int32 a, b; int32 result = a * b; | Zwei-Komplement-Multiplikation. |
div-in | int32 a, b; int32 result = a / b; | Zwei-Komplement-Division, abgerundet auf Null abgerundet (dh an Ganzzahl abgeschnitten). Dies wirft ArithmeticException aus, wenn b == 0 . |
rem-in | int32 a, b; INT32 Ergebnis = A % b; | Zwei-Komplement-Rest nach der Division. Das Zeichen des Ergebnisses ist das gleiche wie das von a und ist genauer wie result == a - (a / b) * b . Dies wirft ArithmeticException aus, wenn b == 0 . |
und-in | int32 a, b; int32 result = a & b; | Bitweise und. |
or-in | int32 a, b; int32 result = a | B; | Bitweise oder. |
xor-int | int32 a, b; int32 result = a ^ b; | Bitweise xor. |
Shl-in | int32 a, b; int32 result = a << (B & 0x1f); | Bitweise Verschiebung nach links (mit maskierter Argument). |
Shr-Int | int32 a, b; int32 result = a >> (b & 0x1f); | Bitweise signierte Verschiebung rechts (mit maskiertem Argument). |
ushr-int | uint32 a, b; int32 result = a >> (b & 0x1f); | Bitgewise Unsigned Verschiebung rechts (mit maskiertem Argument). |
Fügen Sie long | int64 a, b; int64 result = a + b; | Zwei-Komplement-Addition. |
sublong | int64 a, b; int64 result = a - b; | Zwei-Komplement-Subtraktion. |
mullong | int64 a, b; int64 result = a * b; | Zwei-Komplement-Multiplikation. |
Div-Long | int64 a, b; int64 result = a / b; | Zwei-Komplement-Division, abgerundet auf Null abgerundet (dh an Ganzzahl abgeschnitten). Dies wirft ArithmeticException aus, wenn b == 0 . |
rem-long | int64 a, b; int64 Ergebnis = A % b; | Zwei-Komplement-Rest nach der Division. Das Zeichen des Ergebnisses ist das gleiche wie das von a und ist genauer wie result == a - (a / b) * b . Dies wirft ArithmeticException aus, wenn b == 0 . |
und lang | int64 a, b; int64 result = a & b; | Bitweise und. |
oder long | int64 a, b; int64 result = a | B; | Bitweise oder. |
xor-long | int64 a, b; int64 result = a ^ b; | Bitweise xor. |
SHL-Long | int64 a; int32 b; int64 result = a << (B & 0x3f); | Bitweise Verschiebung nach links (mit maskierter Argument). |
Shrlong | int64 a; int32 b; int64 result = a >> (b & 0x3f); | Bitweise signierte Verschiebung rechts (mit maskiertem Argument). |
USHR-Long | uint64 a; int32 b; int64 result = a >> (b & 0x3f); | Bitgewise Unsigned Verschiebung rechts (mit maskiertem Argument). |
Add-Float | float a, b; float result = a + b; | Schwebende Punktzusatz. |
Unterfloat | float a, b; float result = a - b; | Schwimmende Punktsubtraktion. |
Mul-Float | float a, b; float result = a * b; | Schwimmende Punktmultiplikation. |
Div-Float | float a, b; float result = a / b; | Schwebende Punktdivision. |
Rem-Float | float a, b; Float -Ergebnis = A % b; | Schwebender Punkt nach der Teilung. Diese Funktion ist anders als IEEE 754 Rest und wird als result == a - roundTowardZero(a / b) * b definiert. |
Addouble | Doppel A, B; Doppelergebnis = a + b; | Schwebende Punktzusatz. |
Subdouble | Doppel A, B; Doppelergebnis = a - b; | Schwimmende Punktsubtraktion. |
Mul-Double | Doppel A, B; doppeltes Ergebnis = a * b; | Schwimmende Punktmultiplikation. |
div-double | Doppel A, B; Doppelergebnis = a / b; | Schwebende Punktdivision. |
Rem-Double | Doppel A, B; Doppelergebnis = A % B; | Schwebender Punkt nach der Teilung. Diese Funktion ist anders als IEEE 754 Rest und wird als result == a - roundTowardZero(a / b) * b definiert. |