4IM sous DOSEMU - Opérations avec la mémoire

Rappel : le texte cité depuis le tutoriel d'Astrobe, est reproduit en bleu.
Ce site se trouve à l'adresse : http://membres.lycos.fr/astrobe/

1. Intro

Taille des zones identifiables dans la mémoire

4IM connaît des cases mémoire de deux tailles :

Opérateurs manipulant des informations dans la mémoire

Reprenons le texte d'Astrobe.
Nous avons donc 2 opérations - lecture et écriture - et deux "tailles" - caractère et cellule - donc 4 primitives :
Opération/taille lire écrire
sur un octet C@ ( a -- c ) C! ( c a -- )
sur une cellule @ ( a -- n ) ! ( n a -- )
On a vu que les piles étaient des piles de "taille cellules"; le système convertit de lui-même les caractères en cellules ( qui peut le plus peut le moins ).

Obtenir une adresse en mémoire

La théorie

Maintenant, comment obtient-on une adresse mémoire - car il ne faut pas écrire n'importe où!
L'un des moyens en 4IM est le mot HERE:.
Comme la présence du deux-points dans son nom l'indique, il sert à définir un mot:

HERE: VAR

... permet de créer le mot VAR, qui, quand on l'appelle, renvoit l'adresse de la case mémoire qui le suit.
Il y a une petite chose à faire en plus cependant pour avoir une variable: il faut réserver la cellule suivante, sinon elle sera utilisée par la prochaine définition.
On le fait avec le mot , ( virgule; "C," pour réserver un caractère ).

HERE: VAR 0 , ( n -- )
réserve la prochaine adresse libre dans le dictionnaire et y écrit la valeur n.
Dans l'exemple, on a mis zero.

La pratique

Exercice 1

Objectif : créer la variable VAR et y ranger un zéro.
HERE: VAR 0 ,
Vérification dans 4IM :
HERE: VAR 0 ,
Ready

Exercice 2

Objectif : récupérer le nombre rangé dans la variable VAR et l'afficher.
Cela peut s'écrire en une seule ligne :
VAR @ ?
ou par étape. C'est la cas choisi ici, capturé depuis la console de 4IM :
VAR
Ready
@
Ready
?
0 Ready

Exercice 3

Objectif : ranger le nombre 15 dans la variable VAR puis afficher le contenu de cette variable.
Première ligne :
15 VAR !
Seconde ligne :
VAR @ ?
Vérification sur 4IM, capturée depuis la console :
15 VAR !
Ready
VAR @ ?
15 Ready

Réserver plusieurs cases en mémoire

Ce que l'on sait déjà faire

HERE: PUISS2 0 , 1 , 2 , 4 , 8 , 16 ,
Au fait, pourquoi ce nom "HERE:"? "HERE" est le nom d'une variable du système qui mémorise la prochaine adresse libre ( non réservée ) du dictionnaire.

Une autre manière

Il existe d'autres mots pour réserver des cases mémoire, et en particulier
ALLOT ( n -- )
qui réserve non pas une, mais n adresses mémoire.
Voilà pourquoi HERE: ne fait pas la réservation automatiquement:
HERE: TAB 10 ALLOT
... crée une variable de 10 caractères de long, qu'on appelle plus communément un tableau. la valeur dans chacune des cases est indéfinie, puisqu'on y a rien écrit.
En fait, un mot comme ALLOT ne fait rien d'autre qu'ajouter son paramètre à la variable HERE.

Lire le contenu d'un tableau

Occupons-nous de notre tableau des puissances de deux:
PUISS2 @ ? ( affiche 0 )
Mais comment accéder aux autres cases?
On sait que pour 4IM une cellule prends 2 adresses donc il faut ajouter 2 à l'adresse de départ:

PUISS2 2 + @ ? ( affiche 1 )

Toutefois, " 2 + " n'est pas très lisible; de plus c'est dépendant du système: ça ne marchera plus si je crée une version de 4IM qui exploite vraiment les 32 bits du Pentium ( 1 cellule = 4 adresses ).
Il existe des mots pour résoudre cela:
PUISS2 5 CELLS + @ ? ( affiche 16 )
CELLS convertit un nombre de cellules en un nombre d'adresses. Actuellement il est défini par :
: CELLS 2 * .

mais si on travaille un jour en 32 bits il suffira que je le change en :
: CELLS 2* 2* .
Il existe un autre mot pour les cellules :
PUISS2 CELL+ @ ? ( affiche 1 )
CELL+ ajoute une taille de cellule à l'adresse qu'on lui donne
: CELL+ 2 + .

Avant que tout cela devienne trop abstrait, effectuons quelques exercices pratiques sur la console 4IM

Exercice 4

Objectif : créer le tableau des puissances donné en exemple.
En une seule ligne :
HERE: PUISS2 0 , 1 , 2 , 4 , 8 , 16 ,

Exercice 5

Objectif : afficher successivement les valeurs du tableau.
Nous allons utiliser successivement toutes les méthodes.

La première :
PUISS2 @ ?
0 Ready
PUISS2 2 + ?
5180 Ready
PUISS2 2 + @ ?
1 Ready
PUISS2 4 + @ ?
2 Ready
PUISS2 6 + @ ?
4 Ready
PUISS2 8 + @ ?
8 Ready
PUISS2 10 + @
? 16 Ready

La seconde :
PUISS2 @ ?
0 Ready
PUISS2 1 CELLS + @ ?
1 Ready
PUISS2 1 CELLS + @ ?
1 Ready
PUISS2 2 CELLS + @ ?
2 Ready
PUISS2 3 CELLS + @ ?
4 Ready
PUISS2 4 CELLS + @ ?
8 Ready
PUISS2 5 CELLS + @ ?
16 Ready

Pas vraiment une partie de plaisir !

Essayons avec CELL+ :
PUISS2 @ ?
0 Ready
PUISS2 CELL+ @ ?
1 Ready
PUISS2 CELL+ @ ?
1 Ready

Le résultat était prévisible,en réfléchissant sur ce qui était écrit.

Variables d'une seule cellule

A coté de HERE: existe un mot spécifiquement adapté aux variables d'une cellule : VALUE:

0 VALUE: VAR

VALUE: définit le mot VAR, réserve une cellule et l'initialise avec la valeur sur la pile ( 0 ici ).
La différence d'avec HERE: est que VAR ne retourne pas une adresse de cellule, mais directement le contenu de la cellule qui a été réservée.
VALUE: est particulièrement indiqué quand on lit une cellule mémoire plus souvent qu'on ne l'écrit.

Exemple

12 VALUE: VAR
Ready
VAR ?
12 Ready

Mais a propos, comment on écrit une valeur dans ce type de variable?

10 AT VAR !

Le mot AT permet de déterminer l'adresse réservée au mot qui le suit. Son utilité n'est pas exclusivement lié à VALUE: ; en fait, HERE: et VALUE: dérivent d'une primitive qui s'appelle WITH: qui est décrite plus loin.
Grosso modo, WITH: permet d'associer à la mémoire que l'on réserve à une procédure qui l'exploite.

Voilà pour l'essentiel. Il existe d'autres mots pour travailler avec la mémoire. Ce sont TO, XCHG et +!. Vous trouverez leur fonction dans le glossaire. Ils permettent d'écrire de manière plus courte certaines opérations frequemment utilisées.



A suivre...