0
votes

If I need to copy some memory of a given size, is there a typical Forth word to do this? Something like C's memcpy or memmove?

1

1 Answers

3
votes

Copying memory

The Forth standard defines MOVE in the Core word set, for copying arbitrary memory:

MOVE ( addr1 addr2 u -- )
If u is greater than zero, copy the contents of u consecutive address units at addr1 to the u consecutive address units at addr2. After MOVE completes, the u consecutive address units at addr2 contain exactly what the u consecutive address units at addr1 contained before the move.

Like memmove, MOVE allows the source and destination to overlap, as if the copy had happened using an intermediate buffer.

Propagating strings

The Forth standard also defines CMOVE and CMOVE> in the String word set:

CMOVE ( c-addr1 c-addr2 u -- )
If u is greater than zero, copy u consecutive characters from the data space starting at c-addr1 to that starting at c-addr2, proceeding character-by-character from lower addresses to higher addresses.

CMOVE> ( c-addr1 c-addr2 u -- )
If u is greater than zero, copy u consecutive characters from the data space starting at c-addr1 to that starting at c-addr2, proceeding character-by-character from higher addresses to lower addresses.

CMOVE and CMOVE> copy characters one-by-one, in order, beginning at the start and end of the strings respectively.

MOVE is already capable of copying strings safely (using CHARS for full compliance with the standard). But CMOVE and CMOVE> can be used to repeat portions of a string easily, or implement algorithms similar to LZ77 decompression. This is known as propagation. For example:

\ Allocate space for a string, starting with AB
CREATE str  'A' C, 'B' C, 18 CHARS ALLOT

str 2 TYPE  \ prints AB

\ Use CMOVE to propagate AB over rest of string
str  str 2 CHARS +  18  CMOVE

str 20 TYPE  \ prints ABABABABABABABABABAB

CMOVE> is also known as <CMOVE in older Forths.


There is a COPY word in some Forths for writing a block's contents over another block easily.