Ce didacticiel est destiné aux nouveaux utilisateurs de la Simple Virtual Machine.
Dans ce didacticiel, vous allez exécuter du code importé.
Le temps de lecture de ce didacticiel est estimé à 15 minutes si l'écriture basique du code, les sauts et les fonctions ont été abordés.
Pour commencer, créez le canevas de l'application dans le fichier exécutable bibliotheques.svm en utilisant ce code :
#!/usr/bin/env svm
DESCRIPTION
Libraries example
END
LOG
DEBUG "Libraries" STYLE "default"
PLUGIN "svmcom.so"
PROCESS "application"
CODE "main" INLINE
:debug BREAK
:memory STR/source
""":com.message 1
:shutdown
:label l
:com.message 2
:return
:label s
:com.message 3
:return
""" -> &source
END
END
Observez le code fourni. La chaine de caractères définie dans le code a deux spécificités :
Modifiez le code pour obtenir :
#!/usr/bin/env svm
DESCRIPTION
Libraries example
END
LOG
DEBUG "Libraries" STYLE "default"
PLUGIN "svmcom.so"
PROCESS "application"
CODE "main" INLINE
:debug BREAK
:memory STR/source, LIB/library
""":com.message 1
:shutdown
:label l
:com.message 2
:return
:label s
:com.message 3
:return
""" -> &source
:library "lib" @&source -> &library
END
END
Lancez l'application en mode débugueur. La fenêtre mémoire à la fin de l'exécution contient :
La mémoire contient deux adresses. La première contient sans surprise la chaine avec le texte source.
La seconde est de type LIB
(pour "library" en anglais) et contient le code compilé de la bibliothèque. La valeur est représentée par le nom de la bibliothèque (donné en premier argument de l'instruction :library
) suivi d'un identifiant généré par la machine, le tout entre chevrons.
Prenez le contenu de la chaine et mettez le à part dans un fichier non exécutable lib.svm, puis modifiez le code :
#!/usr/bin/env svm
DESCRIPTION
Libraries example
END
LOG
DEBUG "Libraries" STYLE "default"
PLUGIN "svmcom.so"
PROCESS "application"
CODE "main" INLINE
:debug BREAK
:memory com.device/file, STR/source, LIB/library
:com.open com.file < "lib.svm" -> &file
:com.read @&file com.all -> &source
:library "lib" @&source -> &library
[ ] -> file
END
END
Lancez l'application en mode débugueur. A la fin de l'exécution du code, vous devez obtenir sensiblement la même fenêtre mémoire :
Cet extrait de code permet de morceler l'application en plusieurs fichiers, ou d'importer du code écrit par d'autres personnes.
:library chaine_nom_bibliotheque chaine_code_source
.Maintenant que l'on a la bibliothèque enregistrée dans la mémoire, il est temps d'appeller le code via un saut ou un appel de fonction.
Revenez au fichier précédent, puis modifiez le code pour obtenir :
#!/usr/bin/env svm
DESCRIPTION
Libraries example
END
LOG
DEBUG "Libraries" STYLE "default"
PLUGIN "svmcom.so"
PROCESS "application"
CODE "main" INLINE
:debug BREAK
:memory STR/source, LIB/library
""":com.message 1
:shutdown
:label l
:com.message 2
:return
:label s
:com.message 3
:return
""" -> &source
:library "lib" @&source -> &library
:call s P
END
END
Puis lancez l'application :
./bibliotheques.svm
Boot error: Process application has invalid code: @(main, line 13) Label s is not defined in code main.
Et cela ne fonctionne pas ! En effet, l'appel vers l'étiquette "s" ne peut aboutir que si elle est définie dans le code de base "main" et non dans le code compilé "lib". Pour atteindre le code contenu dans "lib", il faudra un nouveau concept : les symboles.
Modifiez le code :
#!/usr/bin/env svm
DESCRIPTION
Libraries example
END
LOG
DEBUG "Libraries" STYLE "default"
PLUGIN "svmcom.so"
PROCESS "application"
CODE "main" INLINE
:debug BREAK
:memory STR/source, LIB/library
""":com.message 1
:shutdown
:label l
:com.message 2
:return
:label s
:com.message 3
:return
""" -> &source
:library "lib" @&source -> &library
:call $(@&library/"s") P
END
END
Lancez l'application :
./bibliotheques.svm
### Simple Virtual Machine 1234 : PROCESS application | 2023-01-01 00:00:00 GMT ######################################################################
Kernel interrupted: @(main, line 13) Interruption FAILURE not handled: Symbol s is not defined in code lib.
Core dump:
Kernel:
State: I, transmit_interruption, interrupted @(main, line 13) Interruption FAILURE not handled: Symbol s is not defined in code lib.
Processor:
State:
Next instruction: <main:1/5> (Current one: <main:1/4>)
Current memory : &0*0
Allocated memory: &0*2
Aliases : library source
Flags :
Cascaded flags :
Local interruption handlers:
Cascaded local interruption handlers:
Saved states:
Global interruption handlers:
Code at <main:1/4>:
:debug BREAK # <0> @(main, line 1)
:memory STR/source , LIB/library # <1> @(main, line 2)
""":com.message 1\n\t\t :shutdown\n\t\t:label l\n\t\t :com.message 2\n\t\t :return\n\t\t:label s\n\t\t :com.message 3\n\t\t :return\n\t\t""" -> &source # <2> @(main, lines 3-11)
:library "lib" @&source -> &library # <3> @(main, line 12)
====== HERE ======
:call $(@&library/"s") P # <4> @(main, line 13)
==================
Labels:
Symbols:
Memory:
&0: STR ":com.message 1\n\t\t :shutdown\n\t\t:label l\n\t\t :com.message 2\n\t\t :return\n\t\t:label s\n\t\t :com.message 3\n\t\t :return\n\t\t"
&1: LIB <lib:2>
Aliases:
library -> &1*1
source -> &0*1
Free space:
### Simple Virtual Machine 1234 : SYSTEM | 2023-01-01 00:00:00 GMT ###################################################################################
Process application interrupted: @(main, line 13) Interruption FAILURE not handled: Symbol s is not defined in code lib.
La cible de l'appel a été modifiée et contient maintenant une référence sur le code de la bibliothèque et une étiquette de la bibliothèque.
Cependant, les étiquettes comme "l" et "s" dans une bibliothèque ne peuvent pas être appellées depuis une instruction placée dans un autre code que cette bibliothèque.
Modifiez le code pour changer "s" :
#!/usr/bin/env svm
DESCRIPTION
Libraries example
END
LOG
DEBUG "Libraries" STYLE "default"
PLUGIN "svmcom.so"
PROCESS "application"
CODE "main" INLINE
:debug BREAK
:memory STR/source, LIB/library
""":com.message 1
:shutdown
:label l
:com.message 2
:return
:symbol s
:com.message 3
:return
""" -> &source
:library "lib" @&source -> &library
:call $(@&library/"s") P
:goto $(@&library/)
END
END
Puis lancez l'application :
./bibliotheques.svm
3
1
Cette fois-ci, l'appel est bien réalisé. Le saut ajouté à la suite de l'appel fonctionne également, et exécute le code "lib" à partir de la première instruction.
Vous pouvez lancer l'application en mode débugueur. Lors de l'exécution de la fonction "s", les fenêtres du processeur et des codes ressemblent à :
Entre l'état du processeur et la pile de retour, vous retrouvez la référence aux deux codes "main" et "lib".
En jouant l'application instruction par instruction, vous pouvez constater comment l'exécution passe d'un code à l'autre.
:symbol nom_symbole
.$(bibliotheque/chaine_symbole)
pour atteindre un symbole nommé dans une bibliothèque donnée,$(bibliotheque/)
pour atteindre la première instruction de la bibliothèque donnée,$chaine_symbole
pour atteindre un symbole nommé du code courant.Vous venez de voir comment intégrer du code depuis plusieurs sources au sein d'une application.
Cette capacité de la machine permet de constituer des applications en intégrant des modules écrits en langage machine.
Dans certaines circonstances, cela permet aussi d'exécuter du code généré par du code.