Reworked registers.md to hell and back.

Now also lists scratch registers.
This commit is contained in:
Jon Michael Aanes 2015-12-30 14:15:04 +01:00
parent b29622e238
commit cabdda89b8

View File

@ -1,82 +1,94 @@
Registers in MAL
================
Program registers
The MAL-1 has 13 registers, 10 of them directly accessible, 2 of them virtual,
and 1 completely obscured. In this article we'll cover them in detail. We'll
look at which can be read from, written to, and which is safe to use for
arithmetic purposes.
The Complete List
-----------------
### PC
The *Program Counter* holds the address of the next instruction byte.
Below is a complete list of all registers and virtual registers in the MAL-1
architecture:
### MBR
The *Memory Buffer Register* stores the single byte that is read from the
address specified in **PC**. This register is special as it can be read as two
different registers:
- `PC`: The **Program Counter**. It holds the address of the next instruction
byte. Can be both read and written.
#### MBR
When read as MBR, the register reads as a 32-bit signed integer. The 32-bit
signed integer is sign extended from an 8-bit signed integer and thus has the
range -128 to 127.
- `MBR`: The **Memory Buffer Register**. It stores the byte read from the
address in `PC`. Cannot be written to. Can be read as a signed byte (-128 to
127), from the `MBR` address, or as an unsigned byte (0 to 255) from the
`MBRU` address.
#### MBRU
When read as *Memory Buffer Register Unsigned*, the register reads as a 32-bit
*unsigned* integer. The 32-bit signed integer is extended with zeros from an
8-bit *unsigned* integer and thus has the range 0 to 255.
- `OPC`: The **Old Program Counter**. It should technically store the previous
value of the `PC` register, but is frequently used as a *scratch register*.
Can be both read and written.
### OPC
The *Old Program Counter* is used to store the old value of the **PC**-register,
although it is very commonly used as a *scratch register* for storing other
values.
- `MPC`: The **Micro-Program Counter**. It holds the address of the next micro
program word. It is automatically set after very operation. Cannot be
read or written directly, though the `goto` statement in MAL will allow one
to set it.
### MPC
The *Micro-Program Counter* point so the current position in the microcode. It
is automatically set after very operation.
- `MAR`: The **Memory Address Register**. Holds the address of the next `rd`
or `wr` statement. Is used in conjunction with `MDR`. Cannot be read from,
only written to.
Read and write
--------------
- `MDR`: The **Memory Data Register**. Holds the data that has either just
been read from address `MAR` in memory, or is going to be written to address
`MAR` in memory. Can be used as a *scratch register*. Can be both read and
written.
### MAR
The *Memory Address Register* contains the address of the 32-bit word that the
next read or write is going to use. This register can only be written to, not
read from.
- `SP`: The **Stack Pointer**. Holds the address of the top-most element of
the stack. Can be both read and written.
### MDR
The *Memory Data Register* contains the data that has just been read in the case
of a *read* operation or is to be written in the case of a *wr* operation.
- `LV`: The **Local Variables pointer**. Points to the lowest of the local
variables in the current *stack frame*, that is the lowest of the local
variables for the currently executing function. Can be both read and
written.
### MBR
See **MBR** under *Program registers*
- `CPP`: The **Contant Pool Pointer**. Points to the lowest element of the
constant pool. Can be both read and written.
Stack registers
---------------
- `TOS`: The **Top Of Stack**. Contains the *value* of the uppermost stack
element. It is not a pointer. Can be used as a *scratch register*, but
should always be set back at the end of the instruction. Can be both read
and written.
### SP
The *Stack Pointer* register contains a pointer to the top-most element of the
stack.
- `H`: The **Hold register**. Contains any value the developer wishes. Is
required for many arithmetic operations. (See
[Operations](./operations.md).) Can be both read and written.
### LV
The *Local Variables* register points to the lowest of the local variables in
the current *stack frame*, that is the lowest of the local variables for the
currently executing function.
- `Z` & `N`: The **Zero** and **Negative** registers are *virtual registers*.
At the end of an ALU operation `Z` is automatically set to *on* if the
output is `0`. Likewise `N` is set to *on* if the output is `< 0`. Cannot be
read or written directly. Can only be used as arguments to the `if`
statement. (See [Operations](./operations.md))
### CPP
The *Constant Pool Pointer* points to the lowest element of the constant pool.
Scratch Registers
-----------------
### TOS
The *Top Of Stack* register contains the *value* of the uppermost element on the
stack--it is *not* a pointer. This is, however, not a requirement that the
developer is bound to follow when coding own instructions. The register should
however always be set to the value of the top element at the end of the
instruction.
To achieve the best possible performance, it is often wise to avoid any
interaction with memory while doing arithmetic work. This can be accomplished by
exclusively using registers for most work. Unfortunately most MAL registers are
unsuited for this.
Arithmetics
-----------
For a register to be suitable as a *scratch register*, it needs to achieve
following requirements:
### H
The *Hold* register is used to hold the left operand in the operations performed
by the ALU.
1. The register can be both read from and written to.
2. The register's primary function is either:
- Rarely used (eg `OPC`)
- Deliberately as as a *scratch register* (eg `H`)
- To contain a value easily retrieved from elsewhere (`TOS`)
### Z & N
The *Zero* and *Negative* registers are *virtual registers*. They are
automatically set after any ALU operation. A MAL `if(x)` statement can only
accept *Z* and *N* as input. *Z* is on if the output of the latest ALU operation
was zero. *N* is on if the output was negative.
Below is a list of registers on the MAL-1 suitable as *scratch registers*, why
they are usable in this fashion, and possible quirks:
- `OPC`: Rarely used.
- `MDR`: Can store any value when not being used for writing or reading
memory. It can even be useful to use it as the "final" result register, for
stack operations like `add` or `sub`.
- `TOS`: Should always contain the same value as the top element of the stack
in memory at the end of an operation, but can be used in any other way
before then. It is also a useful "final" result register similar to `MDR`.
- `H`: Is defined as a *scratch register*, and can be used in any way.