This cheatsheet assumes that you are using this compiler. However, much of the information is also applicable to compilers that follow the specifications of TECS
Use the navigation bar to jump to a section of interest
If you are writing assembly code from scratch, you are free to write or read to any memory location. The only caveat is the section allocated for IO use. Although the assembly code can write here, values written will be reflected in an output device or overwritten by an input device
If you are tweaking assembly code generated by a compiler (VM or HL), you should keep in mind the memory layout that the code assumes
Case sensitive
File extension is .asm
Single line comments start with //
A valid name must begin with a letter or underscore. The remaining characters can be digits, letters, or underscores
D
Used to facilitate computations
M
Pseudo register (no hardware equivalent)
Used to read from and write to data memory
A
Multiple uses:
As the address when reading from or writing to data memory
As the target address (program position) of a jump
To load a specific integer into another register
@integer
Sets the value of the A register to the given integer
The integer must be in the range 0 to 32767 (inclusive)
@symbolName
Sets the value of the A register to the address referenced by symbolName
See symbols
destination = computation
The ALU computes the specified computation. Its output is placed in the specified register (destination)
See destination
See computation
computation; jump
The ALU computes the specified computation. Its output is used to determine whether to jump
See computation
See jump
Used to give meaningful aliases to locations in memory
Labels refer to locations in program memory (i.e. locations in the executing program)
Variables refer to locations in data memory
Labels
Declaration, ( labelName )
To use, @labelName
Name must be unique. See valid names
Variables
To use, @variableName
Predefined:
*Address varies depending on color bit mode. See memory layout
Custom variables:
Declaration, @variableName
Name must be unique. See valid names
Mapping starts at address 16. For example, the first variable you declare will refer to dataMemory[16], the second to dataMemory[17] etc.
Sets the destination register(s) for the ALU's output
Types:
NULL
No destination
register[register][register]
One or more registers (ex. D, DM, DMA)
Jumps to a location in the program
More specifically, sets the program counter value to the value of the A register
If conditional, compares the ALU output to zero to determine whether to jump
Types:
NULL
Don't jump
JMP
Jump (unconditional)
JGT
Jump if greater than
JEQ
Jump if equal to
JLT
Jump if less than
JGE
Jump if greater than or equal to
JLE
Jump if less than or equal to
JNE
Jump if not equal to
Computations that the ALU can perform
Constant
0
Zero
1
One
- 1
Negative one
Unary
register
! register
Not
- register
Negate
Binary
register + 1
Add one
register - 1
Subtract one
register op register
+
Add
-
Subtract
*
Multiply1
/
Divide1
&
And
|
Or
^
Xor1
<<
Logical shift left1
>>
Logical shift right1
Note: The registers should be different (ex. D + D is not supported)
Notes
See registers
1The *
, /
, ^
, <<
, and >>
operations assume that the Hack computer's ALU can perform them. Though not present in the official TECS architecture, I am in the process of adding them to my version of the ALU
Addition:
@35 // A_register holds 35
D = A // D_register holds 35
@100 // A_register holds 100
D = D + A // D_register holds 135
Memory access:
// Read contents of Memory[ 999 ] into the D_register
@999
D = M
// Read contents of Memory[ 65534 ] into the D_register
@2
A = - A // A_register holds -2 (which is equivalent to 65534 in two's complement)
D = M
Array access:
// Let c represent an 'array' that begins at Memory[ 9000 ]
@9000
D = A
@c
M = D // Memory[ @c ] = 9000
// Set c[ 21 ] = - 1
@c
D = M // get the array's base address (9000)
@21 // A_register holds index (21)
A = D + A // A_register holds 9021 (9000 + 21)
M = - 1 // set value; Memory[ 9021 ] = - 1
Loops:
// --- Computes Memory[ 1 ] = 1 + 2 + ... + Memory[ 0 ]
// --- Usage: load a value into Memory[ 0 ]
// Setup
@i
M = 1 // Memory[ @i ] = Memory[ 16 ] = 1 // represents i
@sum
M = 0 // Memory[ @sum ] = Memory[ 17 ] = 0 // represents sum
// Main
(loop)
// break condition
@i
D = M
@0
D = D - M // i - Memory[ 0 ]
@loopEnd
D ; JGT // if i > Memory[ 0 ], exit loop
// body
@i
D = M
@sum
M = D + M // sum += i
@i
M = M + 1 // i += 1
@loop
0 ; JMP // go to next iteration of loop
(loopEnd)
@sum
D = M
@1
M = D // Memory[ 1 ] = sum // done
// Program end
(end)
@end
0 ; JMP // loop indefinitely