# Accessing memory

## Alignment discipline

Some platforms that Dusk OS runs on (ARM) have restrictions with regards to
unaligned memory access: 16-bit memory access have to be done on even addresses
and 32-bit ones have to be done on addresses divisible by 4.

This imposes what we call an "alignment discipline" on all of Dusk OS' code.

The biggest unalignment source is already handled by the kernel: all new
dictionary entries are always created aligned. Therefore, whenever you use
"create" or "value" or other such words, you don't have to worry about whether
you're aligned.

However, in some cases, you do have to worry about alignment as an operator:
"here" is not always aligned! For example, starting from an aligned "here",
this code:

  ,"foo"

results in "here" becoming unaligned because 3 bytes were written.

This type of situations mostly arises in structs' [doc/lib/ns] ":new" methods,
but can arise in other contexts too.

Therefore, the general rule is that when you're about to access memory related
to here in 16-bit or 32-bit mode, you need to align "here". You can do so with
the "align4" word, but there's also the shortcut "here#" which aligns "here" and
then yield it.

Therefore, the general rule of thumb is: use "here#" instead of "here".

For structs, (which includes C structs), you have to arrange your fields
accordingly. By principle, no auto-alignment takes place on structures. The idea
is that looking at a structure's definition should always tell the reader the
exact structure without them having to second guess.

To help, there are alignment checks built in. When a structure's definition
results in misaligned fields, Dusk aborts with "alignment error".

## Endian-ness

In Dusk, memory accesses are done in the CPU's native endian-ness. For accessing
memory in arbitrary endian-ness, see [doc/mem/endian].

## Fancy storage in RS with []>r and friends

Forth programmers quickly get used to treating RS as storage using >r and r>.
This is especially true of recursive words, where RS is the best place to keep
execution state.

As long as what you need to keep around fits in 32, or maybe 64, bits,
everything is fine and dandy.

But what if it's a string? Then things get murky. You could use scratchpads
[mem/scratch] for this, but it's a bit hackish.

Dusk has a set of words for you:

  []>r  ( a u -- )
  r>[]  ( dst -- a u )
  str>r ( str -- )
  r>str ( dst -- str )

All of these words are immediate and compile code that store the specified range
of data directly in RS. To get that data back, you call the "mirror" word, but
there's a twist: we can't just use the RS address directly because as soon as
you begin working with that data, you'll corrupt it through regular RS usage!

Therefore, the "extractor" part needs a destination buffer to extract itself
into. The size of the buffer is kept in RS, so you don't need to remember it.
You only have to make sure that your destination buffer is big enough for
whatever can possibly come from there.
