Comment créer un pool de données dans Jasmin?
Question
Jasmin a-t-il la capacité de spécifier un pool constant? J'ai besoin de pouvoir créer une zone de descripteur de milliers d'octets. La zone contiendra des données d'octets arbitraires, y compris Nulls. Voici un exemple d'une directive d'assemblage typique pour déclarer les constantes binaires:
data 0x00, 0x01, 10, 32 ...
Il semble que les fichiers de classe Java contiennent ces zones, mais je ne trouve pas de moyen dans Jasmin de déclarer les valeurs à une si grande échelle.
La solution
Cette zone du fichier de classe Java est appelée le pool constant et est décrit en détail dans §4.4 de la spécification JVM.
Il ne peut cependant pas contenir des données non typées arbitraires, mais contient plutôt des données dactylographiées seulement.
Les types de données pris en charge sont:
CONSTANT_Class
CONSTANT_Fieldref
CONSTANT_Methodref
CONSTANT_InterfaceMethodref
CONSTANT_String
CONSTANT_Integer
CONSTANT_Float
CONSTANT_Long
CONSTANT_Double
CONSTANT_NameAndType
CONSTANT_Utf8
Aucun de ces types prennent en charge arbitraire byte
Données de longueur arbitraire. CONSTANT_Utf8
Le plus proche, mais nécessite que son contenu soit des données UTF-8 valides et ne permet pas 0 octets.
La meilleure façon de savoir comment byte[]
sont codés, c'est en définir un en Java et décompiler .class
dossier. Pour autant que je sache UN byte[]
est compilé avec un bloc d'initialiseur définissant ses champs.
Confirmé: cette classe Java:
public class Test {
byte[] b = { 0, 1, 2, 3, 100 };
}
Décompiles à cela (en utilisant 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
}
Comme vous pouvez le voir, le constructeur généré définit "manuellement" les 5 valeurs dans le tableau nouvellement alloué.