程序代写代做代考 compiler assembler assembly CSCE-312 Day 1 Introduction

CSCE-312 Day 1 Introduction

L16 – Writing Basic HACK Programs

Hack assembly language (overview)
Semantics:
Computes the value of comp
Stores the result in dest
If the Boolean expression (comp jump 0) is true,
jumps to execute the instruction at ROM[A]
where:
0, 1, -1, D, A, !D, !A, -D, -A, D+1, A+1, D-1, A-1, D+A, D-A, A-D, D&A, D|A
M, !M, -M, M+1, M-1, D+M, D-M, M-D, D&M, D|M
comp =
null, JGT, JEQ, JGE, JLT, JNE, JLE, JMP
jump =
null, M, D, MD, A, AM, AD, AMD
dest =
(M refers to RAM[A])
dest = comp ; jump
(both dest and jump are optional)
C-instruction:
A-instruction:
where value is either a constant or a symbol referring to such a constant
@value // A = value
credit: nand2tetris.org
2

Hack assembler
Assembly program
// Program: Flip.asm
// flips the values of
// RAM[0] and RAM[1]
@R1
D=M
@temp
M=D // temp = R1

@R0
D=M
@R1
M=D // R1 = R0

@temp
D=M
@R0
M=D // R0 = temp

(END)
@END
0;JMP
Hack
assembler
Binary code
0000000000000001
1111110000010000
0000000000010000
1110001100001000
0000000000000000
1111110000010000
0000000000000001
1110001100001000
0000000000010000
1111110000010000
0000000000000000
1110001100001000
0000000000001100
1110101010000111
load &
execute
We’ll develop a Hack assembler later in the course.
credit: nand2tetris.org
3

Symbolic program implemented as a text file
3

CPU Emulator
A software tool
Convenient for debugging and executing symbolic Hack programs.
load
CPU Emulator

Assembly program
// Program: Flip.asm
// flips the values of
// RAM[0] and RAM[1]
@R1
D=M
@temp
M=D // temp = R1

@R0
D=M
@R1
M=D // R1 = R0

@temp
D=M
@R0
M=D // R0 = temp

(END)
@END
0;JMP
(the simulator software translates from symbolic to binary as it loads)
credit: nand2tetris.org
4

Symbolic program implemented as a text file
4

Registers and memory

RAM
ROM
instructions
data out
data in

CPU
M register
D register
A register
D: data register
A: address / data register
M: the currently selected memory register: M = RAM[A]
credit: nand2tetris.org
5

Registers and memory
Typical operations:
D: data register
A: address / data register
M: the currently selected memory register: M = RAM[A]
credit: nand2tetris.org
6

Registers and memory
// D=10
@10
D=A

// D++
D=D+1

// D=RAM[17]
@17
D=M

// RAM[17]=D
@17
M=D

Typical operations:
D: data register
A: address / data register
M: the currently selected memory register: M = RAM[A]
credit: nand2tetris.org
7

Registers and memory
// RAM[17]=10
@10
D=A
@17
M=D

// RAM[5] = RAM[3]
@3
D=M
@5
M=D

// D=10
@10
D=A

// D++
D=D+1

// D=RAM[17]
@17
D=M

// RAM[17]=D
@17
M=D

Typical operations:
D: data register
A: address / data register
M: the currently selected memory register: M = RAM[A]
credit: nand2tetris.org
8

Program example: add two numbers
Hack assembly code
credit: nand2tetris.org
9

Program example: add two numbers
// Program: Add2.asm
// Computes: RAM[2] = RAM[0] + RAM[1]
// Usage: put values in RAM[0], RAM[1]

@0
D=M // D = RAM[0]

@1
D=D+M // D = D + RAM[1]

@2
M=D // RAM[2] = D

Hack assembly code
4
5
0
1
2
3
32767

@0
D=M
0
1




Memory (ROM)
@1
D=D+M
2
3
@2
M=D
4
5

6
7

8
9

10
11

12
13

14
15

(white space
ignored)
translate and load
symbolic view
credit: nand2tetris.org
10

32767

Program example: add two numbers
0000000000000000
1111110000010000
0
1




Memory (ROM)
0000000000000001
1111000010010000
2
3
0000000000000010
1110001100001000
4
5

