here . -- 291977
create four-char
create first-letter 1 allot
create second-letter 1 allot
create third-letter 1 allot
create fourth-letter 1 allot
here . -- 292013 \ bizarrely, 36 bytes have been used
\ for this four character array!
\ ... and the characters are non-contiguous
I'm not familiar with Win32Forth, but I think I'm correct in saying
that your assumption is incorrect :-) I'll try and explain why.
Assume an ITC system. All bets are off with native systems :-)
Firstly, when CREATE is used, HERE is pointing at the PFA (parameter
field address) of the created word:
CREATE FRED
Results in
CFA PFA
-----+-------+-----+
FRED | DOVAR | ??? |
-----+-------+-----+
^
HERE
CFA=Code Field Address (points to executable code (in this case
DOVAR).
PFA=Parameter Field Address (holds data that the word can work with).
Here is pointing to the cell directly after the cell that calls DOVAR.
The contents of the cell are effectively garbage/unknown, hence ???.
Now, a valid, legal use of CREATEd words is to "comma" or poke data (a
"payload", if you will) into the word. So, that then the CREATEd word
is executed, it can return some data:
CREATE TEN
10 ,
The word , (comma) takes whatever is on the stack and appends it into
the 'code stream' (for want of a better description). It uses HERE to
determine where it should go. It appends it, and updates HERE.
CREATE TEN
10 ,
Results in the following:
CFA PFA
-----+-------+-----+----
TEN | DOVAR | 10 |
-----+-------+-----+----
^
HERE
If you enter the above code and do:
TEN @ .
You'll get 10 displayed. Why? Because the default behaviour of a
CREATEd word is to behave like a variable. Variables leave an address
on the stack. Which address? Generally speaking (most Forths, I guess)
the address of the cell immediately following.
If you do the following:
CREATE TEN
CREATE TWO
You end up with the beginning of the definition (the dictionary entry)
of TWO sitting in the *data-space* (the PFA) of TEN:
CFA PFA CFA PFA
-----+-------+-----+-------+-----+
TEN | DOVAR | TWO | DOVAR | ??? |
-----+-------+-----+-------+-----+
^
HERE
Can you see that? The start of TWOs dictionary entry is sitting in the
data-space of TEN. Woops.
So, when using CREATE, you need to put something in the data-space,
either by comma-ing something in:
CREATE NINE 9 ,
Which gives:
CFA PFA
------+-------+-----+----
NINE | DOVAR | 9 | ???
------+-------+-----+----
^
HERE
Or by using allot:
CREATE TEMP 1 CELL ALLOT
Which gives:
CFA PFA
------+-------+-----+----
TEMP | DOVAR | ??? | ???
------+-------+-----+----
^
HERE
Using ALLOT results in un-initialised data-space. But that's okay,
since the default behaviour of CREATEd words is to return the address
of their data-space, we can get to it with ! :
99 TEMP !
Now there is 99 in TEMPs dataspace.
Obviously, we can have a bigger data space, not just one cell:
If we do this:
CREATE BUFF 4 CELLS ALLOT
: DOUBLE DUP + ;
We get:
CFA PFA
------+-------+-----+-----+-----+-----+--------+-----+---+
BUFF | DOVAR | ??? | ??? | ??? | ??? | DOUBLE | DUP | + |
------+-------+-----+-----+-----+-----+--------+-----+---+
^
HERE
I can fill BUFF with data like this:
: FILL-BUFF
100
BUFF 4 CELLS + BUFF DO
DUP I !
100 +
LOOP
DROP ;
Which gives us:
CFA PFA
------+-------+-----+-----+-----+-----+--------+-----+---+-----------
+-----
BUFF | DOVAR | 100 | 200 | 300 | 300 | DOUBLE | DUP | + | FILL-BUFF
| ...
------+-------+-----+-----+-----+-----+--------+-----+---+-----------
+-----
You get the idea. Note, the data-space (in fact the whole dictionary)
is not protected in any way. You're free to screw up in any way you
like! Taking the last example, if I did:
BUFF 150 99 FILL
I would fill the 150 bytes starting at BUFF with 99, which would write
over the definition of FILL-BUFF, and break the dictionary linkage
(probably) thus rendering the system brain-dead - it wouldn't be able
to find any words.
Hope this helps to give some insight.
Regards
Mark