Extended VM

At the Euroforth 2008 Stephen Pelc presented a paper http://www.complang.tuwien.ac.at/anton/euroforth/ef08/papers/pelc.pdf with some interesting extensions to the Forth virtual machine model. He proposed 4 new registers A, B, X, and Y. They can be used to simply store temporary data. More intelligent use cases arise from certian pointer operations with auto-increment and auto-decrement facilities.

AmForth adapts these ideas by combining the operations for A and X (B and Y similiarly). All commands are implemented in assembly using free registers and are included at compile time by adding the line

.include "words/reg-a.asm"
.include "words/reg-b.asm"

They do not depend on other files.

Basic Usage

Both registers A and B act the same way. They are not used inside any standard AmForth code and are not thread local. Since they use CPU registers, they work faster than variables or other memory based data.

To store data into a register, the command >a is used. Getting back the data is done with a>. Unlike the similiar looking >r, repeated calls to >a overwrite the register contents.

> a> .
  6183 ok
> 17 >a
> a> .
  17 ok

Pointer Voodoo

The registers can work as address registers. The command a@ reads the RAM location, the A register points to. By using a@+ the data is read and the register is incremented by 1 cell (2 bytes). Similiar the a@-: the data is read and the register is decremented by 1 cell.

> : dump swap >a 2/ 0 do a@+ . loop ;
>  source dump
 7320 756F 6372 2065 7564 706D  ok

To store data, the commands a!, a!+ and a!- can be used. They store the Top-Of-Stack Element to RAM where the A register points to and modify it afterwards (if applicable).

The words na@ and na! give access to the memory location n bytes relative to the current value of the A register. The content of the A register is not changed.

> : dump swap >a 2/ 0 do i cells na@ . loop ;
>  source dump
 7320 756F 6372 2065 7564 706D  ok

Portable Version

The registers are an extension of the underlying forth VM. There is no official reference implementation available. To experiment with them, the following code may be useful.

1 cells constant cell

variable reg:a

: >a  reg:a  ! ;
: a>  reg:a  @ ;
: a@  a> @ ;
: a!  a> ! ;
: na@ a> + @ ;
: na! a> + ! ;

\ post-increment fetch/store
: a@+ cell reg:a +! a@ ;
: a!+ cell reg:a +! a! ;
: a@- cell negate reg:a +! a@ ;
: a!- cell negate reg:a +! a! ;

\ alternativly
\ pre-increment fetch/store
: a@+ a@ cell reg:a +! ;
: a!+ a! cell reg:a +! ;
: a@- a@ cell negate reg:a +! ;
: a!- a! cell negate reg:a +! ;

Amforth has a highly optimizied assembler implementation of these commands.