Pregunta

¿Jasmin tiene la capacidad de especificar un grupo constante? Necesito poder crear un área descriptor de miles de bytes. El área contendrá datos de bytes arbitrarios, incluidos nulos. Aquí hay un ejemplo de una directiva de ensamblaje típica para declarar constantes binarias:

data  0x00, 0x01, 10, 32 ...

Parece que los archivos de clase Java contienen estas áreas, pero no puedo encontrar una manera en Jasmin para declarar los valores a una escala tan grande.

¿Fue útil?

Solución

Esa área en el archivo de clase Java se llama grupo constante y se describe en detalle en §4.4 de la especificación JVM.

Sin embargo, no puede contener datos arbitrarios sin tipo, sino que contiene datos tipados solamente.

Los tipos de datos compatibles son:

  • CONSTANT_Class
  • CONSTANT_Fieldref
  • CONSTANT_Methodref
  • CONSTANT_InterfaceMethodref
  • CONSTANT_String
  • CONSTANT_Integer
  • CONSTANT_Float
  • CONSTANT_Long
  • CONSTANT_Double
  • CONSTANT_NameAndType
  • CONSTANT_Utf8

Ninguna de esos tipos admiten arbitrarios byte Datos de longitud arbitraria. CONSTANT_Utf8 Se acerca más, pero requiere que su contenido sea válidos de datos UTF-8 y no permita 0 bytes.

La mejor manera de averiguar cómo byte[] están codificados es definir uno en Java y descompilar el resultante .class expediente. Por lo que sé A byte[] se compila en un bloque inicializador que establece sus campos.

Confirmado: Esta clase de Java:

public class Test {
  byte[] b = { 0, 1, 2, 3, 100 };
}

Descompila a esto (usando javac Test.java && javap -v Test):

Compiled from "Test.java"
public class Test extends java.lang.Object
  SourceFile: "Test.java"
  minor version: 0
  major version: 50
  Constant pool:
const #1 = Method   #4.#13; //  java/lang/Object."<init>":()V
const #2 = Field    #3.#14; //  Test.b:[B
const #3 = class    #15;    //  Test
const #4 = class    #16;    //  java/lang/Object
const #5 = Asciz    b;
const #6 = Asciz    [B;
const #7 = Asciz    <init>;
const #8 = Asciz    ()V;
const #9 = Asciz    Code;
const #10 = Asciz   LineNumberTable;
const #11 = Asciz   SourceFile;
const #12 = Asciz   Test.java;
const #13 = NameAndType #7:#8;//  "<init>":()V
const #14 = NameAndType #5:#6;//  b:[B
const #15 = Asciz   Test;
const #16 = Asciz   java/lang/Object;

{
byte[] b;

public Test();
  Code:
   Stack=5, Locals=1, Args_size=1
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   aload_0
   5:   iconst_5
   6:   newarray byte
   8:   dup
   9:   iconst_0
   10:  iconst_0
   11:  bastore
   12:  dup
   13:  iconst_1
   14:  iconst_1
   15:  bastore
   16:  dup
   17:  iconst_2
   18:  iconst_2
   19:  bastore
   20:  dup
   21:  iconst_3
   22:  iconst_3
   23:  bastore
   24:  dup
   25:  iconst_4
   26:  bipush  100
   28:  bastore
   29:  putfield    #2; //Field b:[B
   32:  return
  LineNumberTable: 
   line 1: 0
   line 2: 4


}

Como puede ver, el constructor generado "manualmente" establece los 5 valores en la matriz recién asignada.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top