Ce didacticiel est destiné aux nouveaux utilisateurs de la Simple Virtual Machine.
Dans ce didacticiel, vous allez utiliser les pointeurs comme des tableaux.
Le temps de lecture de ce didacticiel est estimé à 20 minutes si les adresses mémoire et les pointeurs ont déjà été abordés.
Pour commencer, créez le canevas de l'application dans le fichier exécutable tableau.svm en utilisant ce code :
#!/usr/bin/env svm
DESCRIPTION
Array example
END
LOG
DEBUG "Array" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmint.so"
PLUGIN "svmstr.so"
OPTION -s MULTIPLE STR array
PROCESS "application"
CODE "main" INLINE
:debug BREAK
END
MEMORY array
END
Lancez l'application en mode débugueur avec ces options :
./tableau.svm -s a -s b -s c -s d -s e -d 8080
Puis ouvrez le débugueur et affichez la mémoire. Enfin, mettez en surbrillance la zone mémoire du pointeur "array" :
Le pointeur lié à l'alias "array" permet, comme vu précédemment, de référencer plusieurs valeurs.
Ces valeurs sont placées dans la mémoire à des adresses contigües et peuvent être vues comme des valeurs mises dans un tableau. En effet :
L'interêt principal d'un tableau est de pouvoir facilement appliquer les mêmes opérations sur toutes les valeurs d'un tableau.
La première étape consiste à créer une adresse avec un entier, qui servira d'indice dans le tableau. Pour cela, ajoutez ce code :
#!/usr/bin/env svm
DESCRIPTION
Array example
END
LOG
DEBUG "Array" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmint.so"
PLUGIN "svmstr.so"
OPTION -s MULTIPLE STR array
PROCESS "application"
CODE "main" INLINE
:memory INT/index
0 -> &index
:debug BREAK
:com.message @(array/@&index)
END
MEMORY array
END
L'application ainsi modifiée peut être lancée avec les mêmes options sans le débugueur :
./tableau.svm -s a -s b -s c -s d -s e
Elle affiche alors :
a
Si vous la lancez dans le débugueur, vous devez voir dans la mémoire l'alias "index" défini avec sa première adresse ayant la valeur 0. Ainsi, l'application a lu la première valeur du tableau "array".
Pour modifier l'indice, modifiez le code pour obtenir :
#!/usr/bin/env svm
DESCRIPTION
Array example
END
LOG
DEBUG "Array" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmint.so"
PLUGIN "svmstr.so"
OPTION -s MULTIPLE STR array
PROCESS "application"
CODE "main" INLINE
:memory INT/index
0 -> &index
:debug BREAK
:com.message @(array/@&index)
:shift &index
:com.message @(array/@&index)
END
MEMORY array
END
Une fois lancée, l'application toujours lancée avec les mêmes options affiche :
a
b
Cette fois, les deux premières valeurs du tableau ont été affichées par deux instructions rigoureusement identiques.
L'instruction :shift
est celle qui modifie l'indice du tableau, en ajoutant 1 à l'entier stocké en mémoire à l'adresse &index
.
L'instruction :shift
modifie un entier stocké en mémoire, en indiquant à quelle adresse il se trouve.
:shift valeur adresse
.Si on tient à parcourir tout le tableau en s'adaptant à sa taille avec le même code, il faut inclure un saut. Modifiez le code :
#!/usr/bin/env svm
DESCRIPTION
Array example
END
LOG
DEBUG "Array" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmint.so"
PLUGIN "svmstr.so"
OPTION -s MULTIPLE STR array
PROCESS "application"
CODE "main" INLINE
:memory INT/index
0 -> &index
:debug BREAK
:label array
:com.message @(array/@&index)
:shift &index
:goto array
END
MEMORY array
END
Et relancez une nouvelle fois (en mode débugueur à votre convenance) avec les mêmes options. On obtient :
a
b
c
d
e
### Simple Virtual Machine 1234 : PROCESS application | 2023-01-01 00:00:00 GMT ######################################################################
Kernel interrupted: @(main, line 5) Interruption MEMORY not handled: Index 5 is outside pointer &0*5.
Core dump:
Kernel:
State: I, transmit_interruption, interrupted @(main, line 5) Interruption MEMORY not handled: Index 5 is outside pointer &0*5.
Processor:
State:
Next instruction: <main:1/4> (Current one: <main:1/3>)
Current memory : &0*0
Allocated memory: &5*1
Aliases : index
Flags :
Cascaded flags :
Local interruption handlers:
Cascaded local interruption handlers:
Saved states:
Global interruption handlers:
Code at <main:1/3>:
:memory INT/index # <0> @(main, line 1)
0 -> &index # <1> @(main, line 2)
:debug BREAK # <2> @(main, line 3)
:label array
====== HERE ======
:com.message @(array/@&index) # <3> @(main, line 5)
==================
:shift &index # <4> @(main, line 6)
:goto array # <5> @(main, line 7)
Labels:
array -> <3>
Symbols:
Memory:
&0: STR "a"
&1: STR "b"
&2: STR "c"
&3: STR "d"
&4: STR "e"
&5: INT 5
Aliases:
array -> &0*5
index -> &5*1
Free space:
### Simple Virtual Machine 1234 : SYSTEM | 2023-01-01 00:00:00 GMT ###################################################################################
Process application interrupted: @(main, line 5) Interruption MEMORY not handled: Index 5 is outside pointer &0*5.
Au début, chaque valeur du tableau est bien écrite sur une ligne. Seulement, on obtient également à la fin une erreur. En effet, on boucle indéfiniment en augmentant l'indice et il finit par désigner une adresse qui se trouve hors du tableau : il faut pouvoir s'arrêter avant.
Modifiez le code ainsi :
#!/usr/bin/env svm
DESCRIPTION
Array example
END
LOG
DEBUG "Array" STYLE "default"
PLUGIN "svmcom.so"
PLUGIN "svmint.so"
PLUGIN "svmstr.so"
OPTION -s MULTIPLE STR array
PROCESS "application"
CODE "main" INLINE
:memory INT/index
0 -> &index
:debug BREAK
:label array
:com.message @(array/@&index)
:shift &index
:goto array :when @&index IN array
END
MEMORY array
END
Relancez une dernière fois l'application avec les mêmes options. Cette fois, on obtient :
a
b
c
d
e
Ce que vous venez d'ajouter au code rend l'instruction de saut conditionnelle : elle s'exécute tant que la condition ajoutée est vraie.
:when
suivi d'une condition :
:when
par :unless
.indice IN pointeur
est vraie si l'indice est entre zéro et la taille du pointeur moins un. Cela signifie que l'opérateur (pointeur/indice)
ne génèrera pas d'erreur.Vous venez de voir comment utiliser un pointeur de la machine virtuelle comme tableau de valeurs.
Les outils d'incrémentation et de saut conditionnel permettent de réaliser le même traitement sur toutes les valeurs d'un pointeur.