6
7

8
9

10
11

12
13

14
15

// Program: Add2.asm
// Computes: RAM[2] = RAM[0] + RAM[1]
// Usage: put values in RAM[0], RAM[1]

@0
D=M // D = RAM[0]

@1
D=D+M // D = D + RAM[1]

@2
M=D // RAM[2] = D

Hack assembly code
4
5
0
1
2
3
binary
view
translate and load
credit: nand2tetris.org
11

Terminating a program

@0
D=M
0
1




Memory (ROM)
@1
D=D+M
2
3
@2
M=D
4
5

6
7

8
9

10
11

12
13

14
15

4
5
0
1
2
3
// Program: Add2.asm
// Computes: RAM[2] = RAM[0] + RAM[1]
// Usage: put values in RAM[0], RAM[1]

@0
D=M // D = RAM[0]

@1
D=D+M // D = D + RAM[1]

@2
M=D // RAM[2] = D

Hack assembly code
credit: nand2tetris.org
12

Terminating a program

@0
D=M
0
1




Memory (ROM)
@1
D=D+M
2
3
@2
M=D
4
5

6
7

8
9

10
11

12
13
malicious code
starts here…
14
15

4
5
0
1
2
3

// Program: Add2.asm
// Computes: RAM[2] = RAM[0] + RAM[1]
// Usage: put values in RAM[0], RAM[1]

@0
D=M // D = RAM[0]

@1
D=D+M // D = D + RAM[1]

@2
M=D // RAM[2] = D

Hack assembly code
Resulting from some attack on the computer
credit: nand2tetris.org
13

Terminating a program

@0
D=M
0
1




Memory (ROM)
@1
D=D+M
2
3
@2
M=D
4
5

6
7

8
9

10
11

12
13

14
15

4
5
0
1
2
3
// Program: Add2.asm
// Computes: RAM[2] = RAM[0] + RAM[1]
// Usage: put values in RAM[0], RAM[1]

@0
D=M // D = RAM[0]

@1
D=D+M // D = D + RAM[1]

@2
M=D // RAM[2] = D

Hack assembly code
credit: nand2tetris.org
14

Terminating a program
// Program: Add2.asm
// Computes: RAM[2] = RAM[0] + RAM[1]
// Usage: put values in RAM[0], RAM[1]

@0
D=M // D = RAM[0]

@1
D=D+M // D = D + RAM[1]

@2
M=D // RAM[2] = D

@6
0;JMP

Hack assembly code
Best practice:
To terminate a program safely, end it with an infinite loop.
4
5
6
7
0
1
2
3

@0
D=M




Memory (ROM)
@1
D=D+M
@2
M=D
@6
0;JMP

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Jump to instruction number A
(which happens to be 6)
0: syntax convention for jmp instructions
credit: nand2tetris.org
15

Built-in symbols
symbol value
R0 0
R1 1
R2 2
… …
R15 15

The Hack assembly language features built-in symbols:
These symbols can be used to denote “virtual registers”
Example: suppose we wish to use RAM[5] to represent some variable,
say x, and we wish to let x=7
// let RAM[5] = 7
@7
D=A

@5
M=D
implementation:
Attention: Hack is case-sensitive! R5 and r5 are different symbols.
better style:
// let RAM[5] = 7
@7
D=A

@R5
M=D
credit: nand2tetris.org
16

16

Built-in symbols
symbol value
R0 0
R1 1
R2 2
… …
R15 15

The Hack assembly language features built-in symbols:
credit: nand2tetris.org
17

17

Built-in symbols
symbol value
R0 0
R1 1
R2 2
… …
R15 15
SCREEN 16384
KBD 24576

The Hack assembly language features built-in symbols:
symbol value
SP 0
LCL 1
ARG 2
THIS 3
THAT 4

R0, R1 ,…, R15 : “virtual registers”, can be used as variables
SCREEN and KBD : base addresses of I/O memory maps
Remaining symbols: used in the implementation of the Hack virtual
machine, discussed in chapters 7-8.
credit: nand2tetris.org
18

18

OUTLINE
Hack programming
Part 1: registers and memory
Part 2: branching, variables, iteration
Part 3: pointers, input/output
Project 4 overview
19

