Les premiers pas
Le Jasmin est un assembleur pour la JVM (Java Virtual Machine). Il permet d'écrire directement du bytecode Java sous forme lisible par l'humain. Le code Jasmin est compilé en fichiers .class pouvant être exécutés par la JVM, exactement comme les fichiers générés par le compilateur javac.
Outils nécessaires
Pour utiliser Jasmin, il est tout d'abord indispensable d'avoir installé le JDK (Java Development Kit) sur votre système. Le JDK comprend les outils de base pour travailler avec Java, comme java (le moteur d'exécution de la JVM) et javac (le compilateur Java standard). Même si Jasmin ne se sert pas directement de javac, le JDK reste essentiel pour exécuter les fichiers .class générés à partir du code Jasmin. Il est donc recommandé de télécharger et d'installer la dernière version du JDK depuis le site officiel d'Oracle ou d'utiliser une distribution open source comme OpenJDK.
Ensuite, il vous faut le fichier jasmin.jar, qui contient l'assembleur Jasmin lui-même. Cet outil prend un fichier source .j (contenant du bytecode écrit manuellement) et le convertit en un fichier .class que la JVM peut exécuter. Le fichier jasmin.jar est généralement disponible sur des dépôts GitHub ou via d'anciens sites de projet Jasmin. Il est portable et peut être utilisé avec n'importe quel système compatible avec Java (Windows, Linux, macOS). Pour l'utiliser, il suffit d'exécuter une commande du type java -jar jasmin.jar MonFichier.j.
Enfin, un éditeur de texte simple (comme Notepad++, Visual Studio Code ou vim) est suffisant pour écrire les fichiers .j. Jasmin ne dépend pas d'un IDE complexe. Cependant, il est utile de choisir un éditeur avec la coloration syntaxique ou la possibilité d'exécuter des scripts pour automatiser l'assemblage. Il est également conseillé d'organiser ses fichiers dans des dossiers de projet pour séparer les sources .j, les fichiers .class générés et les éventuels scripts de test. Une bonne organisation vous aidera à gagner du temps, surtout quand vous manipulez plusieurs classes ou méthodes.
- Java JDK (avec java et javac)
- Jasmin.jar, téléchargeable ici : Jasmin GitHub
Étapes de base pour écrire et exécuter un fichier Jasmin
Écrire le fichier .j (Hello.j) :
- .class public Hello
- .super java/lang/Object
-
- .method public static main([Ljava/lang/String;)V
- .limit stack 2
- .limit locals 1
-
- getstatic java/lang/System/out Ljava/io/PrintStream;
- ldc "Bonjour depuis Jasmin !"
- invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
- return
- .end method
Assembler le fichier en .class :
| java -jar jasmin.jar Hello.j |
Exécuter le fichier .class :
| java Hello |
Exemple Jasmin avec tableau d'objets
Voici un exemple créant un tableau de chaînes, stocke une valeur et la récupère :
- .class public ExempleTableau
- .super java/lang/Object
-
- .method public static main([Ljava/lang/String;)V
- .limit stack 5
- .limit locals 2
-
- iconst_3
- anewarray java/lang/String
- astore_1 ; tableau -> variable 1
-
- aload_1
- iconst_0
- ldc "Salut"
- aastore ; tableau[0] = "Salut"
-
- aload_1
- iconst_0
- aaload ; empile tableau[0]
- getstatic java/lang/System/out Ljava/io/PrintStream;
- swap
- invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
-
- return
- .end method
Instructions de manipulation de la pile
Voici un tableau listant les instructions de manipulation de la pile dans le langage Jasmin (assembleur pour bytecode Java). Ces instructions permettent de gérer les éléments empilés et dépilés dans la pile d'opérandes de la JVM, essentielle pour les calculs et les transferts de données :
| Instruction / Directive | Description |
|---|---|
| pop | Retire (dépile) le sommet de la pile (valeur de 1 mot : int, float, référence,...). |
| pop2 | Retire les deux mots du sommet de la pile (utilisé pour long ou double, ou deux valeurs simples). |
| dup | Duplique la valeur au sommet de la pile. |
| dup_x1 | Duplique la valeur au sommet et l'insère deux positions plus bas. |
| dup_x2 | Duplique la valeur au sommet et l'insère trois positions plus bas. |
| dup2 | Duplique les deux mots du sommet de la pile (pour long, double, ou deux valeurs simples). |
| dup2_x1 | Duplique les deux mots du sommet et les insère deux ou trois positions plus bas. |
| dup2_x2 | Duplique les deux mots du sommet et les insère trois ou quatre positions plus bas. |
| swap | Échange les deux éléments au sommet de la pile (valeurs de 1 mot). |
Exemple simple de manipulation de pile :
- iconst_1 ; empile 1
- iconst_2 ; empile 2
- swap ; échange 1 et 2 -> pile: 1, 2 devient 2, 1
- pop ; retire 1 -> pile: 2
Ces instructions sont cruciales pour manipuler l'ordre des éléments sans utiliser de variables locales.
Instructions arithmétiques
Voici un tableau listant les instructions arithmétiques du langage Jasmin (langage assembleur pour bytecode Java), regroupées par types de données (entiers, flottants,...). Ces instructions effectuent des opérations de base comme l'addition, la soustraction, la multiplication,...
| Instruction / Directive | Description |
|---|---|
| iadd | Additionne deux entiers (int). |
| isub | Soustrait deux entiers (int). |
| imul | Multiplie deux entiers (int). |
| idiv | Divise deux entiers (int). |
| irem | Reste de la division entière (int). |
| ineg | Négation d'un entier (change le signe). |
| ladd | Additionne deux longs (long). |
| lsub | Soustrait deux longs (long). |
| lmul | Multiplie deux longs (long). |
| ldiv | Divise deux longs (long). |
| lrem | Reste de division (long). |
| lneg | Négation d'un long. |
| fadd | Additionne deux réels (float). |
| fsub | Soustrait deux réels (float). |
| fmul | Multiplie deux réels (float). |
| fdiv | Divise deux réels (float). |
| frem | Reste de division réelle (float). |
| fneg | Négation d'un réel (float). |
| dadd | Additionne deux doubles (double). |
| dsub | Soustrait deux doubles (double). |
| dmul | Multiplie deux doubles (double). |
| ddiv | Divise deux doubles (double). |
| drem | Reste de division (double). |
| dneg | Négation d'un double. |
| iinc | Incrémente une variable locale entière de n (exemple : iinc 1 3 ? ajoute 3 à la variable locale 1). |
Exemple simple avec des entiers :
- iconst_4 ; empile 4
- iconst_2 ; empile 2
- iadd ; addition -> résultat 6 sur la pile
Instructions de comparaison et de branchement
Voici un tableau des instructions de comparaison et de branchement dans le langage Jasmin. Ces instructions permettent de comparer des valeurs et de modifier le flux d'exécution en fonction des résultats des comparaisons, souvent en sautant à des étiquettes spécifiques dans le code.
| Instruction / Directive | Description |
|---|---|
| ifeq | Si la valeur au sommet de la pile est égale à zéro, effectue un saut vers l'étiquette spécifiée. |
| ifne | Si la valeur au sommet de la pile n'est pas égale à zéro, effectue un saut vers l'étiquette spécifiée. |
| iflt | Si la valeur au sommet de la pile est inférieure à zéro, effectue un saut vers l'étiquette spécifiée. |
| ifge | Si la valeur au sommet de la pile est supérieure ou égale à zéro, effectue un saut vers l'étiquette spécifiée. |
| ifgt | Si la valeur au sommet de la pile est supérieure à zéro, effectue un saut vers l'étiquette spécifiée. |
| ifle | Si la valeur au sommet de la pile est inférieure ou égale à zéro, effectue un saut vers l'étiquette spécifiée. |
| icmp | Compare deux entiers sur la pile et empile le résultat (0 si égal, -1 si inférieur, 1 si supérieur). |
| icmpeq | Compare deux entiers et effectue un saut si les deux sont égaux. |
| icmpne | Compare deux entiers et effectue un saut si les deux ne sont pas égaux. |
| icmplt | Compare deux entiers et effectue un saut si le premier est inférieur au second. |
| icmpge | Compare deux entiers et effectue un saut si le premier est supérieur ou égal au second. |
| icmpgt | Compare deux entiers et effectue un saut si le premier est supérieur au second. |
| icmple | Compare deux entiers et effectue un saut si le premier est inférieur ou égal au second. |
| fcmpg | Compare deux flottants (avec gestion de NaN) et empile un entier qui indique le résultat de la comparaison. |
| fcmpl | Compare deux flottants (avec gestion de NaN) et empile un entier qui indique le résultat de la comparaison. |
| fcmpeq | Compare deux flottants et effectue un saut si les deux sont égaux. |
| fcmpne | Compare deux flottants et effectue un saut si les deux ne sont pas égaux. |
| fcmplt | Compare deux flottants et effectue un saut si le premier est inférieur au second. |
| fcmpge | Compare deux flottants et effectue un saut si le premier est supérieur ou égal au second. |
| fcmpgt | Compare deux flottants et effectue un saut si le premier est supérieur au second. |
| fcmple | Compare deux flottants et effectue un saut si le premier est inférieur ou égal au second. |
| dcmpl | Compare deux doubles (avec gestion de NaN) et empile un entier qui indique le résultat de la comparaison. |
| dcmpg | Compare deux doubles (avec gestion de NaN) et empile un entier qui indique le résultat de la comparaison. |
| dcmpneq | Compare deux doubles et effectue un saut si les deux ne sont pas égaux. |
| dcmpgt | Compare deux doubles et effectue un saut si le premier est supérieur au second. |
| dcmpge | Compare deux doubles et effectue un saut si le premier est supérieur ou égal au second. |
| dcmplt | Compare deux doubles et effectue un saut si le premier est inférieur au second. |
Exemple simple avec comparaison d'entiers :
- iconst_5 ; empile 5
- iconst_3 ; empile 3
- isub ; soustrait -> résultat 2
- iflt Label1 ; si résultat < 0, saute à Label1
- iconst_1 ; empile 1 (exécution continue)
- Label1:
- iconst_2 ; empile 2
Ces instructions sont essentielles pour les structures conditionnelles et les boucles dans Jasmin, car elles permettent de contrôler le flux de programme en fonction des résultats de comparaisons entre les éléments de la pile.
Instructions d'accès aux objets et aux champs
Voici un tableau des instructions d'accès aux objets et aux champs dans le langage Jasmin. Ces instructions permettent de manipuler les objets Java et leurs champs dans le bytecode. Elles sont essentielles pour accéder, modifier ou manipuler des objets et leurs attributs (champs) à partir du bytecode Jasmin.
| Instruction / Directive | Description |
|---|---|
| getfield | Accède à un champ d'instance d'un objet. Le champ est récupéré et empilé dans la pile. |
| putfield | Modifie un champ d'instance d'un objet avec la valeur au sommet de la pile. |
| getstatic | Accède à un champ statique d'une classe (n'est pas lié à un objet). Le champ est récupéré et empilé dans la pile. |
| putstatic | Modifie un champ statique d'une classe avec la valeur au sommet de la pile. |
| aload | Récupère une référence d'objet à partir d'une variable locale et l'empile. |
| astore | Entrepose une référence d'objet depuis la pile dans une variable locale. |
| new | Crée une nouvelle instance d'un objet (alloue de la mémoire) et empile la référence à cet objet. |
| newarray | Crée un tableau de types primitifs (exemple int, float,...) et empile la référence au tableau. |
| anewarray | Crée un tableau d'objets et empile la référence à ce tableau. |
| checkcast | Effectue un test de type, vérifie si l'objet au sommet de la pile peut être casté dans le type spécifié. Si ce n'est pas possible, une exception est lancée. |
| instanceof | Vérifie si l'objet au sommet de la pile est une instance du type spécifié. Le résultat est empilé. |
Exemple d'utilisation :
- new MyClass ; Crée une nouvelle instance de MyClass
- dup ; Duplique l'objet (nécessaire avant d'appeler un constructeur)
- invokespecial MyClass/<init>()V ; Appelle le constructeur de MyClass
-
- astore_1 ; Stocke la référence de l'objet dans la variable locale 1
- aload_1 ; Charge la référence de l'objet de la variable locale 1
- getfield MyClass/fieldName I ; Accède au champ 'fieldName' de MyClass
Dans cet exemple, nous créons un objet de type MyClass, puis nous accédons à son champ fieldName après l'avoir stocké dans une variable locale.
Ces instructions sont cruciales pour manipuler les objets Java dans Jasmin, et leur utilisation est essentielle pour les applications nécessitant de la manipulation d'objets et de champs à bas niveau dans le bytecode.
Instructions de gestion d'exception
Voici un tableau récapitulatif des instructions de gestion d'exception dans le langage de programmation Jasmin (bytecode Java). Jasmin ne dispose pas d'un grand nombre d'instructions spécifiques aux exceptions, car une grande partie de la gestion se fait via des directives Jasmin plutôt que des instructions JVM classiques. Cela dit, voici les principales utilisées dans ce contexte :
| Instruction / Directive | Description |
|---|---|
| .catch | Directive Jasmin utilisée pour définir une clause try/catch. Elle associe un type d'exception à une intervalle de code protégée et une étiquette de gestion. |
| .catchall | Variante de .catch qui intercepte toutes les exceptions (Throwable). Elle permet de définir une clause de type finally. |
| athrow | Instruction permettant de lancer une exception. Elle extrait une référence d'objet Throwable de la pile et interrompt l'exécution pour passer au gestionnaire d'exceptions. |