2017-07-29 7 views
3

En essayant de savoir comment Forth gère le dictionnaire (et la mémoire en général), je suis tombé sur la page this. Étant familier avec C, je n'ai aucun problème avec le concept de pointeurs, et je suppose que j'ai tout compris correctement. Cependant, à la fin de la page sont several exercises, et ici j'ai remarqué quelque chose d'étrange.Pourquoi Forth réserve-t-il deux cellules par variable?

exercice 9.4, en supposant DATE a été définie comme une VARIABLE, demande quelle est la différence entre

DATE . 

et

' DATE . 

et exercice 9,5 fait la même chose en utilisant l'utilisateur variable BASE. Selon les réponses fournies, les deux phrases donneront le même résultat (avec BASE). En essayant cela avec Win32Forth cependant, donne des résultats avec une différence de 4 octets (1 cellule). Voici ce que je faisais:

here . 4494668 ok 
variable x ok 
x . 4494672 ok 
' x . 4494668 ok 

Création d'une autre variable donne un résultat similaire:

variable y ok 
y . 4494680 ok 
' y . 4494676 ok 

Ainsi, il semble que chaque variable obtient non seulement une cellule (pour la valeur), mais deux cellules. La variable elle-même indique où la valeur réelle est stockée et la récupération du contenu au jeton d'exécution (en utilisant ' x ?) donne 0040101F pour les deux variables.

Pour exercice 9.5, mes résultats sont les suivants:

base . 195F90 ok 
' base . 40B418 ok 

Ce sont même pas proches les uns des autres. La réponse à cet exercice mentionne cependant que les résultats peuvent dépendre de la définition de BASE.

retour à des variables normales, ma question principale est donc: pourquoi sont deux cellules réservées par variable?

De plus:

  • Comme une seule cellule contient la valeur réelle, qu'est-ce que le contenu de l'autre cellule signifie?
  • Est-ce spécifique à Win32Forth? Que se passe-t-il dans d'autres implémentations?
  • Est-ce différent pour les variables d'exécution et de compilation?
  • Comment réponses aux questions ci-dessus appliquent aux variables utilisateur (telles que BASE)?

EDIT1: Ok, donc stocke également Forth un en-tête pour chaque variable, et en utilisant la ' vous donne l'adresse de cet en-tête. De mes tests, je conclurais alors que l'en-tête utilise une seule cellule, ce qui ne correspond pas à toutes les informations que l'en-tête devrait contenir.Deuxièmement, selon l'exercice de récupération de l'adresse d'une variable devrait dans les deux cas donner le même résultat, ce qui semble contredire l'existence d'un en-tête tout à fait. Mon sentiment est que tout cela est très spécifique à l'implémentation. Si oui, que se passe-t-il dans Win32Forth, et que devrait-il se passer en fonction de l'exercice?

+2

Il est beaucoup plus réservé. La plupart des mots Forth (y compris les variables) ont un en-tête complet, avec les champs pointant vers le mot précédent, vers le nom de la variable (et généralement ce nom est également stocké dans l'en-tête) vers le code exécuté lorsque la variable est référencé et à la cellule de données. Et puis il y a la cellule de données elle-même (ou plus d'une, en fonction de ce qui a été alloué lors de la création de la variable). Tick ​​('' ') retourne l'adresse du code qui est exécuté pour le mot qui suit. Cela peut même être différent pour le code interprété et pour le code compilé ... –

+1

... si vous référencez le mot, comme 'DATE' lui-même, le code de la variable met l'adresse de données sur la pile. Il y a donc une grande différence entre "DATE" et "DATE" lui-même. –

+0

https://forth-standard.org/standard/core/Tick. –

Répondre

3

Voici à peu près à quoi ressemble une définition dans le dictionnaire en utilisant une disposition de mémoire traditionnelle. Notez que les implémentations peuvent bien diverger, parfois beaucoup. En particulier, l'ordre des champs peut être différent.

Link to previous word (one cell) 
Flags (a few bits) 
Name length (one byte, less a few bits) 
Name string (variable) 
Code field (one cell) 
Parameter field (variable) 

Tout sauf les champs de code et de paramètre est considéré comme l'en-tête. Le champ de code vient généralement juste avant le champ de paramètre.

Cocher un mot avec ' vous donne un XT ou un jeton d'exécution. Cela peut être tout ce que l'implémentation a envie de faire, mais dans de nombreux cas, c'est l'adresse du champ de code.

L'exécution d'un mot créé avec CREATE ou VARIABLE vous donne l'adresse du champ de paramètre.

C'est probablement pourquoi dans Win32Forth, les deux adresses diffèrent de 4 octets, ou une cellule. Je ne sais pas pourquoi les réponses aux exercices indiquent qu'il ne devrait y avoir aucune différence.

En supposant que BASE est une variable utilisateur, cela fonctionne probablement comme ceci: Chaque tâche a sa propre zone utilisateur dans laquelle les variables utilisateur sont allouées. Toutes les variables utilisateur connaissent leur décalage spécifique dans cette zone. Cocher BASE vous donne son XT, qui est le même pour toutes les tâches. L'exécution BASE calcule une adresse en ajoutant son décalage à la base de la zone utilisateur.

+0

Il existe donc une méthode spécifiée pour que Forth gère les variables, mais le type exact de l'implémentation dépend de comment et où exactement. Merci pour la clarification! – Mattenii