Branching
credit: nand2tetris.org
20

Branching
// Program: Signum.asm
// Computes: if R0>0
// R1=1
// else
// R1=0

example:
credit: nand2tetris.org
21

Branching
// Program: Signum.asm
// Computes: if R0>0
// R1=1
// else
// R1=0
// Usage: put a value in RAM[0],
// run and inspect RAM[1].

example:
credit: nand2tetris.org
22

Branching
// Program: Signum.asm
// Computes: if R0>0
// R1=1
// else
// R1=0
// Usage: put a value in RAM[0],
// run and inspect RAM[1].

@R0
D=M // D = RAM[0]

@8
D;JGT // If R0>0 goto 8

@R1
M=0 // RAM[1]=0
@10
0;JMP // goto end

@R1
M=1 // R1=1

@10
0;JMP
8
9
10
11
4
5
6
7
0
1
2
3
example:
credit: nand2tetris.org
23

Branching
// Program: Signum.asm
// Computes: if R0>0
// R1=1
// else
// R1=0
// Usage: put a value in RAM[0],
// run and inspect RAM[1].

@R0
D=M // D = RAM[0]

@8
D;JGT // If R0>0 goto 8

@R1
M=0 // RAM[1]=0
@10
0;JMP // goto end

@R1
M=1 // R1=1

@10
0;JMP
8
9
10
11
4
5
6
7
0
1
2
3
example:
credit: nand2tetris.org
24

Branching
“Instead of imagining that our main task as programmers is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.”
– Donald Knuth

// Program: Signum.asm
// Computes: if R0>0
// R1=1
// else
// R1=0
// Usage: put a value in RAM[0],
// run and inspect RAM[1].

@R0
D=M // D = RAM[0]

@8
D;JGT // If R0>0 goto 8

@R1
M=0 // RAM[1]=0
@10
0;JMP // goto end

@R1
M=1 // R1=1

@10
0;JMP
8
9
10
11
4
5
6
7
0
1
2
3
cryptic code
example:
credit: nand2tetris.org
25

Branching
// Program: Signum.asm
// Computes: if R0>0
// R1=1
// else
// R1=0
// Usage: put a value in RAM[0],
// run and inspect RAM[1].

@R0
D=M // D = RAM[0]

@POSITIVE
D;JGT // If R0>0 goto 8

@R1
M=0 // RAM[1]=0
@10
0;JMP // goto end

(POSITIVE)
@R1
M=1 // R1=1

(END)
@END
0;JMP
example:
8
9
10
11
4
5
6
7
0
1
2
3
referring to a label
declaringa label
credit: nand2tetris.org
26

Labels
Label resolution rules:
Label declarations
generate no code
Each reference to a
label is replaced with
a reference to the instruction number following that label’s declaration.
32767

@0
D=M
0
1




Memory
@8 // @POSITIVE
D;JGT
2
3
@1
M=0
4
5
@10 // @END
0;JMP
6
7
@1
M=1
8
9
@10 // @END
0;JMP
10
11

12
13

14
15
resolving
labels

// Program: Signum.asm
// Computes: if R0>0
// R1=1
// else
// R1=0
// Usage: put a value in RAM[0],
// run and inspect RAM[1].

@R0
D=M // D = RAM[0]

@POSITIVE
D;JGT // If R0>0 goto 8

@R1
M=0 // RAM[1]=0
@10
0;JMP // goto end

(POSITIVE)
@R1
M=1 // R1=1

(END)
@END
0;JMP
example:
8
9
10
11
4
5
6
7
0
1
2
3
referring to a label
declaringa label
credit: nand2tetris.org
27

Labels
Implications:
32767

@0
D=M
0
1




@8 // @POSITIVE
D;JGT
2
3
@1
M=0
4
5
@10 // @END
0;JMP
6
7
@1
M=1
8
9
@10 // @END
0;JMP
10
11

12
13

14
15

// Program: Signum.asm
// Computes: if R0>0
// R1=1
// else
// R1=0
// Usage: put a value in RAM[0],
// run and inspect RAM[1].

@R0
D=M // D = RAM[0]

