Diseño general
- El modelo de máquina y las convenciones de llamada pretenden imitar aproximadamente arquitecturas reales comunes y convenciones de llamada de estilo C:
- La máquina se basa en registros y el tamaño de los fotogramas se fija en el momento de su creación. Cada cuadro consta de un número particular de registros (especificados por el método), así como de cualquier dato adjunto necesario para ejecutar el método, como (pero no limitado a) el contador del programa y una referencia al archivo
.dex
que contiene el método. . - Cuando se utilizan para valores de bits (como números enteros y números de punto flotante), los registros se consideran de 32 bits de ancho. Los pares de registros adyacentes se utilizan para valores de 64 bits. No existe ningún requisito de alineación para los pares de registros.
- Cuando se utilizan para referencias de objetos, los registros se consideran lo suficientemente anchos como para contener exactamente una de esas referencias.
- En términos de representación bit a bit,
(Object) null == (int) 0
. - Los N argumentos de un método aterrizan en los últimos N registros del marco de invocación del método, en orden. Los argumentos amplios consumen dos registros. A los métodos de instancia se les pasa
this
referencia como primer argumento.
- La máquina se basa en registros y el tamaño de los fotogramas se fija en el momento de su creación. Cada cuadro consta de un número particular de registros (especificados por el método), así como de cualquier dato adjunto necesario para ejecutar el método, como (pero no limitado a) el contador del programa y una referencia al archivo
- La unidad de almacenamiento en el flujo de instrucciones es una cantidad sin signo de 16 bits. Algunos bits en algunas instrucciones se ignoran/deben ser cero.
- Las instrucciones no se limitan gratuitamente a un tipo particular. Por ejemplo, las instrucciones que mueven valores de registros de 32 bits sin interpretación no tienen que especificar si mueven enteros o flotantes.
- Hay grupos de constantes indexados y enumerados por separado para referencias a cadenas, tipos, campos y métodos.
- Los datos literales bit a bit se representan en línea en el flujo de instrucciones.
- Debido a que, en la práctica, es poco común que un método necesite más de 16 registros, y debido a que necesitar más de ocho registros es razonablemente común, muchas instrucciones se limitan a abordar solo los primeros 16 registros. Cuando sea razonablemente posible, las instrucciones permiten referencias hasta a los primeros 256 registros. Además, algunas instrucciones tienen variantes que permiten recuentos de registros mucho mayores, incluido un par de instrucciones
move
generales que pueden abordar registros en el rangov0
–v65535
. En los casos en los que una variante de instrucción no está disponible para abordar un registro deseado, se espera que el contenido del registro se mueva del registro original a un registro bajo (antes de la operación) y/o se mueva de un registro de resultado bajo a un registro alto. registrarse (después de la operación). - Hay varias "pseudoinstrucciones" que se utilizan para contener cargas útiles de datos de longitud variable, a las que se hace referencia mediante instrucciones regulares (por ejemplo,
fill-array-data
). Este tipo de instrucciones nunca deben encontrarse durante el flujo normal de ejecución. Además, las instrucciones deben ubicarse en desplazamientos de códigos de bytes pares (es decir, alineados con 4 bytes). Para cumplir con este requisito, las herramientas de generación dex deben emitir una instrucciónnop
adicional como espaciador si, de lo contrario, dicha instrucción no estaría alineada. Finalmente, aunque no es obligatorio, se espera que la mayoría de las herramientas elijan emitir estas instrucciones al final de los métodos, ya que de lo contrario probablemente se necesitarían instrucciones adicionales para ramificarlas. - Cuando se instala en un sistema en ejecución, algunas instrucciones pueden modificarse, cambiando su formato, como una optimización de enlaces estáticos durante la instalación. Esto es para permitir una ejecución más rápida una vez que se conoce el vínculo. Consulte el documento de formatos de instrucciones asociado para conocer las variantes sugeridas. La palabra "sugerido" se utiliza deliberadamente; no es obligatorio implementarlos.
- Sintaxis humana y mnemónicos:
- Orden de destino y luego origen para los argumentos.
- Algunos códigos de operación tienen un sufijo de nombre desambiguante para indicar los tipos en los que operan:
- Los códigos de operación de tipo general de 32 bits no están marcados.
- Los códigos de operación de tipo general de 64 bits tienen el sufijo
-wide
. - Los códigos de operación específicos de tipo tienen el sufijo de su tipo (o una abreviatura sencilla), uno de:
-boolean
-byte
-char
-short
-int
-long
-float
-double
-object
-string
-class
-void
.
- Algunos códigos de operación tienen un sufijo desambiguante para distinguir operaciones idénticas que tienen diferentes diseños u opciones de instrucciones. Estos sufijos están separados de los nombres principales con una barra diagonal ("
/
") y existen principalmente para hacer que haya un mapeo uno a uno con constantes estáticas en el código que genera e interpreta los ejecutables (es decir, para reducir la ambigüedad). para humanos). - En las descripciones aquí, el ancho de un valor (que indica, por ejemplo, el rango de una constante o el número de registros posiblemente direccionados) se enfatiza mediante el uso de un carácter por cada cuatro bits de ancho.
- Por ejemplo, en la instrucción "
move-wide/from16 vAA, vBBBB
":- "
move
" es el código de operación base, que indica la operación base (mover el valor de un registro). - "
wide
" es el sufijo del nombre, lo que indica que opera con datos anchos (64 bits). - "
from16
" es el sufijo del código de operación, que indica una variante que tiene una referencia de registro de 16 bits como fuente. - "
vAA
" es el registro de destino (implícito en la operación; nuevamente, la regla es que los argumentos de destino siempre van primero), que debe estar en el rangov0
–v255
. - "
vBBBB
" es el registro fuente, que debe estar en el rangov0
–v65535
.
- "
- Consulte el documento de formatos de instrucciones para obtener más detalles sobre los distintos formatos de instrucciones (enumerados en "Op. y formato"), así como detalles sobre la sintaxis del código de operación.
- Consulte el documento de formato de archivo
.dex
para obtener más detalles sobre dónde encaja el código de bytes en el panorama general.
Resumen del conjunto de códigos de bytes
Operación y formato | Mnemónico / Sintaxis | Argumentos | Descripción |
---|---|---|---|
00 10x | nop | Ciclos de residuos. Nota: Las pseudoinstrucciones que contienen datos están etiquetadas con este código de operación, en cuyo caso el byte de orden superior de la unidad del código de operación indica la naturaleza de los datos. Consulte "Formato | |
01 12x | mover vA, vB | A: registro de destino (4 bits)B: registro fuente (4 bits) | Mueve el contenido de un registro que no es objeto a otro. |
02 22x | mover/desde16 vAA, vBBBB | A: registro de destino (8 bits)B: registro fuente (16 bits) | Mueve el contenido de un registro que no es objeto a otro. |
03 32x | mover/16 vAAAA, vBBBB | A: registro de destino (16 bits)B: registro fuente (16 bits) | Mueve el contenido de un registro que no es objeto a otro. |
04 12x | movimiento amplio vA, vB | A: par de registros de destino (4 bits)B: par de registros fuente (4 bits) | Mueva el contenido de un par de registros a otro. Nota: Es legal pasar de |
05 22x | mover-ancho/desde16 vAA, vBBBB | A: par de registros de destino (8 bits)B: par de registros fuente (16 bits) | Mueva el contenido de un par de registros a otro. Nota: Las consideraciones de implementación son las mismas que las de |
06 32x | movimiento amplio/16 vAAAA, vBBBB | A: par de registros de destino (16 bits)B: par de registros fuente (16 bits) | Mueva el contenido de un par de registros a otro. Nota: Las consideraciones de implementación son las mismas que las de |
07 12x | mover objeto vA, vB | A: registro de destino (4 bits)B: registro fuente (4 bits) | Mueva el contenido de un registro portador de objetos a otro. |
08 22x | mover-objeto/desde16 vAA, vBBBB | A: registro de destino (8 bits)B: registro fuente (16 bits) | Mueva el contenido de un registro portador de objetos a otro. |
09 32x | mover-objeto/16 vAAAA, vBBBB | A: registro de destino (16 bits)B: registro fuente (16 bits) | Mueva el contenido de un registro portador de objetos a otro. |
0a 11x | resultado-movimiento vAA | A: registro de destino (8 bits) | Mueva el resultado de una sola palabra que no sea objeto del invoke- kind más reciente al registro indicado. Esto debe hacerse como la instrucción inmediatamente después de un invoke- kind cuyo resultado (de una sola palabra, sin objeto) no debe ignorarse; en cualquier otro lugar no es válido. |
0b 11x | mover-resultado-todo vAA | A: par de registros de destino (8 bits) | Mueva el resultado de doble palabra del invoke- kind más reciente al par de registros indicado. Esto debe hacerse como la instrucción inmediatamente después de un invoke- kind cuyo resultado (palabra doble) no debe ignorarse; en cualquier otro lugar no es válido. |
0c 11x | mover-resultado-objeto vAA | A: registro de destino (8 bits) | Mueva el resultado del objeto del invoke- kind más reciente al registro indicado. Esto debe hacerse como la instrucción inmediatamente después de una invoke- kind o filled-new-array cuyo resultado (objeto) no debe ignorarse; en cualquier otro lugar no es válido. |
0d 11x | excepción de movimiento vAA | A: registro de destino (8 bits) | Guarde una excepción recién detectada en el registro proporcionado. Esta debe ser la primera instrucción de cualquier manejador de excepciones cuya excepción detectada no deba ignorarse, y esta instrucción solo debe ocurrir como la primera instrucción de un manejador de excepciones; en cualquier otro lugar no es válido. |
0e 10x | retorno nulo | Regreso de un método void . | |
0f 11x | devolver vaa | A: registro de valor de retorno (8 bits) | Retorno desde un método de devolución de valor sin objeto de ancho único (32 bits). |
10 11x | vAA de todo el retorno | A: valor de retorno par de registros (8 bits) | Regreso de un método de devolución de valor de doble ancho (64 bits). |
11 11x | objeto de retorno vAA | A: registro de valor de retorno (8 bits) | Regreso de un método de devolución de objetos. |
12 11n | constante/4vA, #+B | A: registro de destino (4 bits)B: int con signo (4 bits) | Mueva el valor literal dado (signo extendido a 32 bits) al registro especificado. |
13 21 | constante/16 vAA, #+BBBB | A: registro de destino (8 bits)B: int con signo (16 bits) | Mueva el valor literal dado (signo extendido a 32 bits) al registro especificado. |
14 31i | constante vAA, #+BBBBBBBB | A: registro de destino (8 bits)B: constante arbitraria de 32 bits | Mueva el valor literal dado al registro especificado. |
15 21h | constante/alto16 vAA, #+BBBB0000 | A: registro de destino (8 bits)B: int con signo (16 bits) | Mueva el valor literal dado (cero a la derecha extendido a 32 bits) al registro especificado. |
16 21 | ancho constante/16 vAA, #+BBBB | A: registro de destino (8 bits)B: int con signo (16 bits) | Mueva el valor literal dado (signo extendido a 64 bits) al par de registros especificado. |
17 31i | ancho constante/32 vAA, #+BBBBBBBB | A: registro de destino (8 bits)B: int con signo (32 bits) | Mueva el valor literal dado (signo extendido a 64 bits) al par de registros especificado. |
18 51l | vAA constante, #+BBBBBBBBBBBBBBBB | A: registro de destino (8 bits)B: constante arbitraria de doble ancho (64 bits) | Mueva el valor literal dado al par de registros especificado. |
19 21h | constante ancho/alto16 vAA, #+BBBB000000000000 | A: registro de destino (8 bits)B: int con signo (16 bits) | Mueva el valor literal dado (cero a la derecha extendido a 64 bits) al par de registros especificado. |
1a 21c | cadena constante vAA, cadena@BBBB | A: registro de destino (8 bits)B: índice de cadena | Mueva una referencia a la cadena especificada por el índice dado al registro especificado. |
1b 31c | cadena constante/vAA jumbo, cadena@BBBBBBBB | A: registro de destino (8 bits)B: índice de cadena | Mueva una referencia a la cadena especificada por el índice dado al registro especificado. |
1c 21c | clase constante vAA, tipo@BBBB | A: registro de destino (8 bits)B: índice de tipo | Mueva una referencia a la clase especificada por el índice dado al registro especificado. En el caso de que el tipo indicado sea primitivo, esto almacenará una referencia a la clase degenerada del tipo primitivo. |
1d 11x | monitor-ingrese vAA | A: registro de referencia (8 bits) | Adquirir el monitor para el objeto indicado. |
1e 11x | monitor-salida vAA | A: registro de referencia (8 bits) | Suelte el monitor para el objeto indicado. Nota: Si esta instrucción necesita generar una excepción, debe hacerlo como si la computadora ya hubiera avanzado más allá de la instrucción. Puede ser útil pensar en esto como si la instrucción se ejecutara exitosamente (en cierto sentido) y la excepción se lanzara después de la instrucción pero antes de que la siguiente tenga la oportunidad de ejecutarse. Esta definición hace posible que un método utilice un bloque general de limpieza de monitor (por ejemplo, |
1f 21c | check-cast vAA, escriba @BBBB | A: registro de referencia (8 bits)B: índice de tipo (16 bits) | Lanza una ClassCastException si la referencia en el registro dado no se puede convertir al tipo indicado. Nota: Dado que |
20 22c | instancia de vA, vB, tipo@CCCC | A: registro de destino (4 bits)B: registro de referencia (4 bits)C: índice de tipo (16 bits) | Almacene en el registro de destino dado 1 si la referencia indicada es una instancia del tipo dado, o 0 en caso contrario. Nota: Dado que |
21 12x | longitud de la matriz vA, vB | A: registro de destino (4 bits)B: registro de referencia de matriz (4 bits) | Almacenar en el registro de destino dado la longitud de la matriz indicada, en entradas |
22 21c | vAA de nueva instancia, tipo@BBBB | A: registro de destino (8 bits)B: índice de tipo | Construya una nueva instancia del tipo indicado, almacenando una referencia a ella en el destino. El tipo debe hacer referencia a una clase que no sea una matriz. |
23 22c | nueva matriz vA, vB, tipo@CCCC | A: registro de destino (4 bits)B: registro de tamañoC: índice de tipo | Construya una nueva matriz del tipo y tamaño indicados. El tipo debe ser un tipo de matriz. |
24 35c | nueva matriz llena {vC, vD, vE, vF, vG}, tipo@BBBB | A: tamaño de la matriz y recuento de palabras de argumento (4 bits)B: índice de tipo (16 bits)C..G: registros de argumentos (4 bits cada uno) | Construya una matriz del tipo y tamaño dados, llenándola con el contenido proporcionado. El tipo debe ser un tipo de matriz. El contenido de la matriz debe ser de una sola palabra (es decir, no hay matrices de tipo long o double , pero los tipos de referencia son aceptables). La instancia construida se almacena como un "resultado" de la misma manera que las instrucciones de invocación del método almacenan sus resultados, por lo que la instancia construida debe moverse a un registro con una instrucción move-result-object inmediatamente posterior (si se va a utilizar ). |
25 3c | nueva matriz llena/rango {vCCCC .. vNNNN}, tipo@BBBB | A: tamaño de la matriz y recuento de palabras de argumento (8 bits)B: índice de tipo (16 bits)C: registro del primer argumento (16 bits)N = A + C - 1 | Construya una matriz del tipo y tamaño dados, llenándola con el contenido proporcionado. Las aclaraciones y restricciones son las mismas que las filled-new-array descritas anteriormente. |
26 31t | fill-array-data vAA, +BBBBBBBB (con datos suplementarios como se especifica a continuación en "Formato fill-array-data-payload ") | A: referencia de matriz (8 bits)B: pseudoinstrucción de desplazamiento de "rama" firmada a los datos de la tabla (32 bits) | Complete la matriz dada con los datos indicados. La referencia debe ser a una matriz de primitivas, y la tabla de datos debe coincidir en tipo y no debe contener más elementos de los que caben en la matriz. Es decir, la matriz puede ser más grande que la tabla y, de ser así, solo se establecen los elementos iniciales de la matriz, dejando el resto solo. |
27 11x | tirar vAA | A: registro portador de excepciones (8 bits) | Lanza la excepción indicada. |
28 10t | ir a +AA | A: desplazamiento de rama con signo (8 bits) | Saltar incondicionalmente a la instrucción indicada. Nota: El desplazamiento de la rama no debe ser |
29 20t | ir a/16 +AAAA | A: desplazamiento de rama con signo (16 bits) | Saltar incondicionalmente a la instrucción indicada. Nota: El desplazamiento de la rama no debe ser |
2a 30t | ir a/32 +AAAAAAAA | A: desplazamiento de rama con signo (32 bits) | Saltar incondicionalmente a la instrucción indicada. |
2b 31t | pack-switch-vAA, +BBBBBBBB (con datos suplementarios como se especifica a continuación en "Formato packed-switch-payload ") | A: registrarse para probarB: pseudoinstrucción de desplazamiento de "rama" firmada a los datos de la tabla (32 bits) | Salte a una nueva instrucción basada en el valor en el registro dado, usando una tabla de compensaciones correspondientes a cada valor en un rango integral particular, o pase a la siguiente instrucción si no hay coincidencia. |
2c 31t | sparse-switch vAA, +BBBBBBBB (con datos complementarios como se especifica a continuación en "Formato sparse-switch-payload ") | A: registrarse para probarB: pseudoinstrucción de desplazamiento de "rama" firmada a los datos de la tabla (32 bits) | Salte a una nueva instrucción basada en el valor del registro dado, utilizando una tabla ordenada de pares de valores-compensaciones, o pase a la siguiente instrucción si no hay coincidencia. |
2d..31 23x | cmp tipo vAA, vBB, vCC 2d: cmmpl-float (sesgo lt) 2e: cmpg-float (sesgo gt) 2f: cmpl-doble (sesgo lt) 30: cmpg-doble (sesgo gt) 31: cmp-largo | A: registro de destino (8 bits)B: primer registro o par fuenteC: segundo registro o par fuente | Realice el punto flotante indicado o una comparación long , estableciendo a en 0 si b == c , 1 si b > c o -1 si b < c . El "sesgo" enumerado para las operaciones de punto flotante indica cómo se tratan las comparaciones NaN : las instrucciones "gt sesgo" devuelven 1 para comparaciones NaN y las instrucciones "lt sesgo" devuelven -1 . Por ejemplo, para comprobar si el punto flotante |
32..37 22t | si- prueba vA, vB, +CCCC 32: si-eq 33: si-ne 34: si-lt 35: si-ge 36: si-gt 37: si-le | A: primer registro para probar (4 bits)B: segundo registro para probar (4 bits)C: desplazamiento de rama con signo (16 bits) | Vaya al destino dado si los valores de los dos registros dados se comparan según lo especificado. Nota: El desplazamiento de la rama no debe ser |
38..3d 21t | si- prueba z vAA, +BBBB 38: si-eqz 39: si-nez 3a: si-ltz 3b: si-gez 3c: si-gtz 3d: si-lez | A: registrarse para probar (8 bits)B: desplazamiento de rama con signo (16 bits) | Salte al destino dado si el valor del registro dado se compara con 0 como se especifica. Nota: El desplazamiento de la rama no debe ser |
3e..43 10x | (no usado) | (no usado) | |
44..51 23x | arrayop vAA, vBB, vCC 44: conseguir 45: toda la edad 46: objeto-objeto 47: aget-booleano 48: aget-byte 49: aget-char 4a: get-short 4b: aput 4c: todo el aput 4d: objeto-aput 4e: aput-booleano 4f: aput-byte 50: aput-char 51: aput-corto | A: registro o par de valores; puede ser origen o destino (8 bits)B: registro de matriz (8 bits)C: registro índice (8 bits) | Realice la operación de matriz identificada en el índice identificado de la matriz dada, cargándola o almacenándola en el registro de valor. |
52..5f 22c | i instanciaop vA, vB, campo@CCCC 52: conseguir 53: iget-ancho 54: iget-objeto 55: iget-booleano 56: iget-byte 57: iget-char 58: iget-corto 59: entrada 5a: en toda la entrada 5b: objeto-iput 5c: iput-booleano 5d: byte de entrada 5e: iput-char 5f: iput-corto | A: registro o par de valores; puede ser origen o destino (4 bits)B: registro de objeto (4 bits)C: índice de referencia del campo de instancia (16 bits) | Realice la operación de campo de instancia de objeto identificado con el campo identificado, cargándolo o almacenándolo en el registro de valor. Nota: Estos códigos de operación son candidatos razonables para enlaces estáticos, alterando el argumento del campo para que sea un desplazamiento más directo. |
60..6d 21c | s staticop vAA, campo@BBBB 60: sget 61: todo el sget 62: objeto-sget 63: sget-booleano 64: sget-byte 65: sget-char 66: sget-corto 67: escupir 68: todo el sput 69: objeto de esputo 6a: sput-booleano 6b: byte de salida 6c: sput-char 6d: sput-corto | A: registro o par de valores; puede ser origen o destino (8 bits)B: índice de referencia de campo estático (16 bits) | Realice la operación del campo estático del objeto identificado con el campo estático identificado, cargándolo o almacenándolo en el registro de valor. Nota: Estos códigos de operación son candidatos razonables para enlaces estáticos, alterando el argumento del campo para que sea un desplazamiento más directo. |
6e..72 35c | invocar tipo {vC, vD, vE, vF, vG}, meta@BBBB 6e: invocar-virtual 6f: invocar-super 70: invocación directa 71: invocar-estático 72: interfaz de invocación | A: recuento de palabras de argumento (4 bits)B: índice de referencia del método (16 bits)C..G: registros de argumentos (4 bits cada uno) | Llame al método indicado. El resultado (si lo hay) se puede almacenar con una variante apropiada move-result* como instrucción inmediatamente posterior. Cuando el En los archivos Dex versión Nota: Estos códigos de operación son candidatos razonables para la vinculación estática, alterando el argumento del método para que sea un desplazamiento más directo (o un par de ellos). |
73 10x | (no usado) | (no usado) | |
74..78 3rc | invocar tipo /rango {vCCCC .. vNNNN}, meta@BBBB 74: invocar-virtual/rango 75: invocar-super/rango 76: invocación directa/rango 77: invocar-estático/rango 78: invocar-interfaz/rango | A: recuento de palabras de argumento (8 bits)B: índice de referencia del método (16 bits)C: registro del primer argumento (16 bits)N = A + C - 1 | Llame al método indicado. Consulte la descripción anterior del primer invoke- kind para obtener detalles, advertencias y sugerencias. |
79..7a 10x | (no usado) | (no usado) | |
7b..8f 12x | unop va, vB 7b: neg-int 7c: no-int 7d: neg-largo 7e: no mucho 7f: flotación negativa 80: neg-doble 81: int a largo 82: int-a-flotar 83: int-a-doble 84: largo a int 85: largo para flotar 86: largo a doble 87: flotante a int 88: flotante a largo 89: flotar a doble 8a: doble a int 8b: doble a largo 8c: doble para flotar 8d: int a byte 8e: int-a-char 8f: int a corto | A: registro o par de destino (4 bits)B: registro fuente o par (4 bits) | Realice la operación unaria identificada en el registro de origen, almacenando el resultado en el registro de destino. |
90..af 23x | binop vAA, vBB, vCC 90: complemento 91: sub-int 92: multiint 93: div-int 94: remanente 95: y-int 96: o-int 97: xor-int 98: shl-int 99: encogimiento 9a: ushr-int 9b: complemento largo 9c: sublargo 9d: mul-largo 9e: div-largo 9f: rem-largo a0: y-largo a1: o-largo a2: xor-largo a3: shl-largo a4: shr-largo a5: ushr-largo a6: agregar flotación a7: subflotación a8: mul-flotación a9: div-flotante aa: flotación remota ab: sumar-doble ac: subdoble anuncio: mul-doble ae: div-doble af: rem-doble | A: registro o par de destino (8 bits)B: primer registro o par fuente (8 bits)C: segundo registro o par fuente (8 bits) | Realice la operación binaria identificada en los dos registros de origen, almacenando el resultado en el registro de destino. Nota: A diferencia de otras operaciones matemáticas |
b0..cf 12x | binop /2dirección vA, vB b0: complemento/2dirección b1: sub-int/2dirección b2: mul-int/2addr b3: div-int/2dirección b4: rem-int/2addr b5: and-int/2addr b6: o-int/2addr b7: xor-int/2dirección b8: shl-int/2addr b9: shr-int/2addr ba: ushr-int/2addr bb: agregar largo/2dirección bc: sublargo/2addr bd: mul-long/2addr ser: div-long/2addr novio: rem-long/2addr c0: y-largo/2addr c1: o-largo/2dirección c2: xor-long/2addr c3: shl-long/2addr c4: shr-long/2addr c5: ushr-long/2addr c6: agregar-flotante/2addr c7: subflotación/2dirección c8: mul-flotante/2addr c9: div-float/2addr ca: rem-float/2addr cb: agregar-doble/2dirección cc: subdoble/2addr cd: mul-doble/2addr ce: div-doble/2addr cf: rem-doble/2addr | A: registro o par de destino y primer origen (4 bits)B: segundo registro o par fuente (4 bits) | Realice la operación binaria identificada en los dos registros fuente, almacenando el resultado en el primer registro fuente. Nota: A diferencia de otras operaciones matemáticas |
d0..d7 22s | binop /lit16 vA, vB, #+CCCC d0: complemento/lit16 d1: rsub-int (resta inversa) d2: mul-int/lit16 d3: div-int/lit16 d4: remanente/lit16 d5: and-int/lit16 d6: or-int/lit16 d7: xor-int/lit16 | A: registro de destino (4 bits)B: registro fuente (4 bits)C: constante int con signo (16 bits) | Realizar la operación binaria indicada sobre el registro indicado (primer argumento) y el valor literal (segundo argumento), almacenando el resultado en el registro de destino. Nota: |
d8..e2 22b | binop /lit8 vAA, vBB, #+CC d8: complemento/lit8 d9: rsub-int/lit8 da: mul-int/lit8 base de datos: div-int/lit8 CC: 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: registro de destino (8 bits)B: registro fuente (8 bits)C: constante int con signo (8 bits) | Realizar la operación binaria indicada sobre el registro indicado (primer argumento) y el valor literal (segundo argumento), almacenando el resultado en el registro de destino. Nota: Consulte a continuación para obtener detalles sobre la semántica de |
e3..f9 10x | (no usado) | (no usado) | |
45cc | invocar polimórfico {vC, vD, vE, vF, vG}, meta@BBBB, proto@HHHH | A: recuento de palabras de argumento (4 bits)B: índice de referencia del método (16 bits)C: receptor (4 bits)D..G: registros de argumentos (4 bits cada uno)H: índice de referencia del prototipo (16 bits) | Invoca el método polimórfico de firma indicado. El resultado (si lo hay) se puede almacenar con una variante apropiada move-result* como instrucción inmediatamente posterior.La referencia del método debe ser un método polimórfico característico, como java.lang.invoke.MethodHandle.invoke o java.lang.invoke.MethodHandle.invokeExact .El receptor debe ser un objeto que admita el método polimórfico de firma que se invoca. La referencia del prototipo describe los tipos de argumentos proporcionados y el tipo de retorno esperado. El código de bytes invoke-polymorphic puede generar excepciones cuando se ejecuta. Las excepciones se describen en la documentación de la API para el método polimórfico de firma que se invoca.Presente en archivos Dex desde la versión 038 en adelante. |
facebook 4rcc | invocar-polimórfico/rango {vCCCC .. vNNNN}, meta@BBBB, proto@HHHH | A: recuento de palabras de argumento (8 bits)B: índice de referencia del método (16 bits)C: receptor (16 bits)H: índice de referencia del prototipo (16 bits)N = A + C - 1 | Invoca el identificador del método indicado. Consulte la descripción invoke-polymorphic anterior para obtener más detalles.Presente en archivos Dex desde la versión 038 en adelante. |
fc 35c | invocar-personalizado {vC, vD, vE, vF, vG}, call_site@BBBB | A: recuento de palabras de argumento (4 bits)B: índice de referencia del sitio de llamada (16 bits)C..G: registros de argumentos (4 bits cada uno) | Resuelve e invoca el sitio de llamada indicado. El resultado de la invocación (si existe) se puede almacenar con una variante apropiada move-result* como instrucción inmediatamente posterior.Esta instrucción se ejecuta en dos fases: resolución del sitio de llamada e invocación del sitio de llamada. La resolución del sitio de llamadas comprueba si el sitio de llamadas indicado tiene una instancia java.lang.invoke.CallSite asociada. De lo contrario, el método del vinculador de arranque para el sitio de llamada indicado se invoca utilizando argumentos presentes en el archivo DEX (consulte call_site_item ). El método del vinculador bootstrap devuelve una instancia java.lang.invoke.CallSite que luego se asociará con el sitio de llamada indicado si no existe ninguna asociación. Es posible que otro subproceso ya haya realizado la asociación primero y, de ser así, la ejecución de la instrucción continúa con la primera instancia java.lang.invoke.CallSite asociada.La invocación del sitio de llamada se realiza en el destino java.lang.invoke.MethodHandle de la instancia java.lang.invoke.CallSite resuelta. El objetivo se invoca como si se estuviera ejecutando invoke-polymorphic (descrito anteriormente) utilizando el identificador del método y los argumentos de la instrucción invoke-custom como argumentos para una invocación exacta del identificador de método.Las excepciones generadas por el método del vinculador bootstrap están envueltas en un java.lang.BootstrapMethodError . También se genera un BootstrapMethodError si:
038 en adelante. |
fd3rc | invocar-personalizado/rango {vCCCC .. vNNNN}, call_site@BBBB | A: recuento de palabras de argumento (8 bits)B: índice de referencia del sitio de llamada (16 bits)C: registro del primer argumento (16 bits)N = A + C - 1 | Resolver e invocar un sitio de llamada. Consulte la descripción invoke-custom anterior para obtener más detalles.Presente en archivos Dex desde la versión 038 en adelante. |
fe 21c | mango-método-const vAA, mango_método@BBBB | A: registro de destino (8 bits)B: índice de identificador de método (16 bits) | Mueva una referencia al identificador del método especificado por el índice dado al registro especificado. Presente en archivos Dex desde la versión 039 en adelante. |
ff 21c | método constante tipo vAA, proto@BBBB | A: registro de destino (8 bits)B: referencia del prototipo del método (16 bits) | Mueva una referencia al prototipo del método especificado por el índice dado al registro especificado. Presente en archivos Dex desde la versión 039 en adelante. |
formato de carga útil del conmutador empaquetado
Nombre | Formato | Descripción |
---|---|---|
identificador | ucorto = 0x0100 | identificar pseudocódigo de operación |
tamaño | corto | número de entradas en la tabla |
primera_clave | En t | primer (y más bajo) valor del caso de cambio |
objetivos | En t[] | lista de objetivos de rama relativos size . Los objetivos son relativos a la dirección del código de operación del conmutador, no a esta tabla. |
Nota: El número total de unidades de código para una instancia de esta tabla es (size * 2) + 4
.
formato de carga útil de cambio disperso
Nombre | Formato | Descripción |
---|---|---|
identificador | ucorto = 0x0200 | identificar pseudocódigo de operación |
tamaño | corto | número de entradas en la tabla |
llaves | En t[] | lista de valores clave size , ordenados de menor a mayor |
objetivos | En t[] | lista de objetivos de rama relativos size , cada uno correspondiente al valor clave en el mismo índice. Los objetivos son relativos a la dirección del código de operación del conmutador, no a esta tabla. |
Nota: El número total de unidades de código para una instancia de esta tabla es (size * 4) + 2
.
formato de carga útil de datos de matriz de relleno
Nombre | Formato | Descripción |
---|---|---|
identificador | ucorto = 0x0300 | identificar pseudocódigo de operación |
ancho_elemento | corto | número de bytes en cada elemento |
tamaño | uint | número de elementos en la tabla |
datos | ubyte[] | valores de datos |
Nota: El número total de unidades de código para una instancia de esta tabla es (size * element_width + 1) / 2 + 4
.
Detalles de la operación matemática
Nota: Las operaciones de coma flotante deben seguir las reglas IEEE 754, utilizando redondeo al más cercano y desbordamiento gradual, excepto que se indique lo contrario.
Código de operación | C Semántica | Notas |
---|---|---|
neg-int | int32a; resultado int32 = -a; | Complemento unario a dos. |
no-int | int32a; resultado int32 = ~a; | Complemento unario. |
neg-largo | int64a; resultado int64 = -a; | Complemento unario a dos. |
No largo | int64a; resultado int64 = ~a; | Complemento unario. |
flotación negativa | flotar un; resultado flotante = -a; | Negación de coma flotante. |
neg-doble | doble a; resultado doble = -a; | Negación de coma flotante. |
int a largo | int32a; resultado int64 = (int64) a; | Firme la extensión de int32 en int64 . |
int-a-flotar | int32a; resultado flotante = (flotante) a; | Conversión de int32 a float , usando redondear. Esto pierde precisión para algunos valores. |
int-doblar | int32 a; resultado doble = (doble) a; | Conversión de int32 a double . |
largo | int64 a; int32 resultado = (int32) a; | Truncamiento de int64 en int32 . |
largo | int64 a; resultado flotante = (flotante) a; | Conversión de int64 a float , usando redondear. Esto pierde precisión para algunos valores. |
largo | int64 a; resultado doble = (doble) a; | Conversión de int64 a double , usando redondear a la más reina. Esto pierde precisión para algunos valores. |
flotante | flotar un; int32 resultado = (int32) a; | Conversión de float a int32 , usando el-cero redondo de cero. NaN y -0.0 (cero negativo) se convierten al entero 0 . Los infinitos y los valores con una magnitud demasiado grande para representarse se convierten en 0x7fffffff o -0x80000000 dependiendo del signo. |
flotante | flotar un; int64 resultado = (int64) a; | Conversión de float a int64 , usando el cero redondo de cero. Las mismas reglas de caso especial que para float-to-int se aplican aquí, excepto que los valores fuera de rango se convierten en 0x7fffffffffffffff o -0x8000000000000000 dependiendo del signo. |
flotante a doble | flotar un; resultado doble = (doble) a; | Conversión de float a double , preservando el valor exactamente. |
doble | doble a; int32 resultado = (int32) a; | Conversión de double a int32 , utilizando cero redondo de cero. Las mismas reglas de casos especiales que para float-to-int se aplican aquí. |
doble | doble a; int64 resultado = (int64) a; | Conversión de double a int64 , utilizando cero redondo de cero. Las mismas reglas especiales de caso que para float-to-long se aplican aquí. |
doble a piso | doble a; resultado flotante = (flotante) a; | Conversión de double a float , usando redondear. Esto pierde precisión para algunos valores. |
int-byte | int32 a; int32 result = (a << 24) >> 24; | Truncamiento de int32 a int8 , signo extendiendo el resultado. |
int-to-Char | int32 a; int32 result = a & 0xffff; | Truncamiento de int32 a uint16 , sin extensión de signo. |
int-a-short | int32 a; int32 result = (a << 16) >> 16; | Truncamiento de int32 a int16 , signo que extiende el resultado. |
complemento | int32 a, b; int32 resultado = a + b; | Adición de Twos-Complemento. |
submarino | int32 a, b; int32 resultado = a - b; | RESTRACIÓN DE TWOS-COMPLEMENT. |
intensidad | int32 a, b; int32 resultado = b - a; | RESTRACCIÓN INVERSE DE TWOS-COMPLEMENT. |
insignificante | int32 a, b; int32 resultado = a * b; | Multiplicación de Twos-Complement. |
div-entrada | int32 a, b; Resultado int32 = a / b; | División de complemento de dos, redondeada hacia cero (es decir, truncada a entero). Esto arroja ArithmeticException si b == 0 . |
rem-intento | int32 a, b; int32 resultado = a % b; | DWOS-COMPLEMENTE RESTERENTE CUENTA DIVISIÓN. El signo del resultado es el mismo que el de a , y se define con mayor precisión como result == a - (a / b) * b Esto arroja ArithmeticException si b == 0 . |
y | int32 a, b; int32 resultado = a & b; | Bit a bit Y. |
o-entrada | int32 a, b; int32 resultado = a | b; | O bit a bit. |
xor | int32 a, b; int32 resultado = a ^ b; | Bitwise xor. |
SHL-INT | int32 a, b; int32 result = a << (b & 0x1f); | Cambio de bit a bit a la izquierda (con argumento enmascarado). |
shr-intemperatura | int32 a, b; int32 resultado = a >> (b & 0x1f); | Bitwise firmado desplazamiento a la derecha (con argumento enmascarado). |
USHR-INT | uint32 a, b; int32 resultado = a >> (b & 0x1f); | Bitwise Unsigned Shift Derecha (con argumento enmascarado). |
anhelo | int64 a, b; int64 resultado = a + b; | Adición de Twos-Complemento. |
subterráneo | int64 a, b; int64 resultado = a - b; | RESTRACIÓN DE TWOS-COMPLEMENT. |
mul | int64 a, b; int64 resultado = a * b; | Multiplicación de Twos-Complement. |
Div-Div | int64 a, b; Resultado int64 = a / b; | División de complemento de dos, redondeada hacia cero (es decir, truncada a entero). Esto arroja ArithmeticException si b == 0 . |
remulgado | int64 a, b; int64 resultado = a % b; | DWOS-COMPLEMENTE RESTERENTE CUENTA DIVISIÓN. El signo del resultado es el mismo que el de a , y se define con mayor precisión como result == a - (a / b) * b Esto arroja ArithmeticException si b == 0 . |
y largo | int64 a, b; int64 resultado = a & b; | Bit a bit Y. |
o largo | int64 a, b; int64 resultado = a | b; | O bit a bit. |
anual | int64 a, b; int64 resultado = a ^ b; | Bitwise xor. |
shl largo | int64 a; int32 b; int64 resultado = a << (b & 0x3f); | Cambio de bit a bit a la izquierda (con argumento enmascarado). |
shr largo | int64 a; int32 b; int64 resultado = a >> (b & 0x3f); | Bitwise firmado desplazamiento a la derecha (con argumento enmascarado). |
USHR largo | uint64 a; int32 b; int64 resultado = a >> (b & 0x3f); | Bitwise Unsigned Shift Derecha (con argumento enmascarado). |
agrega | flotar A, B; resultado flotante = a + b; | Adición de punto flotante. |
subsuelo | flotar A, B; Resultado flotante = a - b; | RESTRACIÓN DEL PUNTO FLOTANTE. |
mul-float | flotar A, B; resultado flotante = a * b; | Multiplicación del punto flotante. |
Divlibre | flotar A, B; resultado flotante = a / b; | División de puntos flotantes. |
remo | flotar A, B; resultado flotante = a % b; | Punto flotante RESTANTE ASPARACIÓN AL DIVISIÓN. Esta función es diferente al resto IEEE 754 y se define como result == a - roundTowardZero(a / b) * b . |
agrega-doble | doble a, b; resultado doble = a + b; | Adición de punto flotante. |
subdobilar | doble a, b; resultado doble = a - b; | RESTRACIÓN DEL PUNTO FLOTANTE. |
MUL-Double | doble a, b; resultado doble = a * b; | Multiplicación del punto flotante. |
Div-Double | doble a, b; resultado doble = a / b; | División de puntos flotantes. |
remo | doble a, b; resultado doble = A % B; | Punto flotante RESTANTE ASPARACIÓN AL DIVISIÓN. Esta función es diferente al resto IEEE 754 y se define como result == a - roundTowardZero(a / b) * b . |