From cabdda89b85236ffa4c408bc03dae58e8ddf5fdd Mon Sep 17 00:00:00 2001 From: Jon Michael Aanes Date: Wed, 30 Dec 2015 14:15:04 +0100 Subject: [PATCH] Reworked `registers.md` to hell and back. Now also lists scratch registers. --- registers.md | 132 ++++++++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 60 deletions(-) diff --git a/registers.md b/registers.md index fd23b05..027ef41 100644 --- a/registers.md +++ b/registers.md @@ -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.