@POSITIVE
D;JGT // If R0>0 goto 8

@R1
M=0 // RAM[1]=0
@10
0;JMP // goto end

(POSITIVE)
@R1
M=1 // R1=1

(END)
@END
0;JMP
example:
8
9
10
11
4
5
6
7
0
1
2
3
resolving
labels
Memory
referring to a label
declaringa label
credit: nand2tetris.org
28

Labels
Implications:
Instruction numbers no longer needed in symbolic programming
The symbolic code becomes relocatable.
32767

@0
D=M
0
1




@8 // @POSITIVE
D;JGT
2
3
@1
M=0
4
5
@10 // @END
0;JMP
6
7
@1
M=1
8
9
@10 // @END
0;JMP
10
11

12
13

14
15

// Program: Signum.asm
// Computes: if R0>0
// R1=1
// else
// R1=0
// Usage: put a value in RAM[0],
// run and inspect RAM[1].

@R0
D=M // D = RAM[0]

@POSITIVE
D;JGT // If R0>0 goto 8

@R1
M=0 // RAM[1]=0
@10
0;JMP // goto end

(POSITIVE)
@R1
M=1 // R1=1

(END)
@END
0;JMP
example:
8
9
10
11
4
5
6
7
0
1
2
3
resolving
labels
Memory
referring to a label
declaringa label
credit: nand2tetris.org
29

Variables
// Program: Flip.asm
// flips the values of
// RAM[0] and RAM[1]

Variable usage example:
credit: nand2tetris.org
30

Variables
// Program: Flip.asm
// flips the values of
// RAM[0] and RAM[1]

// temp = R1
// R1 = R0
// R0 = temp

@R1
D=M
@temp
M=D // temp = R1

@R0
D=M
@R1
M=D // R1 = R0

@temp
D=M
@R0
M=D // R0 = temp

(END)
@END
0;JMP
Variable usage example:
credit: nand2tetris.org
31

Variables
Variable usage example:
// Program: Flip.asm
// flips the values of
// RAM[0] and RAM[1]

// temp = R1
// R1 = R0
// R0 = temp

@R1
D=M
@temp
M=D // temp = R1

@R0
D=M
@R1
M=D // R1 = R0

@temp
D=M
@R0
M=D // R0 = temp

(END)
@END
0;JMP
symbol
used for the first time
symbol used again
credit: nand2tetris.org
32

Variables
Variable usage example:
32767

@1
D=M
0
1




Memory
@16 // @temp
M=D
2
3
@0
D=M
4
5
@1
M=D
6
7
@16 // @temp
D=M
8
9
@0
M=D
10
11
@12
0;JMP
12
13

14
15
resolving
symbols

Symbol resolution rules:
A reference to a symbol that has no corresponding label declaration is treated
as a reference to a variable
If the reference @ symbol occurs in the program for first time, symbol is allocated to address 16 onward (say n), and the generated code is @ n
All subsequencet
@ symbol commands are translated into @ n
// Program: Flip.asm
// flips the values of
// RAM[0] and RAM[1]

// temp = R1
// R1 = R0
// R0 = temp

@R1
D=M
@temp
M=D // temp = R1

@R0
D=M
@R1
M=D // R1 = R0

@temp
D=M
@R0
M=D // R0 = temp

(END)
@END
0;JMP
In other words: variables are allocated to RAM[16] onward.
symbol
used for the first time
symbol used again
credit: nand2tetris.org
33

Variables
Variable usage example:
Implications:

// Program: Flip.asm
// flips the values of
// RAM[0] and RAM[1]

// temp = R1
// R1 = R0
// R0 = temp

@R1
D=M
@temp
M=D // temp = R1

@R0
D=M
@R1
M=D // R1 = R0

@temp
D=M
@R0
M=D // R0 = temp

(END)
@END
0;JMP
symbolic code is easy
to read and debug
32767

@1
D=M
0
1




Memory
@16 // @temp
M=D
2
3
@0
D=M
4
5
@1
M=D
6
7
@16 // @temp
D=M
8
9
@0
M=D
10
11
@12
0;JMP
12
13

14
15
resolving
symbols

credit: nand2tetris.org
34

Iterative processing
// Computes RAM[1] = 1+2+ … +RAM[0]

