
Figure 5.9: Proposed CPU Implementation
The Hack CPU has two registers, A and D. The Hack Assembly Language adds a pseudo-register, M, that refers to transferring data between the CPU and RAM. The A, D, and M register values can be sent to the ALU. The output of the ALU can be stored into the A, D, and M registers. The A register value is used as the RAM address when reading or writing the M register. The A register value is also used to set the program counter (PC) when a program jump occurs.
The Hack CPU has two types of instructions, A-instructions and C-instructions. The Hack Assembly Language adds a Label pseudo-instruction.
| "@"constant | Load a non-negative decimal constant into the A-register. | |
| "@"symbol | Load the address of the code label or RAM variable symbol into the A-register. |
Warning: A, D and M are valid symbol names and can be used with A-instructions, as in "@D". This will load the A register with the address of a variable named "D" or a code label "(D)"; it has nothing to do with the D register. Using A, D or M as symbols is highly discouraged.
| [ destination"=" ] computation [ ";" jump-condition ] | Note that destination and jump-condition are optional. |
For computations involving two registers, the registers must be D and one of A or M. The registers may occur in either order. Register names must be upper case.
| 0 | The constant value 0. | A+1 | A register plus 1. | |||
| A | The A register. | M-D | Subtract D register from RAM[A]. | |||
| -1 | The constant value -1. | D+D | Illegal – Must use D and A or M. | |||
| -D | Arithmetic negation of D register. | A+M | Illegal – Must use D and A or M. |
| A | M | AD | ADM | |||
| D | MD | AM |
| JLT | Jump if result < 0. | JEQ | Jump if result = 0. | JGT | Jump if result > 0. | |||||
| JLE | Jump if result ≤ 0. | JNE | Jump if result ≠ 0. | JGE | Jump if result ≥ 0. | |||||
| JMP | Always jump. |
| D=A | Set D register to A register. | |
| AD=A+1 | Increment A register and set D register to incremented value. | |
| M=~M | Invert RAM[A]. | |
| M=M-D | Subtract D register from RAM[A]. | |
| ADM=0 | Set RAM[A] and A and D registers to zero. | |
| 0;JMP | Unconditional jump to ROM address in A register. Note that there must be a computation; the convention is to use 0 for unconditional jumps. | |
| D;JNE | Jump to ROM address in A register if D register is non-zero. | |
| D=D-1;JGT | Decrement D register, then jump to ROM address in A register if D register is greater than zero. | |
| M=M-1;JGT | Not useful because the A register must be used for both the RAM address and the target jump address. |
| "(" symbol ")" |
The "D" in D-register stands for data. The D-register is primarily used for two things:
| Pseudo-code | ASM | Pseudo-code | ASM | Pseudo-code | ASM | |||||
n = 1 |
@n |
n = 17 |
@17 |
n = -2 |
@2 | |||||
a = -a |
@a |
a = a+7 |
@7 |
a = b+c |
@b | |||||
goto LOOP |
@LOOP |
if (x==0) |
@x |
if (y<=5) |
@y | |||||
a[123] = 0 |
@123 |
a[i] = 1 |
@i |
a[j] = b |
This is tricky and |
Here's the pseudo-code for the program:
n = 0
addr = 100
do {
RAM[addr] = n
addr = addr+1
n = n+11
} while n <= 99
Hack program
1: @n // n = 0
2: M=0
3:
4: @100 // addr = 100
5: D=A
6: @addr
7: M=D
8:
9: (Loop) // do {
10: @n // RAM[addr] = n
11: D=M
12: @addr
13: A=M
14: M=D
15:
16: @addr // addr = addr+1
17: M=M+1
18:
19: @11 // n = n+11
20: D=A
21: @n
22: MD=M+D // (tricky: also leaves new 'n' value in D)
23:
24: @99 // } while n <= 99
25: D=D-A
26: @Loop
27: D;JLE
28:
29: @Halt // loop forever
30: (Halt)
31: 0;JMP
Notes:
| 1: | n will be assigned address 16. |
| 6: | addr will be assigned address 17. |
| 13: | Although it looks like this might be a problem because the instruction is changing the A register which is supplying the address of addr, this is OK because the A register is changed when the instruction executes which happens after addr's value is read from RAM. |
| 22: | Stores n+11 into n and into D where it will be used for the following comparison. |
| 30: | Halt is assigned the ROM address of the 0;JMP instruction. This is the preferred way to write a halt loop so that the 0;JMP jumps to itself. |
| Free forum by Nabble | Edit this page |