Registers are assigned as follows:
- EAX - volatile scratch
- ECX - volatile scratch
- EDX - volatile scratch
- EBX - volatile scratch
- EBP - volatile scratch
- ESI - data stack pointer
- EDI - retain stack pointer
- ESP - callstack pointer
EBPas volatile scratch registers, since otherwise they'd be unused.
Stack frames are fixed-size, 16 bytes each, with no explicit back-chain pointers. Stack frames have the following layout:
- 4 bytes current quotation position - used by code compiled with quotation compiler
- 4 bytes current quotation - used by code compiled with quotation compiler
- Pointer to start current of current code block - used by code GC as a root when scavenging the call stack
- Return address for callee
Unlike typical x86 code which passes parameters on the call stack, I use registers to pass parameters to quotations and words.
Quotations are called with the following values in registers:
- EAX - a tagged pointer to the quotation itself ECX - a pointer to the start of the quotation's code block. The quotation's compiled definition saves this in the stack frame
Compound definitions and symbols are called with the following values in registers:
- EAX - the word itself
Primitive words are called with the following values in registers:
- EDX - the top of the call stack before the primitive call
Compiled words can be called without any parameters in registers.
Compiled words are responsible for a pointer to the start of their own in their stack frame, however the caller of a compiled quotation must do this for the quotation. This is because right now, compiled quotations must be fully position independent without requiring any relocation.