pseudo code
credit: nand2tetris.org
35

35

Iterative processing
// Computes RAM[1] = 1+2+ … +RAM[0]

n = R0
i = 1
sum = 0
LOOP:
if i > n goto STOP
sum = sum + i
i = i + 1
goto LOOP
STOP:
R1 = sum
pseudo code
credit: nand2tetris.org
36

36

Iterative processing
// Computes RAM[1] = 1+2+ … +RAM[0]

n = R0
i = 1
sum = 0

pseudo code
// Program: Sum1toN.asm
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]

assembly code
credit: nand2tetris.org
37

37

Iterative processing
// Computes RAM[1] = 1+2+ … +RAM[0]

n = R0
i = 1
sum = 0

pseudo code
// Program: Sum1toN.asm
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]

@R0
D=M
@n
M=D // n = R0

@i
M=1 // i = 1

@sum
M=0 // sum = 0

assembly code
credit: nand2tetris.org
38

38

// Computes RAM[1] = 1+2+ … +RAM[0]

n = R0
i = 1
sum = 0

Iterative processing
pseudo code
// Program: Sum1toN.asm
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]

@R0
D=M
@n
M=D // n = R0

@i
M=1 // i = 1

@sum
M=0 // sum = 0

assembly code
32767

@0
D=M
0
1




Memory
@16 // @n
M=D
2
3
@17 // @i
M=1
4
5
@18 // @sum
M=0
6
7

8
9

10
11

12
13

14
15

Variables are allocated to consecutive RAM locations from address
16 onward
credit: nand2tetris.org
39

39

// Computes RAM[1] = 1+2+ … +RAM[0]

n = R0
i = 1
sum = 0

Iterative processing
pseudo code
credit: nand2tetris.org
40

40

Iterative processing
pseudo code
// Computes RAM[1] = 1+2+ … +RAM[0]

n = R0
i = 1
sum = 0
LOOP:
if i > n goto STOP
sum = sum + i
i = i + 1
goto LOOP
STOP:
R1 = sum
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0

assembly program
credit: nand2tetris.org
41

41

Iterative processing
pseudo code
// Computes RAM[1] = 1+2+ … +RAM[0]

n = R0
i = 1
sum = 0
LOOP:
if i > n goto STOP
sum = sum + i
i = i + 1
goto LOOP
STOP:
R1 = sum
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i
D=M
@n
D=D-M
@STOP
D;JGT // if i > n goto STOP
@sum
D=M
@i
D=D+M
@sum
M=D // sum = sum + i
@i
M=M+1 // i = i + 1
@LOOP
0;JMP
assembly program
credit: nand2tetris.org
42

42

Iterative processing
pseudo code
// Computes RAM[1] = 1+2+ … +RAM[0]

n = R0
i = 1
sum = 0
LOOP:
if i > n goto STOP
sum = sum + i
i = i + 1
goto LOOP
STOP:
R1 = sum
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i
D=M
@n
D=D-M
@STOP
D;JGT // if i > n goto STOP
@sum
D=M
@i
D=D+M
@sum
M=D // sum = sum + i
@i
M=M+1 // i = i + 1
@LOOP
0;JMP
(STOP)
@sum
D=M
@R1
M=D // RAM[1] = sum

assembly program
credit: nand2tetris.org
43

43

Iterative processing
pseudo code
// Computes RAM[1] = 1+2+ … +RAM[0]

n = R0
i = 1
sum = 0
LOOP:
if i > n goto STOP
sum = sum + i
i = i + 1
goto LOOP
STOP:
R1 = sum
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i
D=M
@n
D=D-M
@STOP
D;JGT // if i > n goto STOP
@sum
D=M
@i
D=D+M
@sum
M=D // sum = sum + i
@i
M=M+1 // i = i + 1
@LOOP
0;JMP
(STOP)
@sum
D=M
@R1
M=D // RAM[1] = sum
(END)
@END
0;JMP
assembly program
credit: nand2tetris.org
44

44

