This section is about memory accesses useful for communicating with other software or other computers. This means that the accesses are of a certain bit width (independent of Gforth’s cell width), are possibly not naturally aligned and typically have a certain byte order that may be different from the native byte order of the system that Gforth runs on.
We use the following prefixes:
c
8 bits (character)
w
16 bits
l
32 bits
x
64 bits represented as one cell
xd
64 bits represented as two cells
The x
-prefix words do not work properly on 32-bit systems, so
for code that is intended to be portable to 32-bit systems you should
use xd
-prefix words. Note that xd
-prefix words work on
64-bit systems: there the upper cell is just 0 (for unsigned values)
or a sign extension of the lower cell.
The memory-access words below all work with arbitrarily (un)aligned
addresses (unlike @
, !
, f@
, f!
, which
require alignment on some hardware), and use native byte order (like
these words),
u is the zero-extended 16-bit value stored at c_addr.
Store the bottom 16 bits of w at c_addr.
u is the zero-extended 32-bit value stored at c_addr.
Store the bottom 32 bits of w at c_addr.
u is the zero-extended 64-bit value stored at c_addr.
Store the bottom 64 bits of w at c_addr.
ud is the zero-extended 64-bit value stored at c_addr.
Store the bottom 64 bits of ud at c_addr.
For accesses with a specific byte order, you have to perform byte-order adjustment immediately after a fetch (before the sign-extension), or immediately before the store. The results of these byte-order adjustment words are always zero-extended.
Convert 16-bit value in u1 from native byte order to big-endian or from big-endian to native byte order (the same operation)
Convert 16-bit value in u1 from native byte order to little-endian or from little-endian to native byte order (the same operation)
Convert 32-bit value in u1 from native byte order to big-endian or from big-endian to native byte order (the same operation)
Convert 32-bit value in u1 from native byte order to little-endian or from little-endian to native byte order (the same operation)
Convert 64-bit value in u1 from native byte order to big-endian or from big-endian to native byte order (the same operation)
Convert 64-bit value in u1 from native byte order to little-endian or from little-endian to native byte order (the same operation)
Convert 64-bit value in ud1 from native byte order to big-endian or from big-endian to native byte order (the same operation)
Convert 64-bit value in ud1 from native byte order to little-endian or from little-endian to native byte order (the same operation)
For signed fetches with a specific byte order, you have first have to perform an unsigned fetch and a byte-order correction, and finally use a sign-extension word:
Sign-extend the 8-bit value in x to cell n.
Sign-extend the 16-bit value in x to cell n.
Sign-extend the 32-bit value in x to cell n.
Sign-extend the 64-bit value in x to cell n.
Sign-extend the 64-bit value in xd to double-cell d.
Overall, this leads to sequences like
w@ wbe w>s \ 16-bit unaligned signed big-endian fetch >r lle r> l! \ 32-bit unaligned little-endian store