¿Cómo crear un grupo de datos en Jasmin?
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.
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.