Introduction

Ce didacticiel est destiné aux nouveaux utilisateurs de la Simple Virtual Machine.

Dans ce didacticiel, vous allez vous initier aux instructions de saut.

Le temps de lecture de ce didacticiel est estimé à 15 minutes si l'écriture d'une application simple a déjà été étudiée.

Mise en place

Pour commencer, créez le canevas de l'application dans le fichier exécutable sauts.svm en utilisant ce code :

#!/usr/bin/env svm
DESCRIPTION
Jump examples
END
LOG
DEBUG "Jumps" STYLE "default"
PLUGIN "svmcom.so"
ARGUMENT STR t
PROCESS "application"
	CODE "main" INLINE
		:debug BREAK
		:com.message 1
		:com.message 2
		:com.message 3
		:com.message 4
		:com.message 5
		:com.message 6
		:com.message 7
		:com.message 8
		:com.message 9
	END
	MEMORY t
END

L'instruction de saut

Pour commencer, placez une instruction de saut et une étiquette comme indiqué ci-dessous :

#!/usr/bin/env svm
DESCRIPTION
Jump examples
END
LOG
DEBUG "Jumps" STYLE "default"
PLUGIN "svmcom.so"
ARGUMENT STR t
PROCESS "application"
	CODE "main" INLINE
		:debug BREAK
		:com.message 1
		:com.message 2
		:goto skip
		:com.message 3
		:com.message 4
		:com.message 5
		:com.message 6
		:com.message 7
	:label skip
		:com.message 8
		:com.message 9
	END
	MEMORY t
END

Puis lancez l'application :

./sauts.svm a

Le résultat est :

1
2
8
9

Les instructions affichant les nombres de 3 à 7 n'ont tout simplement pas été exécutées.

L'instruction :goto altère le flot d'instructions, qui repart à l'instruction :label correspondante.

Un saut est composé d'une instruction :goto suivie d'un nom (source du saut), et d'une instruction :label suivie du même nom (destination du saut).

La destination du saut peut être placée avant ou après la source du saut, dans la même portion de code.

Types de saut

Saut local statique

Le saut précédent, indiqué par l'instruction :goto suivi d'un nom sans double-quotes, permet de faire un saut à une destination fixe au sein du même code.

Il s'agit du saut le plus rapide à l'exécution et doit être privilégié lorsque cela est possible.

Saut local dynamique

Modifiez le code pour obtenir :

#!/usr/bin/env svm
DESCRIPTION
Jump examples
END
LOG
DEBUG "Jumps" STYLE "default"
PLUGIN "svmcom.so"
ARGUMENT STR t
PROCESS "application"
	CODE "main" INLINE
		:debug BREAK
		:com.message 1
		:goto "skip"
		:com.message 2
	:label skip
		:com.message 3
		:goto @&t
	:label a
		:com.message 4
		:com.message 5
	:label b
		:com.message 6
		:com.message 7
	:label c
		:com.message 8
		:com.message 9
	END
	MEMORY t
END

Lancez maintenant l'application avec l'argument b 

./sauts.svm b

Le résultat est :

1
3
6
7
8
9

La première instruction de saut est ici suivie d'un nom entre double-quotes "skip" : dans ce cas, la résolution du saut est faite lors de l'exécution de l'instruction de saut.

Cela permet de réaliser un saut vers différentes destinations depuis la même instruction :goto, comme c'est le cas avec la seconde instruction de saut.

Ici, la destination de ce saut dépend de la valeur passée en argument de l'application et lue à travers le nom t.

Vous pouvez essayer avec les arguments a et c, puis essayez avec l'argument d :

1
3
### Simple Virtual Machine 1234 : PROCESS application | 2023-01-01 00:00:00 GMT ######################################################################
Kernel interrupted: @(main, line 7) Interruption FAILURE not handled: Label d is not defined in code main.

Core dump:
Kernel:
State: I, transmit_interruption, interrupted @(main, line 6) Interruption FAILURE not handled: Label d is not defined in code main.

Processor:
 State:
   Next instruction: <main:1/6> (Current one: <main:1/5>)
   Current memory  : &0*0
   Allocated memory:
   Aliases         :
   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)
     :com.message 1     # <1> @(main, line 2)
     :goto "skip"       # <2> @(main, line 3)
     :com.message 2     # <3> @(main, line 4)
  :label skip
     :com.message 3     # <4> @(main, line 6)
====== HERE ======
     :goto @&t  # <5> @(main, line 7)
==================
  :label a
     :com.message 4     # <6> @(main, line 9)
     :com.message 5     # <7> @(main, line 10)
  :label b
     :com.message 6     # <8> @(main, line 12)
     :com.message 7     # <9> @(main, line 13)
  :label c
     :com.message 8     # <10> @(main, line 15)
     :com.message 9     # <11> @(main, line 16)
 Labels:
  a -> <6>
  b -> <8>
  c -> <10>
  skip -> <4>
 Symbols:


Memory:
  &0: STR "d"
 Aliases:
  t -> &0*1
 Free space:



### Simple Virtual Machine 1234 : SYSTEM | 2023-01-01 00:00:00 GMT ###################################################################################
Process application interrupted: @(main, line 7) Interruption FAILURE not handled: Label d is not defined in code main.


Dans le cas où l'argument d est passé, la résolution de la destination du saut est faite avec un nom qui ne correspond à aucune étiquette dans le code. La résolution échoue, et une erreur est générée.

Il existe plusieurs types de saut :

Lorsque le choix est possible, il est toujours préférable d'utiliser un saut statique.

Conclusion

Vous venez de voir comment implémenter des sauts dans le code de la machine virtuelle.

De plus, les deux premiers types de saut ont été présentés dans ce didacticiel. Il existe un troisième type de saut (dit global) qui sera abordé plus tard.

Enfin, il est bon de remarquer que les sauts, employés seuls, ne sont pas très utiles. Il faudra les combiner avec d'autres notions pour qu'ils expriment tout leur potentiel. Ces notions seront abordées dans des didacticiels ultérieurs.