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