Program execution
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i
D=M
@n
D=D-M
@STOP
D;JGT // if i > n goto STOP
@sum
D=M
@i
D=D+M
@sum
M=D // sum = sum + i
@i
M=M+1 // i = i + 1
@LOOP
0;JMP
(STOP)
@sum
D=M
@R1
M=D // RAM[1] = sum
(END)
@END
0;JMP
assembly program
credit: nand2tetris.org
45

45

Program execution
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i
D=M
@n
D=D-M
@STOP
D;JGT // if i > n goto STOP
@sum
D=M
@i
D=D+M
@sum
M=D // sum = sum + i
@i
M=M+1 // i = i + 1
@LOOP
0;JMP
(STOP)
@sum
D=M
@R1
M=D // RAM[1] = sum
(END)
@END
0;JMP
assembly program
iterations
0
RAM[0]: 3
n: 3
i: 1
sum: 0

credit: nand2tetris.org
46

46

Program execution
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i
D=M
@n
D=D-M
@STOP
D;JGT // if i > n goto STOP
@sum
D=M
@i
D=D+M
@sum
M=D // sum = sum + i
@i
M=M+1 // i = i + 1
@LOOP
0;JMP
(STOP)
@sum
D=M
@R1
M=D // RAM[1] = sum
(END)
@END
0;JMP
assembly program
iterations
0 1
RAM[0]: 3
n: 3
i: 1 2
sum: 0 1

credit: nand2tetris.org
47

47

Program execution
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i
D=M
@n
D=D-M
@STOP
D;JGT // if i > n goto STOP
@sum
D=M
@i
D=D+M
@sum
M=D // sum = sum + i
@i
M=M+1 // i = i + 1
@LOOP
0;JMP
(STOP)
@sum
D=M
@R1
M=D // RAM[1] = sum
(END)
@END
0;JMP
assembly program
iterations
0 1 2
RAM[0]: 3
n: 3
i: 1 2 3
sum: 0 1 3

credit: nand2tetris.org
48

48

Program execution
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i
D=M
@n
D=D-M
@STOP
D;JGT // if i > n goto STOP
@sum
D=M
@i
D=D+M
@sum
M=D // sum = sum + i
@i
M=M+1 // i = i + 1
@LOOP
0;JMP
(STOP)
@sum
D=M
@R1
M=D // RAM[1] = sum
(END)
@END
0;JMP
assembly program
iterations
0 1 2 3
RAM[0]: 3
n: 3
i: 1 2 3 4
sum: 0 1 3 6

credit: nand2tetris.org
49

49

Program execution
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i
D=M
@n
D=D-M
@STOP
D;JGT // if i > n goto STOP
@sum
D=M
@i
D=D+M
@sum
M=D // sum = sum + i
@i
M=M+1 // i = i + 1
@LOOP
0;JMP
(STOP)
@sum
D=M
@R1
M=D // RAM[1] = sum
(END)
@END
0;JMP
assembly program
iterations
0 1 2 3 …
RAM[0]: 3
n: 3
i: 1 2 3 4 …
sum: 0 1 3 6 …

credit: nand2tetris.org
50

50

Writing assembly programs
// Computes RAM[1] = 1+2+ … +n
// Usage: put a number (n) in RAM[0]
@R0
D=M
@n
M=D // n = R0
@i
M=1 // i = 1
@sum
M=0 // sum = 0
(LOOP)
@i
D=M
@n
D=D-M
@STOP
D;JGT // if i > n goto STOP
@sum
D=M
@i
D=D+M
@sum
M=D // sum = sum + i
@i
M=M+1 // i = i + 1
@LOOP
0;JMP
(STOP)
@sum
D=M
@R1
M=D // RAM[1] = sum
(END)
@END
0;JMP
assembly program
Best practice:
Design the program using pseudo code
Write the program in assembly language
Test the program (on paper) using
a variable-value trace table
credit: nand2tetris.org
51

51

OUTLINE
Hack programming
Part 1: registers and memory
Part 2: branching, variables, iteration
Part 3: pointers, input/output
Project 4 overview
52

Pointers
Example:

// for (i=0; i n goto END
RAM[addr] = -1 // 1111111111111111
// advances to the next row
addr = addr + 32
i = i + 1
goto LOOP

END:
goto END
Pseudo code

physical screen

screen memory map

