Conception générale
- Le modèle de machine et les conventions d'appel sont censés imiter approximativement les architectures réelles courantes et les conventions d'appel de style C :
- La machine est basée sur des registres et la taille des images est fixe lors de la création. Chaque trame se compose d'un nombre particulier de registres (spécifié par la méthode) ainsi que de toutes les données complémentaires nécessaires à l'exécution de la méthode, telles que (mais sans s'y limiter) le compteur du programme et une référence au fichier
.dex
qui contient la méthode. . - Lorsqu'ils sont utilisés pour des valeurs binaires (telles que des entiers et des nombres à virgule flottante), les registres sont considérés comme ayant une largeur de 32 bits. Les paires de registres adjacents sont utilisées pour les valeurs 64 bits. Il n'y a aucune exigence d'alignement pour les paires de registres.
- Lorsqu'ils sont utilisés pour des références d'objets, les registres sont considérés comme suffisamment larges pour contenir exactement une de ces références.
- En termes de représentation au niveau du bit,
(Object) null == (int) 0
. - Les N arguments d’une méthode atterrissent dans l’ordre dans les N derniers registres de la trame d’invocation de la méthode. Les arguments larges consomment deux registres. Les méthodes d'instance reçoivent une référence
this
comme premier argument.
- La machine est basée sur des registres et la taille des images est fixe lors de la création. Chaque trame se compose d'un nombre particulier de registres (spécifié par la méthode) ainsi que de toutes les données complémentaires nécessaires à l'exécution de la méthode, telles que (mais sans s'y limiter) le compteur du programme et une référence au fichier
- L'unité de stockage dans le flux d'instructions est une quantité non signée de 16 bits. Certains bits de certaines instructions sont ignorés/doivent être nuls.
- Les instructions ne sont pas limitées gratuitement à un type particulier. Par exemple, les instructions qui déplacent des valeurs de registre 32 bits sans interprétation n'ont pas besoin de spécifier si elles déplacent des entiers ou des flottants.
- Il existe des pools de constantes énumérés et indexés séparément pour les références aux chaînes, aux types, aux champs et aux méthodes.
- Les données littérales au niveau du bit sont représentées en ligne dans le flux d'instructions.
- Parce que, dans la pratique, il est rare qu'une méthode ait besoin de plus de 16 registres, et parce qu'il est raisonnablement courant d'avoir besoin de plus de huit registres, de nombreuses instructions se limitent à adresser uniquement les 16 premiers registres. Lorsque cela est raisonnablement possible, les instructions autorisent des références jusqu'aux 256 premiers registres. De plus, certaines instructions ont des variantes qui permettent un nombre de registres beaucoup plus important, y compris une paire d'instructions
move
fourre-tout qui peuvent adresser des registres dans la plagev0
–v65535
. Dans les cas où une variante d'instruction n'est pas disponible pour adresser un registre souhaité, il est prévu que le contenu du registre soit déplacé du registre d'origine vers un registre bas (avant l'opération) et/ou déplacé d'un registre de résultats bas vers un registre haut. s'inscrire (après l'opération). - Il existe plusieurs « pseudo-instructions » utilisées pour contenir des charges utiles de données de longueur variable, auxquelles font référence des instructions régulières (par exemple,
fill-array-data
). De telles instructions ne doivent jamais être rencontrées au cours du flux normal d’exécution. De plus, les instructions doivent être situées sur des décalages de bytecode pairs (c'est-à-dire alignés sur 4 octets). Afin de répondre à cette exigence, les outils de génération dex doivent émettre une instructionnop
supplémentaire comme espaceur si une telle instruction ne serait autrement pas alignée. Enfin, bien que cela ne soit pas obligatoire, on s'attend à ce que la plupart des outils choisissent d'émettre ces instructions à la fin des méthodes, car sinon il serait probable que des instructions supplémentaires seraient nécessaires pour les contourner. - Lorsqu'elles sont installées sur un système en cours d'exécution, certaines instructions peuvent être modifiées, en changeant leur format, en guise d'optimisation des liaisons statiques au moment de l'installation. Cela permet une exécution plus rapide une fois que le lien est connu. Voir le document sur les formats d'instructions associés pour les variantes suggérées. Le mot « suggéré » est utilisé à bon escient ; il n’est pas obligatoire de les mettre en œuvre.
- Syntaxe humaine et mnémoniques :
- Ordre de destination puis source des arguments.
- Certains opcodes ont un suffixe de nom sans ambiguïté pour indiquer le(s) type(s) sur lesquels ils opèrent :
- Les opcodes 32 bits généraux de type ne sont pas marqués.
- Les opcodes 64 bits généraux de type sont suffixés par
-wide
. - Les opcodes spécifiques au type sont suffixés par leur type (ou une abréviation simple), l'un des suivants :
-boolean
-byte
-char
-short
-int
-long
-float
-double
-object
-string
-class
-void
.
- Certains opcodes ont un suffixe sans ambiguïté pour distinguer des opérations par ailleurs identiques qui ont des dispositions ou des options d'instructions différentes. Ces suffixes sont séparés des noms principaux par une barre oblique ("
/
") et existent principalement pour créer un mappage un-à-un avec des constantes statiques dans le code qui génère et interprète les exécutables (c'est-à-dire pour réduire l'ambiguïté pour les humains). - Dans les descriptions ici, la largeur d'une valeur (indiquant, par exemple, la plage d'une constante ou le nombre de registres éventuellement adressés) est accentuée par l'utilisation d'un caractère pour quatre bits de largeur.
- Par exemple, dans l'instruction "
move-wide/from16 vAA, vBBBB
" :- "
move
" est l'opcode de base, indiquant l'opération de base (déplacer la valeur d'un registre). - "
wide
" est le suffixe du nom, indiquant qu'il fonctionne sur des données larges (64 bits). - "
from16
" est le suffixe de l'opcode, indiquant une variante qui a une référence de registre de 16 bits comme source. - "
vAA
" est le registre de destination (impliqué par l'opération ; encore une fois, la règle est que les arguments de destination viennent toujours en premier), qui doit être compris entrev0
–v255
. - "
vBBBB
" est le registre source, qui doit être compris entrev0
–v65535
.
- "
- Consultez le document sur les formats d'instructions pour plus de détails sur les différents formats d'instructions (répertoriés sous « Op & Format ») ainsi que des détails sur la syntaxe de l'opcode.
- Consultez le document sur le format de fichier
.dex
pour plus de détails sur la place du bytecode dans l'ensemble.
Résumé de l'ensemble de bytecodes
Opération et format | Mnémonique / Syntaxe | Arguments | Description |
---|---|---|---|
00 10x | non | Cycles des déchets. Remarque : les pseudo-instructions portant des données sont étiquetées avec cet opcode, auquel cas l'octet de poids fort de l'unité d'opcode indique la nature des données. Voir « | |
01 12x | déplacer vA, vB | A: registre de destination (4 bits)B: registre source (4 bits) | Déplacez le contenu d'un registre non-objet vers un autre. |
02 22x | déplacer/de16 vAA, vBBBB | A: registre de destination (8 bits)B: registre source (16 bits) | Déplacez le contenu d'un registre non-objet vers un autre. |
03 32x | bouger/16 vAAAA, vBBBB | A: registre de destination (16 bits)B: registre source (16 bits) | Déplacez le contenu d'un registre non-objet vers un autre. |
04 12x | vA, vB à l'échelle du mouvement | A: paire de registres de destination (4 bits)B: paire de registres source (4 bits) | Déplacez le contenu d’une paire de registres vers une autre. Remarque : il est légal de passer de |
05 22x | à l'échelle du mouvement/à partir de 16 vAA, vBBBB | A: paire de registres de destination (8 bits)B: paire de registres source (16 bits) | Déplacez le contenu d’une paire de registres vers une autre. Remarque : les considérations d'implémentation sont les mêmes que celles |
06 32x | mouvement large/16 vAAAA, vBBBB | A: paire de registres de destination (16 bits)B: paire de registres source (16 bits) | Déplacez le contenu d’une paire de registres vers une autre. Remarque : les considérations d'implémentation sont les mêmes que celles |
07 12x | déplacer l'objet vA, vB | A: registre de destination (4 bits)B: registre source (4 bits) | Déplacez le contenu d’un registre porteur d’objet vers un autre. |
08 22x | déplacer-objet/from16 vAA, vBBBB | A: registre de destination (8 bits)B: registre source (16 bits) | Déplacez le contenu d’un registre porteur d’objet vers un autre. |
09 32x | déplacer-objet/16 vAAAA, vBBBB | A: registre de destination (16 bits)B: registre source (16 bits) | Déplacez le contenu d’un registre porteur d’objet vers un autre. |
0a 11x | résultat du déplacement vAA | A: registre de destination (8 bits) | Déplacez le résultat non-objet d'un seul mot du invoke- kind le plus récent dans le registre indiqué. Cela doit être fait comme l'instruction immédiatement après un invoke- kind dont le résultat (un seul mot, non-objet) ne doit pas être ignoré ; ailleurs, c'est invalide. |
0b11x | vAA à l'échelle du résultat du déplacement | A: paire de registres de destination (8 bits) | Déplacez le résultat du double mot du invoke- kind le plus récent dans la paire de registres indiquée. Cela doit être fait comme l'instruction immédiatement après un invoke- kind dont le résultat (double mot) ne doit pas être ignoré ; ailleurs, c'est invalide. |
0c 11x | objet de résultat de déplacement vAA | A: registre de destination (8 bits) | Déplacez le résultat de l'objet du invoke- kind le plus récent dans le registre indiqué. Cela doit être fait comme instruction immédiatement après un invoke- kind ou filled-new-array dont le résultat (objet) ne doit pas être ignoré ; ailleurs, c'est invalide. |
0j 11x | vAA d'exception de déplacement | A: registre de destination (8 bits) | Enregistrez une exception qui vient d'être interceptée dans le registre donné. Il doit s'agir de la première instruction de tout gestionnaire d'exceptions dont l'exception interceptée ne doit pas être ignorée, et cette instruction ne doit apparaître que comme première instruction d'un gestionnaire d'exceptions ; ailleurs, c'est invalide. |
0e 10x | retour nul | Retour d'une méthode void . | |
0f 11x | retourner vAA | A: registre de valeur de retour (8 bits) | Retour d’une méthode de retour de valeur non-objet de simple largeur (32 bits). |
10 11x | vAA à l'échelle du retour | A: paire de registres de valeur de retour (8 bits) | Retour d’une méthode de retour de valeur double largeur (64 bits). |
11 11x | objet de retour vAA | A: registre de valeur de retour (8 bits) | Retour d'une méthode de retour d'objet. |
12 11n | const/4 vA, #+B | A: registre de destination (4 bits)B: signé entier (4 bits) | Déplacez la valeur littérale donnée (signe étendu à 32 bits) dans le registre spécifié. |
13 21s | const/16 vAA, #+BBBB | A: registre de destination (8 bits)B: signé entier (16 bits) | Déplacez la valeur littérale donnée (signe étendu à 32 bits) dans le registre spécifié. |
14 31i | const vAA, #+BBBBBBBB | A: registre de destination (8 bits)B: constante arbitraire de 32 bits | Déplacez la valeur littérale donnée dans le registre spécifié. |
15 21h | const/high16 vAA, #+BBBB0000 | A: registre de destination (8 bits)B: signé entier (16 bits) | Déplacez la valeur littérale donnée (zéro à droite étendue à 32 bits) dans le registre spécifié. |
16 21s | const-wide/16 vAA, #+BBBB | A: registre de destination (8 bits)B: signé entier (16 bits) | Déplacez la valeur littérale donnée (signe étendu à 64 bits) dans la paire de registres spécifiée. |
17 31i | const-wide/32 vAA, #+BBBBBBBB | A: registre de destination (8 bits)B: signé entier (32 bits) | Déplacez la valeur littérale donnée (signe étendu à 64 bits) dans la paire de registres spécifiée. |
18 51l | vAA à l'échelle constante, #+BBBBBBBBBBBBBBBB | A: registre de destination (8 bits)B: constante arbitraire de double largeur (64 bits) | Déplacez la valeur littérale donnée dans la paire de registres spécifiée. |
19 21h | const-wide/high16 vAA, #+BBBB000000000000 | A: registre de destination (8 bits)B: signé entier (16 bits) | Déplacez la valeur littérale donnée (zéro droit étendu à 64 bits) dans la paire de registres spécifiée. |
1a 21c | const-string vAA, string@BBBB | A: registre de destination (8 bits)B: index de chaîne | Déplace une référence à la chaîne spécifiée par l'index donné dans le registre spécifié. |
1b 31c | const-string/jumbo vAA, chaîne@BBBBBBBB | A: registre de destination (8 bits)B: index de chaîne | Déplace une référence à la chaîne spécifiée par l'index donné dans le registre spécifié. |
1c 21c | vAA de classe const, tapez @BBBB | A: registre de destination (8 bits)B: indice de type | Déplace une référence à la classe spécifiée par l'index donné dans le registre spécifié. Dans le cas où le type indiqué est primitif, cela stockera une référence à la classe dégénérée du type primitif. |
1j 11x | surveiller-entrer vAA | A: registre de référence (8 bits) | Acquérir le moniteur pour l’objet indiqué. |
1e 11x | vAA de sortie de surveillance | A: registre de référence (8 bits) | Relâchez le moniteur pour l'objet indiqué. Remarque : Si cette instruction doit lever une exception, elle doit le faire comme si le PC avait déjà dépassé l'instruction. Il peut être utile de considérer cela comme l'instruction qui s'exécute avec succès (dans un sens) et l'exception levée après l'instruction mais avant que la suivante ait une chance de s'exécuter. Cette définition permet à une méthode d'utiliser un bloc fourre-tout de nettoyage de moniteur (par exemple, |
1f 21c | check-cast vAA, tapez@BBBB | A: registre de référence (8 bits)B: indice de type (16 bits) | Lancez une ClassCastException si la référence dans le registre donné ne peut pas être convertie en type indiqué. Remarque : Puisque |
20 22c | instance de vA, vB, type@CCCC | A: registre de destination (4 bits)B: registre de référence (4 bits)C: indice de type (16 bits) | Stocker dans le registre de destination donné 1 si la référence indiquée est une instance du type donné, ou 0 sinon. Remarque : Puisque |
21 12x | longueur du tableau vA, vB | A: registre de destination (4 bits)B: registre de référence du tableau (4 bits) | Stocker dans le registre de destination donné la longueur du tableau indiqué, en entrées |
22 21c | vAA de nouvelle instance, tapez@BBBB | A: registre de destination (8 bits)B: indice de type | Construisez une nouvelle instance du type indiqué, en stockant une référence à celle-ci dans la destination. Le type doit faire référence à une classe non-tableau. |
23 22c | nouveau tableau vA, vB, type@CCCC | A: registre de destination (4 bits)B: registre des taillesC: indice de type | Construisez un nouveau tableau du type et de la taille indiqués. Le type doit être un type tableau. |
24 35c | nouveau tableau rempli {vC, vD, vE, vF, vG}, type@BBBB | A: taille du tableau et nombre de mots d’argument (4 bits)B: indice de type (16 bits)C..G: registres d'arguments (4 bits chacun) | Construisez un tableau du type et de la taille donnés, en le remplissant avec le contenu fourni. Le type doit être un type tableau. Le contenu du tableau doit être constitué d'un seul mot (c'est-à-dire aucun tableau de long ou double , mais les types référence sont acceptables). L'instance construite est stockée en tant que "résultat" de la même manière que les instructions d'invocation de méthode stockent leurs résultats, de sorte que l'instance construite doit être déplacée vers un registre avec une instruction move-result-object immédiatement suivante (si elle doit être utilisée ). |
25 3rc | rempli-nouveau-tableau/plage {vCCCC .. vNNNN}, tapez @BBBB | A: taille du tableau et nombre de mots d’argument (8 bits)B: indice de type (16 bits)C: registre du premier argument (16 bits)N = A + C - 1 | Construisez un tableau du type et de la taille donnés, en le remplissant avec le contenu fourni. Les clarifications et restrictions sont les mêmes que filled-new-array , décrit ci-dessus. |
26 31t | fill-array-data vAA, +BBBBBBBB (avec des données supplémentaires comme spécifié ci-dessous dans " fill-array-data-payload Format") | A: référence du tableau (8 bits)B: décalage de "branche" signé vers la pseudo-instruction de données de table (32 bits) | Remplissez le tableau donné avec les données indiquées. La référence doit être à un tableau de primitives, et la table de données doit correspondre à son type et ne doit pas contenir plus d'éléments que ne peut contenir le tableau. Autrement dit, le tableau peut être plus grand que la table, et si tel est le cas, seuls les éléments initiaux du tableau sont définis, laissant le reste seul. |
27 11x | lancer vAA | A: registre porteur d'exceptions (8 bits) | Lancez l'exception indiquée. |
28 10t | aller à +AA | A: décalage de branche signé (8 bits) | Passez sans condition à l’instruction indiquée. Remarque : Le décalage de branche ne doit pas être |
29 20t | aller à/16 +AAAA | A: décalage de branche signé (16 bits) | Passez sans condition à l’instruction indiquée. Remarque : Le décalage de branche ne doit pas être |
2a 30t | aller à/32 +AAAAAAAA | A: décalage de branche signé (32 bits) | Passez sans condition à l’instruction indiquée. |
2b 31t | packed-switch vAA, +BBBBBBBB (avec des données supplémentaires comme spécifié ci-dessous dans " packed-switch-payload Format") | A: inscrivez-vous pour testerB: décalage de "branche" signé vers la pseudo-instruction de données de table (32 bits) | Passez à une nouvelle instruction basée sur la valeur dans le registre donné, en utilisant un tableau de décalages correspondant à chaque valeur dans une plage intégrale particulière, ou passez à l'instruction suivante s'il n'y a pas de correspondance. |
2c 31t | sparse-switch vAA, +BBBBBBBB (avec des données supplémentaires comme spécifié ci-dessous dans " sparse-switch-payload Format") | A: inscrivez-vous pour testerB: décalage de "branche" signé vers la pseudo-instruction de données de table (32 bits) | Passez à une nouvelle instruction basée sur la valeur dans le registre donné, en utilisant un tableau ordonné de paires valeur-décalage, ou passez à l'instruction suivante s'il n'y a pas de correspondance. |
2j..31 23x | cmp type vAA, vBB, vCC 2d : cmpl-float (biais lt) 2e : cmpg-float (biais gt) 2f : cmpl-double (biais lt) 30 : cmpg-double (biais gt) 31 : cmp-long | A: registre de destination (8 bits)B: premier registre ou paire sourceC: deuxième registre ou paire source | Effectuez la comparaison à virgule flottante ou long indiquée, en définissant a sur 0 si b == c , 1 si b > c ou -1 si b < c . Le "biais" répertorié pour les opérations en virgule flottante indique comment les comparaisons NaN sont traitées : les instructions "gt biais" renvoient 1 pour les comparaisons NaN et les instructions "lt biais" renvoient -1 . Par exemple, pour vérifier si la virgule flottante |
32..37 22t | si- tester vA, vB, +CCCC 32 : si-eq 33 : si-ne 34 : si-lt 35 : si-ge 36 : si-gt 37 : si-le | A: premier registre à tester (4 bits)B: deuxième registre à tester (4 bits)C: décalage de branche signé (16 bits) | Branchez-vous vers la destination donnée si les valeurs des deux registres données se comparent comme spécifié. Remarque : Le décalage de branche ne doit pas être |
38..3j 21t | si- test z vAA, +BBBB 38 : si-eqz 39 : si-nez 3a : si-ltz 3b : si-gez 3c : si-gtz 3d : si-lez | A: s'inscrire pour tester (8 bits)B: décalage de branche signé (16 bits) | Branchez-vous vers la destination donnée si la valeur du registre donné est comparable à 0 comme spécifié. Remarque : Le décalage de branche ne doit pas être |
3e..43 10x | (inutilisé) | (inutilisé) | |
44..51 23x | arrayop vAA, vBB, vCC 44 : âge 45 : à l’échelle de la population 46 : objet-aget 47 : aget-booléen 48 : octet-octet 49 : aget-char 4a : âge court 4b : aput 4c : à l'échelle de l'aput 4d : aput-objet 4e : aput-booléen 4f : octet d'aput 50 : aput-char 51 : aput-court | A: registre ou paire de valeurs ; peut être la source ou la destination (8 bits)B: registre de tableau (8 bits)C: registre d'index (8 bits) | Effectuez l'opération de tableau identifié à l'index identifié du tableau donné, en chargeant ou en stockant dans le registre de valeurs. |
52..5f 22c | j'instanceop vA, vB, field@CCCC 52 : j'obtiens 53 : iget-wide 54 : iget-objet 55 : iget-booléen 56 : iget-octet 57 : iget-char 58 : iget-short 59 : entrée 5a : à l'échelle de l'iput 5b : objet iput 5c : iput-booléen 5d : octet d'entrée 5e : iput-char 5f : iput-court | A: registre ou paire de valeurs ; peut être la source ou la destination (4 bits)B: registre d'objets (4 bits)C: index de référence du champ d'instance (16 bits) | Effectuez l'opération de champ d'instance d'objet identifié avec le champ identifié, en le chargeant ou en le stockant dans le registre de valeurs. Remarque : Ces opcodes sont des candidats raisonnables pour la liaison statique, modifiant l'argument du champ pour en faire un décalage plus direct. |
60..6j 21c | s staticop vAA, champ@BBBB 60 : obtenir 61 : s'étendre à l'échelle 62 : sget-objet 63 : sget-booléen 64 : sget-octet 65 : sget-char 66 : soyez court 67 : crachat 68 : à l'échelle de l'entrée 69 : objet-sput 6a : sput-booléen 6b : octet de sortie 6c : sput-char 6d : court-circuit | A: registre ou paire de valeurs ; peut être la source ou la destination (8 bits)B: index de référence de champ statique (16 bits) | Effectuez l'opération de champ statique d'objet identifié avec le champ statique identifié, en le chargeant ou en le stockant dans le registre de valeurs. Remarque : Ces opcodes sont des candidats raisonnables pour la liaison statique, modifiant l'argument du champ pour en faire un décalage plus direct. |
6e..72 35c | invoquer- genre {vC, vD, vE, vF, vG}, meth@BBBB 6e : invoquer-virtuel 6f : invoquer-super 70 : invoquer-direct 71 : invoquer-statique 72 : interface d'invocation | A: nombre de mots d’argument (4 bits)B: index de référence de la méthode (16 bits)C..G: registres d'arguments (4 bits chacun) | Appelez la méthode indiquée. Le résultat (le cas échéant) peut être stocké avec une variante move-result* appropriée comme instruction immédiatement suivante. Lorsque le Dans les fichiers Dex version Remarque : Ces opcodes sont des candidats raisonnables pour la liaison statique, modifiant l'argument de la méthode pour en faire un décalage plus direct (ou une paire de ceux-ci). |
73 10x | (inutilisé) | (inutilisé) | |
74..78 3rc | invoquer- genre /range {vCCCC .. vNNNN}, meth@BBBB 74 : invoquer-virtuel/plage 75 : invocation-super/range 76 : invocation-direct/range 77 : invocation-statique/plage 78 : invoquer l'interface/la plage | A: nombre de mots d’argument (8 bits)B: index de référence de la méthode (16 bits)C: registre du premier argument (16 bits)N = A + C - 1 | Appelez la méthode indiquée. Voir la première description invoke- kind ci-dessus pour plus de détails, de mises en garde et de suggestions. |
79..7a 10x | (inutilisé) | (inutilisé) | |
7b..8f 12x | unop vA, vB 7b : nég-int 7c : non-int 7d : négatif-long 7e : pas longtemps 7f : flotteur négatif 80 : négatif-double 81 : int-à-long 82 : int-à-flotter 83 : entier vers double 84 : long à int 85 : long à flotter 86 : long à doubler 87 : flottant vers int 88 : flotter trop longtemps 89 : flotter pour doubler 8a : double vers entier 8b : double à long 8c : doubler pour flotter 8d : entier vers octet 8e : int-to-char 8f : int-à-short | A: registre ou paire de destination (4 bits)B: registre source ou paire (4 bits) | Effectuez l'opération unaire identifiée sur le registre source, en stockant le résultat dans le registre de destination. |
90..af 23x | binop vAA, vBB, vCC 90 : complément 91 : sous-entier 92 : mul-int 93 : div-int 94 : rem-int 95 : et-int 96 : ou-int 97 : xor-int 98 : shl-int 99 : shr-int 9a : ushr-int 9b : ajout de longueur 9c : sous-long 9d : mul-long 9e : div-long 9f : rem-long a0 : et-long a1 : ou-long a2 : xor-long a3 : shl-long a4 : shr-long a5 : ushr-long a6 : ajouter un flotteur a7 : sous-flotteur a8 : mul-flotteur a9 : div-float aa : rem-float ab : ajouter-double ac : sous-double annonce : mul-double ae : div-double af : rem-double | A: registre ou paire de destination (8 bits)B: premier registre source ou paire (8 bits)C: deuxième registre source ou paire (8 bits) | Effectuez l'opération binaire identifiée sur les deux registres source, en stockant le résultat dans le registre de destination. Remarque : Contrairement aux autres opérations mathématiques |
b0..cf 12x | binop /2addr vA, vB b0 : complément/2addr b1 : sous-entier/2adresse b2 : mul-int/2addr b3 : div-int/2addr b4 : rem-int/2addr b5 : et-int/2addr b6 : ou-int/2adresse b7 : xor-int/2addr b8 : shl-int/2addr b9 : shr-int/2addr ba : ushr-int/2addr bb : ajouter-long/2addr bc : sous-long/2addr BD : mul-long/2addr être : div-long/2addr bf : rem-long/2addr c0 : et-long/2addr c1 : ou-long/2adresse c2 : xor-long/2addr c3 : shl-long/2addr c4 : shr-long/2addr c5 : ushr-long/2addr c6 : add-float/2addr c7 : sous-flotteur/2addr c8 : mul-float/2addr c9 : div-float/2addr ca : rem-float/2addr cb : add-double/2addr cc : sous-double/2adresse cd : mul-double/2 adresses ce : div-double/2addr cf : rem-double/2addr | A: destination et premier registre ou paire source (4 bits)B: deuxième registre source ou paire (4 bits) | Effectuez l'opération binaire identifiée sur les deux registres source, en stockant le résultat dans le premier registre source. Remarque : Contrairement aux autres opérations mathématiques |
d0..d7 22s | binop /lit16 vA, vB, #+CCCC d0 : complément/lit16 d1 : rsub-int (soustraction inverse) d2 : mul-int/lit16 d3 : div-int/lit16 d4 : rem-int/lit16 d5 : et-int/lit16 d6 : ou-int/lit16 d7 : xor-int/lit16 | A: registre de destination (4 bits)B: registre source (4 bits)C: constante entière signée (16 bits) | Effectuez l'opération binaire indiquée sur le registre indiqué (premier argument) et la valeur littérale (deuxième argument), en stockant le résultat dans le registre de destination. Remarque : |
d8..e2 22b | binop /lit8 vAA, vBB, #+CC d8 : complément/lit8 d9 : rsub-int/lit8 par: mul-int/lit8 base de données : div-int/lit8 cc : rem-int/lit8 jj : et-int/lit8 de: ou-int/lit8 df : xor-int/lit8 e0 : shl-int/lit8 e1 : shr-int/lit8 e2 : ushr-int/lit8 | A: registre de destination (8 bits)B: registre source (8 bits)C: constante entière signée (8 bits) | Effectuez l'opération binaire indiquée sur le registre indiqué (premier argument) et la valeur littérale (deuxième argument), en stockant le résultat dans le registre de destination. Remarque : voir ci-dessous pour plus de détails sur la sémantique de |
e3..f9 10x | (inutilisé) | (inutilisé) | |
fa 45cc | invoquer-polymorphique {vC, vD, vE, vF, vG}, meth@BBBB, proto@HHHH | A: nombre de mots d’argument (4 bits)B: index de référence de la méthode (16 bits)C: récepteur (4 bits)D..G: registres d'arguments (4 bits chacun)H: index de référence du prototype (16 bits) | Invoquez la méthode polymorphe de signature indiquée. Le résultat (le cas échéant) peut être stocké avec une variante move-result* appropriée comme instruction immédiatement suivante.La référence de méthode doit renvoyer à une méthode polymorphe de signature, telle que java.lang.invoke.MethodHandle.invoke ou java.lang.invoke.MethodHandle.invokeExact .Le récepteur doit être un objet prenant en charge la méthode polymorphe de signature invoquée. La référence du prototype décrit les types d'arguments fournis et le type de retour attendu. Le bytecode invoke-polymorphic peut déclencher des exceptions lors de son exécution. Les exceptions sont décrites dans la documentation de l'API pour la méthode polymorphe de signature invoquée.Présent dans les fichiers Dex à partir de la version 038 . |
fb4rcc | invoquer-polymorphique/range {vCCCC .. vNNNN}, meth@BBBB, proto@HHHH | A: nombre de mots d’argument (8 bits)B: index de référence de la méthode (16 bits)C: récepteur (16 bits)H: index de référence du prototype (16 bits)N = A + C - 1 | Appelez le handle de méthode indiqué. Voir la description invoke-polymorphic ci-dessus pour plus de détails.Présent dans les fichiers Dex à partir de la version 038 . |
fc 35c | invoquer-personnalisé {vC, vD, vE, vF, vG}, call_site@BBBB | A: nombre de mots d’argument (4 bits)B: index de référence du site d'appel (16 bits)C..G: registres d'arguments (4 bits chacun) | Résout et appelle le site d'appel indiqué. Le résultat de l'invocation (le cas échéant) peut être stocké avec une variante move-result* appropriée comme instruction immédiatement suivante.Cette instruction s'exécute en deux phases : résolution du site d'appel et invocation du site d'appel. La résolution du site d'appel vérifie si le site d'appel indiqué est associé à une instance java.lang.invoke.CallSite . Sinon, la méthode de l'éditeur de liens bootstrap pour le site d'appel indiqué est invoquée à l'aide des arguments présents dans le fichier DEX (voir call_site_item ). La méthode de l'éditeur de liens bootstrap renvoie une instance java.lang.invoke.CallSite qui sera ensuite associée au site d'appel indiqué si aucune association n'existe. Un autre thread peut avoir déjà effectué l'association en premier, et si c'est le cas, l'exécution de l'instruction continue avec la première instance java.lang.invoke.CallSite associée.L'appel du site d'appel est effectué sur la cible java.lang.invoke.MethodHandle de l'instance java.lang.invoke.CallSite résolue. La cible est invoquée comme si elle exécutait invoke-polymorphic (décrit ci-dessus) en utilisant le handle de méthode et les arguments de l'instruction invoke-custom comme arguments d'un appel de handle de méthode exact.Les exceptions déclenchées par la méthode de l'éditeur de liens bootstrap sont enveloppées dans un java.lang.BootstrapMethodError . Une BootstrapMethodError est également levée si :
038 . |
fd3rc | invoquer-custom/range {vCCCC .. vNNNN}, call_site@BBBB | A: nombre de mots d’argument (8 bits)B: index de référence du site d'appel (16 bits)C: registre du premier argument (16 bits)N = A + C - 1 | Résolvez et invoquez un site d’appel. Voir la description invoke-custom ci-dessus pour plus de détails.Présent dans les fichiers Dex à partir de la version 038 . |
fe 21c | const-method-handle vAA, méthode_handle@BBBB | A: registre de destination (8 bits)B: index du handle de méthode (16 bits) | Déplacez une référence au handle de méthode spécifié par l’index donné dans le registre spécifié. Présent dans les fichiers Dex à partir de la version 039 . |
ff 21c | vAA de type méthode const, proto@BBBB | A: registre de destination (8 bits)B: référence du prototype de méthode (16 bits) | Déplacez une référence au prototype de méthode spécifié par l'index donné dans le registre spécifié. Présent dans les fichiers Dex à partir de la version 039 . |
format de charge utile de commutateur emballé
Nom | Format | Description |
---|---|---|
identifier | ushort = 0x0100 | identifier le pseudo-opcode |
taille | ushort | nombre d'entrées dans le tableau |
première_clé | int | première (et la plus basse) valeur du cas de commutation |
cibles | int[] | liste des cibles de branche relative size . Les cibles sont relatives à l'adresse de l'opcode du commutateur, pas à celle de cette table. |
Remarque : Le nombre total d'unités de code pour une instance de cette table est (size * 2) + 4
.
format de charge utile de commutateur clairsemé
Nom | Format | Description |
---|---|---|
identifier | ushort = 0x0200 | identifier le pseudo-opcode |
taille | ushort | nombre d'entrées dans le tableau |
clés | int[] | liste des valeurs clés size , triées de bas en haut |
cibles | int[] | liste de cibles de branche relative size , chacune correspondant à la valeur clé au même index. Les cibles sont relatives à l'adresse de l'opcode du commutateur, pas à celle de cette table. |
Remarque : Le nombre total d'unités de code pour une instance de cette table est (size * 4) + 2
.
format de charge utile de données de tableau de remplissage
Nom | Format | Description |
---|---|---|
identifier | ushort = 0x0300 | identifier le pseudo-opcode |
largeur_élément | ushort | nombre d'octets dans chaque élément |
taille | uint | nombre d'éléments dans le tableau |
données | ubyte[] | valeurs des données |
Remarque : Le nombre total d'unités de code pour une instance de cette table est (size * element_width + 1) / 2 + 4
.
Détails de l'opération mathématique
Remarque : Les opérations en virgule flottante doivent suivre les règles IEEE 754, en utilisant l'arrondi au plus proche et le dépassement progressif, sauf indication contraire.
Opcode | Sémantique C | Remarques |
---|---|---|
négatif-int | int32a; résultat int32 = -a ; | Complément unaire à deux. |
pas-int | int32a; résultat int32 = ~a; | Complément unaire. |
négatif-long | int64a; résultat int64 = -a ; | Complément unaire à deux. |
pas longtemps | int64a; résultat int64 = ~a; | Complément unaire. |
flotteur négatif | flotter un; résultat flottant = -a; | Négation en virgule flottante. |
négatif-double | Double A; résultat double = -a ; | Négation en virgule flottante. |
int-à-long | int32a; résultat int64 = (int64) a; | Extension de signe de int32 dans int64 . |
entre-boue | INT32 A; float result = (float) a; | Conversion de int32 en float , en utilisant le rond à l'agitation. Cela perd la précision de certaines valeurs. |
intrus | INT32 A; Double résultat = (double) a; | Conversion de int32 en double . |
long-à-int | int64 a; INT32 Result = (int32) a; | Troncature de int64 dans int32 . |
de long à éloigner | int64 a; float result = (float) a; | Conversion de int64 en float , en utilisant le rond à l'agitation. Cela perd la précision de certaines valeurs. |
de longue date | int64 a; Double résultat = (double) a; | Conversion de int64 pour double , en utilisant le rond à l'agitation. Cela perd la précision de certaines valeurs. |
float-to-int | flotter a; INT32 Result = (int32) a; | Conversion de float en int32 , en utilisant Round-Toward-Zero. NaN et -0.0 (zéro négatif) convertissent en entier 0 . Les infinités et les valeurs avec une grande ampleur pour être représentées sont représentées par 0x7fffffff ou -0x80000000 selon le panneau. |
flotter | flotter a; INT64 Result = (Int64) a; | Conversion du float en int64 , en utilisant le rond-toward-zéro. Les mêmes règles de cas spéciales que pour float-to-int s'appliquent ici, sauf que les valeurs hors plage sont converties en 0x7fffffffffffffff ou -0x8000000000000000 en fonction du panneau. |
flotteur | flotter a; Double résultat = (double) a; | Conversion du float en double , préservant exactement la valeur. |
double-à-int | Double A; INT32 Result = (int32) a; | Conversion de double en int32 , en utilisant le rond-toward-zéro. Les mêmes règles de cas spéciales que pour float-to-int s'appliquent ici. |
double à long | Double A; INT64 Result = (Int64) a; | Conversion du double en int64 , en utilisant le rond-toward-zéro. Les mêmes règles de cas spéciales que pour float-to-long s'appliquent ici. |
double à flotte | Double A; float result = (float) a; | Conversion du double en float , en utilisant le rond à l'agrément. Cela perd la précision de certaines valeurs. |
entre-octet | INT32 A; INT32 Result = (A << 24) >> 24; | Troncature de int32 à int8 , signe étendant le résultat. |
intra-char | INT32 A; Résultat INT32 = A & 0XFFFF; | Troncature de int32 à uint16 , sans extension de signe. |
intrans | INT32 A; INT32 Result = (A << 16) >> 16; | Troncature de int32 à int16 , signe étendant le résultat. |
complément | INT32 A, B; Résultat INT32 = A + B; | Ajout de complément à deux. |
sous-intrigue | INT32 A, B; Résultat int32 = a - b; | Soustraction de deux compléments. |
rsub-int | INT32 A, B; Résultat INT32 = b - a; | Substraction inverse du complément à deux. |
Mul-Int | INT32 A, B; Résultat INT32 = a * b; | Multiplication des deux compléments. |
div-int | INT32 A, B; Résultat INT32 = A / B; | Division des deux compléments, arrondi vers zéro (c'est-à-dire tronqué à entier). Cela jette ArithmeticException si b == 0 . |
rem-int | INT32 A, B; Résultat INT32 = un% b; | Twos-complément reste après la division. Le signe du résultat est le même que celui de a , et il est plus précisément défini comme result == a - (a / b) * b . Cela jette ArithmeticException si b == 0 . |
et dans | INT32 A, B; Résultat INT32 = A&B; | Bitwise et. |
ou-int | INT32 A, B; Résultat INT32 = A | b; | Bitwise ou. |
xor-int | INT32 A, B; Résultat int32 = a ^ b; | Xor bitwise. |
shl-int | INT32 A, B; INT32 Result = A << (B & 0x1f); | Bitwise Shift à gauche (avec argument masqué). |
shr-int | INT32 A, B; INT32 Result = A >> (B & 0x1f); | Bitwise Signed Shift Right (avec un argument masqué). |
ushr-int | uint32 a, b; INT32 Result = A >> (B & 0x1f); | Bitwise non signé à droite (avec argument masqué). |
complément | INT64 A, B; Résultat int64 = a + b; | Ajout de complément à deux. |
sous-long | INT64 A, B; Résultat int64 = a - b; | Soustraction de deux compléments. |
mâle | INT64 A, B; Résultat int64 = a * b; | Multiplication des deux compléments. |
divorant | INT64 A, B; Résultat int64 = a / b; | Division des deux compléments, arrondi vers zéro (c'est-à-dire tronqué à entier). Cela jette ArithmeticException si b == 0 . |
de longue date | INT64 A, B; Résultat int64 = un% b; | Twos-complément reste après la division. Le signe du résultat est le même que celui de a , et il est plus précisément défini comme result == a - (a / b) * b . Cela jette ArithmeticException si b == 0 . |
et long | INT64 A, B; Résultat INT64 = A&B; | Bitwise et. |
ou long | INT64 A, B; Résultat INT64 = A | b; | Bitwise ou. |
xor | INT64 A, B; Résultat int64 = a ^ b; | Xor bitwise. |
chroniqueur | int64 a; INT32 B; INT64 Result = A << (B & 0x3f); | Bitwise Shift à gauche (avec argument masqué). |
shrolon | int64 a; INT32 B; INT64 Result = A >> (B & 0x3f); | Bitwise Signed Shift Right (avec un argument masqué). |
de longue date | uint64 a; INT32 B; INT64 Result = A >> (B & 0x3f); | Bitwise non signé à droite (avec argument masqué). |
ajouter | Float A, B; Résultat float = a + b; | Ajout de points flottants. |
sous-plan | Float A, B; Résultat float = a - b; | Soustraction du point flottant. |
mâle | Float A, B; Résultat float = a * b; | Multiplication des points flottants. |
div-flott | Float A, B; Résultat float = a / b; | Division des points flottants. |
remorqueur | Float A, B; Résultat flottant = un% b; | Point flottant reste après la division. Cette fonction est différente de l'IEEE 754 reste et est définie comme result == a - roundTowardZero(a / b) * b . |
additionner | Double A, B; Double résultat = a + b; | Ajout de points flottants. |
sous-double | Double A, B; Double résultat = a - b; | Soustraction du point flottant. |
mUl-double | Double A, B; Double résultat = a * b; | Multiplication des points flottants. |
div-doubble | Double A, B; Double résultat = a / b; | Division des points flottants. |
remor-doubble | Double A, B; Double résultat = un% b; | Point flottant reste après la division. Cette fonction est différente de l'IEEE 754 reste et est définie comme result == a - roundTowardZero(a / b) * b . |