Using kForth



2.9 Using Memory

Data Types

Earlier, in section 2.4, we learned how to create named integer and floating point variables using VARIABLE and FVARIABLE. These words define new words, which when executed, return the starting location (address) of the memory region containing their value. Different data types such as integers and floating point numbers require different amounts of memory for storing their values, and the words VARIABLE and FVARIABLE automatically reserve (ALLOT) the appropriate sized region.

In addition to the VARIABLE and FVARIABLE data types, Forth also provides 2VARIABLE for a double length integer. Thus, VARIABLE will allot one cell (typically 4 bytes on a 32-bit system) and 2VARIABLE will allot two cells of memory. To find out how many bytes of memory represent one cell in a Forth system, type

1 cells .


We would use 2VARIABLEs, for example, when we want to store integer numbers that are too large, or will become too large in the course of executing our program, to be represented by single length VARIABLEs.

CREATE and ALLOT

In writing our own Forth programs, we may need to store and retrieve data of different size than the sizes given by the data types discussed above. Examples are a paragraph of text, or an array of integers. How do we go about reserving memory for, say, 100 single length integers? In addition to reserving the memory, we need to assign a name with which to refer to the memory region. These tasks are accomplished through the use of the words CREATE and ALLOT:

CREATE iarray 100 CELLS ALLOT


The above statement will create a new word in the dictionary, called iarray, and reserve 100 cells (400 bytes on a 32-bit system). Executing the word iarray will return the starting address of the memory region. The words CREATE and ALLOT are, in fact, primitive Forth words which may be used to define words such as VARIABLE, e.g.
: VAR CREATE 1 CELLS ALLOT ;

Example 3:Initializing and Printing an Array of Integers

In our example above, we reserved a memory region of 100 cells in size using ALLOT. Simply alloting this memory does not specify what is initally stored in this region. We might need to set the initial values of the 100 integers in iarray before using it in our computation. A word to set all of the 100 integers to zero could be defined in the following way.

: init-iarray ( -- | initialize iarray to zeros)
     iarray  100 0 DO  0 over ! cell+  LOOP  drop ;

Study the above example to see how the word performs the action of storing a zero in each of the 100 cells. You may look up the action of the word CELL+ in the dictionary. A word to print the 100 integers stored in iarray may be defined as follows.
: print-iarray ( -- )
     cr  iarray  
     100 0 DO  
       dup @  
       6 .R  i 1+ 8 mod 0= IF cr THEN   \ nice output formatting
       cell+
     LOOP  drop ;

Forth also provides the words, FILL, BLANK, and ERASE, to set all of the bytes in a memory region to a single byte value. Using ERASE, init-iarray may also be defined as

: init-iarray ( -- ) iarray 100 cells erase ;


As an exercise, try modifying our first definition of init-iarray so that it stores a running count from 1 to 100 in iarray, instead of initializing all the values to zero. The following output should be produced by print-iarray.
print-iarray

     1     2     3     4     5     6     7     8
     9    10    11    12    13    14    15    16
    17    18    19    20    21    22    23    24
    25    26    27    28    29    30    31    32
    33    34    35    36    37    38    39    40
    41    42    43    44    45    46    47    48
    49    50    51    52    53    54    55    56
    57    58    59    60    61    62    63    64
    65    66    67    68    69    70    71    72
    73    74    75    76    77    78    79    80
    81    82    83    84    85    86    87    88
    89    90    91    92    93    94    95    96
    97    98    99   100 ok

Viewing Memory with DUMP

In some applications, particularly those involving sending and receiving data between the computer and another device, it is often very useful to be able to view the individual bytes stored in a region of memory. Forth provides the word DUMP to allow the user to view the individual byte contents of a memory region. In kForth, the word DUMP is provided as a source definition, that is, a word defined using more primitive Forth words, within the file dump.4th. To use the word DUMP, we must first include this file with

include dump


Then, typing IARRAY 64 DUMP should output something like
134969216 :  01  00  00  00  02  00  00  00  03  00  00  00  04  00  00  00  ................
134969232 :  05  00  00  00  06  00  00  00  07  00  00  00  08  00  00  00  ................
134969248 :  09  00  00  00  0A  00  00  00  0B  00  00  00  0C  00  00  00  ................
134969264 :  0D  00  00  00  0E  00  00  00  0F  00  00  00  10  00  00  00  ................ ok
At first glance, the above output does not seem too useful; however, if we look closely, the data stored previously in iarray may be seen --- the running count starting from one can be seen in the successive groups of four bytes. Also, DUMP displays the individual bytes in base 16, or hexadecimal. This is not immediately apparent, until we see that the number 10 in iarray is displayed as the four-byte sequence " 0A 00 00 00 " Engineers trying to debug programs communicating with hardware usually find "hex" output to be more useful than the ordinary decimal representation because they can visualize the bit-pattern represented by each hex character.

DUMP also shows the address of the first byte of each line on the left hand side, and shows additional characters on the right hand side. When the bytes in memory represent printable characters, also known as ASCII codes, the corresponding character is displayed on the right hand side. To see this, try IARRAY 64 CELLS + 128 DUMP. The following output will be shown by DUMP:

134969472 :  41  00  00  00  42  00  00  00  43  00  00  00  44  00  00  00  A...B...C...D...
134969488 :  45  00  00  00  46  00  00  00  47  00  00  00  48  00  00  00  E...F...G...H...
134969504 :  49  00  00  00  4A  00  00  00  4B  00  00  00  4C  00  00  00  I...J...K...L...
134969520 :  4D  00  00  00  4E  00  00  00  4F  00  00  00  50  00  00  00  M...N...O...P...
134969536 :  51  00  00  00  52  00  00  00  53  00  00  00  54  00  00  00  Q...R...S...T...
134969552 :  55  00  00  00  56  00  00  00  57  00  00  00  58  00  00  00  U...V...W...X...
134969568 :  59  00  00  00  5A  00  00  00  5B  00  00  00  5C  00  00  00  Y...Z...[...\...
134969584 :  5D  00  00  00  5E  00  00  00  5F  00  00  00  60  00  00  00  ]...^..._...`... ok