16 black pixels, corresponding to the rectangle’s first row
credit: nand2tetris.org
65

65

Handling the screen (example)
// Program: Rectangle.asm
// Draws a filled rectangle at the
// screen’s top left corner, with
// width of 16 pixels and height of
// RAM[0] pixels.
// Usage: put a non-negative number
// (rectangle’s height) in RAM[0].

@SCREEN
D=A
@addr
M=D // addr = 16384
// (screen’s base address)
@0
D=M
@n
M=D // n = RAM[0]

@i
M=0 // i = 0

(LOOP)
@i
D=M
@n
D=D-M
@END
D;JGT // if i>n goto END

@addr
A=M
M=-1 // RAM[addr]=1111111111111111

@i
M=M+1 // i = i + 1
@32
D=A
@addr
M=D+M // addr = addr + 32
@LOOP
0;JMP // goto LOOP

(END)
@END // program’s end
0;JMP // infinite loop
Assembly code
(continued)
credit: nand2tetris.org
66

66

// Program: Rectangle.asm
// Draws a filled rectangle at the
// screen’s top left corner, with
// width of 16 pixels and height of
// RAM[0] pixels.
// Usage: put a non-negative number
// (rectangle’s height) in RAM[0].

@SCREEN
D=A
@addr
M=D // addr = 16384
// (screen’s base address)
@0
D=M
@n
M=D // n = RAM[0]

@i
M=0 // i = 0

Handling the screen (example)
(LOOP)
@i
D=M
@n
D=D-M
@END
D;JGT // if i>n goto END

@addr
A=M
M=-1 // RAM[addr]=1111111111111111

@i
M=M+1 // i = i + 1
@32
D=A
@addr
M=D+M // addr = addr + 32
@LOOP
0;JMP // goto LOOP

(END)
@END // program’s end
0;JMP // infinite loop
(continued)
Assembly code
credit: nand2tetris.org
67

67

Input

data
memory
(16K)
0

24,576

Hello, world

screen memory map
(8K)
16,384
Hack RAM
Hack language convention:
SCREEN: base address of the screen memory map
SCREEN
credit: nand2tetris.org
68

Input

data
memory
(16K)
0

keyboard map
24,576

Hello, world

screen memory map
(8K)
16,384
Hack RAM
Hack language convention:
SCREEN: base address of the screen memory map
KBD: address of the keyboard memory map
SCREEN
KBD
credit: nand2tetris.org
69

Handling the keyboard
To check which key is currently pressed:
Read the contents of RAM[24576] (address KBD)
If the register contains 0, no key is pressed
Otherwise, the register contains the scan code of the currently pressed key.
24576

k
Scan-code of ‘k’ = 75
0000000001001011

Hack RAM
credit: nand2tetris.org
70

Complete program example
// Adds 1+…+100.
into i = 1;
into sum = 0;
while (i <= 100){ sum += i; i++; } C language code: // Adds 1+...+100. @i // i refers to some RAM location M=1 // i=1 @sum // sum refers to some RAM location M=0 // sum=0 (LOOP) @i D=M // D = i @100 D=D-A // D = i - 100 @END D;JGT // If (i-100) > 0 goto END
@i
D=M // D = i
@sum
M=D+M // sum += i
@i
M=M+1 // i++
@LOOP
0;JMP // Got LOOP
(END)
@END
0;JMP // Infinite loop
Hack assembly code:
Hack assembly convention:
Variables: lower-case
Labels: upper-case
Commands: upper-case
Credit: www.nand2tetris.org
71

71

Assembler
Credit: www.nand2tetris.org
72
Q: Who does all the “automatic” assignments of symbols to RAM addresses?
A: The assembler, which is the program that translates symbolic Hack
programs into binary Hack program. As part of the translation process, the symbols are resolved to RAM addresses. (more about this in future lectures)

Perspective
Hack is a simple machine language
User friendly syntax: D=D+A instead of ADD D,D,A
Hack is a “½-address machine”: any operation that needs to operate on the RAM must be specified using two commands: an A-command to address the RAM, and a subsequent C-command to operate on it
A Hack assembler is needed and will be discusses and developed later in the course.
Credit: www.nand2tetris.org
73

73

End notes
for (i=0; i