lecture 8
lecture 8
Lecture 8
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 1
Nand to Tetris Roadmap
software hierarchy
abstract
concept abstraction
program high-level abstraction
language
compiler
OS VM code abstraction
VM
machine
translator
language
assembler
abstraction
hardware platform
computer abstraction
computer
ALU, RAM abstraction
chips elementary d
logic gates gates Nan
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 2
Nand to Tetris Roadmap: Part II
software hierarchy
abstract
concept abstraction
program high-level abstraction
language
compiler
OS VM code abstraction
VM
machine
translator
language
assembler
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 3
Nand to Tetris Roadmap: Part II
software hierarchy
abstract
concept abstraction
program high-level abstraction
language
compiler
OS VM code abstraction
VM
machine
translator
language
assembler
Previous lecture
Introduced the VM language and developed a basic VM translator;
This lecture
Complete the VM language and development of the VM translator.
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 4
The big picture: Compilation
High-level program VM code
// Returns x * y // Returns x * y
int mult(int x, int y) { function mult
int sum = 0; push constant 0
int n = 1; pop local 0
// sum = sum + x, y times push constant 1
while !(n > y) { pop local 1
sum += x; label WHILE_LOOP Compilation focus (lectures 10 – 11)
n++; push local 1
}
push argument 1 The compiler maps symbolic variables
return sum;
} gt (sum, n, x,...) on virtual memory segment
if-goto END_LOOP
entries (local 0, local 1, argument 0, ...),
push local 0
push argument 0 and generates VM code that operates
add on these segments.
compiler pop local 0
push local 1
push constant 1
(later in the course)
add
pop local 1
goto WHILE_LOOP
label END_LOOP
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 5
The big picture: Compilation
VM code
The VM Language
// Returns x * y
Arithmetic / Logical commands function mult
push constant 0
• add, sub , neg
pop local 0
• eq , gt , lt, and, or , not push constant 1
pop local 1
Push / pop commands
label WHILE_LOOP Virtual machine focus (lectures 7–8)
• push
push local 1
• pop
push argument 1 Understanding and implementing the
gt
Branching commands
if-goto END_LOOP
target VM code
label
push local 0
goto push argument 0
if-goto add
pop local 0
Function commands push local 1
• function push constant 1
• call add
• return pop local 1
goto WHILE_LOOP
label END_LOOP
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 6
Branching (in a nutshell)
VM code
// Returns x * y
function mult
push constant 0
pop local 0
push constant 1
pop local 1 Programs typically include
label WHILE_LOOP branching logic:
push local 1
push argument 1
• Unconditional goto
gt
• Conditional goto
if-goto END_LOOP
push local 0
push argument 0
add
Implementation challenges
pop local 0
How to realize:
push local 1
push constant 1 • Conditions
add
pop local 1 • Goto destinations
goto WHILE_LOOP
label END_LOOP • Goto operations.
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 7
Functions (in a nutshell)
Function bar Function mult
// Some function // Returns x * y
function bar function mult
... push constant 0
// Computes 8 * 5 + 7 pop local 0
push constant 8 push constant 1
Programs typically consist of one ore more:
push constant 5 pop local 1
“methods” Different high-level languages
call mult 2 label WHILE_LOOP
push constant 7 push local 1 “functions” have different terminologies;
add push argument 1
... gt ”subroutines” In the VM language
return if-goto END_LOOP terminology, all these code
caller “procedures” units are called functions
push local 0
push argument 0
add
etc.
pop local 0
push local 1
push constant 1
add
The functions call each other, as shown in
pop local 1 the example.
goto WHILE_LOOP
label END_LOOP
push local 0
return callee
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 8
Functions (in a nutshell)
Function bar Function mult
// Some function // Returns x * y
function bar function mult
... push constant 0
// Computes 8 * 5 + 7 pop local 0
push constant 8
Implementation issues
push constant 1
push constant 5 pop local 1 How to pass arguments from the caller to
call mult 2 label WHILE_LOOP
the callee?
push constant 7 push local 1
add push argument 1 How to switch from executing the caller
... gt to executing the callee?
return if-goto END_LOOP
caller
push local 0 How to pass the return value from the
push argument 0 callee to the caller?
add
pop local 0 How to terminate the callee, and switch
push local 1 back to the caller?
push constant 1
add
pop local 1
goto WHILE_LOOP
label END_LOOP
push local 0
return callee
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 9
Take home lessons
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 10
Branching: Abstraction
// Returns x * y VM branching commands
function mult 2
push constant 0
• label
pop local 0 • goto
push constant 1 • if-goto
pop local 1
label WHILE_LOOP
push local 1
push argument 1
gt
if-goto END_LOOP
push local 0
push argument 0
add
pop local 0
push local 1
push constant 1
add
pop local 1
goto WHILE_LOOP
label END_LOOP
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 11
Branching: Abstraction
// Returns x * y VM branching commands
function mult 2
push constant 0
• label
pop local 0 • goto
push constant 1 • if-goto
pop local 1
label WHILE_LOOP
push local 1
Syntax: label label
push argument 1
gt
if-goto END_LOOP Semantics
push local 0 Marks the destination of goto commands.
push argument 0
add
pop local 0
push local 1
push constant 1
add
pop local 1
goto WHILE_LOOP
label END_LOOP
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 12
Branching: Abstraction
// Returns x * y VM branching commands
function mult 2
push constant 0
• label
pop local 0 • goto
push constant 1 • if-goto
pop local 1
label WHILE_LOOP
push local 1
Syntax: goto label
push argument 1
gt
if-goto END_LOOP Semantics
push local 0 Jump to execute the command just after the label.
push argument 0
add
pop local 0
push local 1
push constant 1
add
pop local 1
goto WHILE_LOOP
label END_LOOP
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 13
Branching: Abstraction
// Returns x * y VM branching commands
function mult 2
push constant 0
• label
pop local 0 • goto
push constant 1 • if-goto
pop local 1
label WHILE_LOOP
push local 1 Syntax: if-goto label
push argument 1
gt Semantics
if-goto END_LOOP
push local 0
1. let cond = pop
push argument 0 2. if cond, jump to execute the command just after the label;
add else, execute the next command.
pop local 0
push local 1
push constant 1
add
pop local 1
goto WHILE_LOOP
label END_LOOP
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 14
Branching: Abstraction
// Returns x * y VM branching commands
function mult 2
push constant 0
• label
pop local 0 • goto
push constant 1 • if-goto
pop local 1
label WHILE_LOOP
push local 1 Syntax: if-goto label
push argument 1
gt Semantics
if-goto END_LOOP
push local 0
1. let cond = pop
push argument 0 2. if cond, jump to execute the command just after the label;
add else, execute the next command.
pop local 0
push local 1 Convention: The code writer (typically, a compiler) must write
push constant 1
code that pushes a boolean expression onto the stack before the
add
if-goto command;
pop local 1
goto WHILE_LOOP In this example, the highlighted code implements the
label END_LOOP abstraction: if (local 1 > argument 1) goto END_LOOP
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 15
Branching: Implementation
Abstraction (recap)
label label // label declaration
goto label // jump to execute the command just after the label
Implementation
For each VM branching command, we generate machine language instructions that
realize the command on the target platform. Example:
VM code Hack code
... ... The instruction set of every computer features
label LOOP (LOOP) low-level “labeling” and “goto” primitives;
... ...
goto LOOP VM translator Therefore, the translation of the VM branching
@LOOP
... 0;JMP
commands to the machine language of the
... target platform is not difficult.
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 16
Lecture plan
Branching
• Abstraction
• Implementation
VM translator
• Bootstrap
• Conventions
• Architecture
• Project 8
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 17
Functions: Abstraction
caller callee
function bar 4 // Returns arg 0 * arg 1 Typical scenario
... function mult 2
// Computes 3 + 8 * 5 push constant 0 A function (the caller) calls
push constant 3 pop local 0 a function (the callee)
push constant 8 push constant 1 for its effect
push constant 5 pop local 1
call mult 2 label LOOP
add push local 1
... push argument 1
return
gt
if-goto END
bar’s view:
push local 0
stack push argument 0
just before 3 add
calling mult 8 pop local 0
5 push local 1
stack push constant 1
just after 3 add
calling mult 40 pop local 1
goto LOOP
label END
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 18
Functions: Abstraction
caller callee
VM function commands
function bar 4 // Returns arg 0 * arg 1
... • call
function mult 2
// Computes 3 + 8 * 5 push constant 0 • function
push constant 3 pop local 0
push constant 8 push constant 1
• return
push constant 5 pop local 1
call mult 2 label LOOP
add push local 1
... push argument 1
return
gt
if-goto END
bar’s view:
push local 0
stack push argument 0
just before 3 add
calling mult 8 pop local 0
5 push local 1
stack push constant 1
just after 3 add
calling mult 40 pop local 1
goto LOOP
label END
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 19
Functions: Abstraction
caller callee
VM function commands
function bar 4 // Returns arg 0 * arg 1
... • call
function mult 2
// Computes 3 + 8 * 5 push constant 0 • function
push constant 3 pop local 0
push constant 8 push constant 1
• return
push constant 5 pop local 1
call mult 2 Syntax: call functionName nArgs
label LOOP
add push local 1
... push argument 1
Semantics: Calls function functionName
return
gt for its effect, informing that nArgs argument
if-goto END values were pushed onto the stack
bar’s view:
push local 0
stack
Convention: The caller must push nArgs
push argument 0
just before arguments onto the stack before the call
3 add
calling mult 8 command.
pop local 0
5 push local 1
stack push constant 1
just after 3 add
calling mult 40 pop local 1
goto LOOP
label END
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 20
Functions: Abstraction
caller callee
VM function commands
function bar 4 // Returns arg 0 * arg 1
... • call
function mult 2
// Computes 3 + 8 * 5 push constant 0 • function
push constant 3 pop local 0
push constant 8 push constant 1
• return
push constant 5 pop local 1
call mult 2 Syntax: function functionName nVars
label LOOP
add push local 1
... Semantics
push argument 1
return
gt Here starts the declaration of a function
if-goto END that has name functionName and
bar’s view: nVars local variables
push local 0
stack push argument 0
just before 3 add
calling mult 8 pop local 0
5 push local 1 Note: In this example the caller passes
stack push constant 1 2 arguments, and the function has 2 local
just after add variables. This is just a coincidence;
3
calling mult 40 pop local 1
nArgs had nothing to do with nVars.
goto LOOP
label END
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 21
Functions: Abstraction
caller callee
VM function commands
function bar 4 // Returns arg 0 * arg 1
... • call
function mult 2
// Computes 3 + 8 * 5 push constant 0 • function
push constant 3 pop local 0
push constant 8 push constant 1
• return
push constant 5 pop local 1
call mult 2 label LOOP Syntax: return
add push local 1
...
return
push argument 1 Convention: The callee must push a
gt
value onto the stack before a return
if-goto END command
bar’s view:
push local 0
stack push argument 0
just before 3 add Semantics
calling mult 8 pop local 0
5
The return value will replace (in the stack)
push local 1
the argument values that were pushed by the
stack push constant 1 caller before the call;
just after 3 add
calling mult Control will be transferred back to the caller;
40 pop local 1
goto LOOP Execution will resume with the command just
label END after the call.
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 22
Lecture plan
Branching
• Abstraction
• Implementation
VM translator
• Bootstrap
• Conventions
• Architecture
• Project 8
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 23
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... function Foo.mult 2 scenario
// Computes 3 + 8 * 5 push constant 0
push constant 3 Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
push constant 1
push constant 5 pop local 1
for its effect
call mult 2 ...
add push local 0
... return
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 24
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... function Foo.mult 2 scenario
// Computes 3 + 8 * 5 push constant 0
push constant 3 Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
push constant 1
push constant 5 pop local 1
for its effect
call mult 2 ...
add push local 0
... return
return
Foo.bar’s view
stack
just before 3
the call 8
5
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 25
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... function Foo.mult 2 scenario
// Computes 3 + 8 * 5 push constant 0
push constant 3 Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
push constant 1
push constant 5 pop local 1
for its effect
call mult 2 ...
add push local 0
... return
return
Foo.bar’s view
stack
just before
the call
3
8
Magic!
5
Let’s open
stack
just after 3
the black box
the call 40
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 26
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... 0 function Foo.mult 2 scenario
// Computes 3 + 8 * 5 1 push constant 0
push constant 3 2
Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
3 push constant 1
push constant 5 pop local 1
for its effect
4
call mult 2 ... ...
add 20 push local 0
... 21 return
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 27
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... 0 function Foo.mult 2 scenario
// Computes 3 + 8 * 5 1 push constant 0
push constant 3 2
Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
3 push constant 1
push constant 5 pop local 1
for its effect
4
call mult 2 ... ...
add 20 push local 0
... 21 return
return
Foo.bar’s view
stack
just before 3
the call 8
5
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 28
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... 0 function Foo.mult 2 scenario
// Computes 3 + 8 * 5 1 push constant 0
push constant 3 2
Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
3 push constant 1
push constant 5 pop local 1
for its effect
4
call mult 2 ... ...
add 20 push local 0
... 21 return
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 29
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... 0 function Foo.mult 2 scenario
// Computes 3 + 8 * 5 1 push constant 0
push constant 3 2
Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
3 push constant 1
push constant 5 pop local 1
for its effect
4
call mult 2 ... ...
add 20 push local 0
... 21 return
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 30
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... 0 function Foo.mult 2 scenario
// Computes 3 + 8 * 5 1 push constant 0
push constant 3 2
Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
3 push constant 1
push constant 5 pop local 1
for its effect
4
call mult 2 ... ...
add 20 push local 0
... 21 return
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 31
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... 0 function Foo.mult 2 scenario
// Computes 3 + 8 * 5 1 push constant 0
push constant 3 2
Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
3 push constant 1
push constant 5 pop local 1
for its effect
4
call mult 2 ... ...
add 20 push local 0
... 21 return
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 32
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... 0 function Foo.mult 2 scenario
// Computes 3 + 8 * 5 1 push constant 0
push constant 3 2
Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
3 push constant 1
push constant 5 pop local 1
for its effect
4
call mult 2 ... ...
add 20 push local 0
... 21 return
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 33
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... 0 function Foo.mult 2 scenario
// Computes 3 + 8 * 5 1 push constant 0
push constant 3 2
Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
3 push constant 1
push constant 5 pop local 1
for its effect
4
call mult 2 ... ...
add 20 push local 0
... 21 return
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 34
Function call and return
caller callee
function Foo.bar 4 // Returns arg 0 * arg 1 Typical function-call-and-return
... 0 function Foo.mult 2 scenario
// Computes 3 + 8 * 5 1 push constant 0
push constant 3 2
Function Foo.bar (the caller) calls
pop local 0
push constant 8 function Foo.mult (the callee)
3 push constant 1
push constant 5 pop local 1
for its effect
4
call mult 2 ... ...
add 20 push local 0
... 21 return
return
Foo.bar’s view
stack
just before 3
the call 8
5 The caller’s execution is resumed;
The next command to be executed:
stack
just after 3 add
the call 40
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 35
Function call and return
Abstraction (recap):
A VM program consists of one or more VM functions;
The functions call each other, for their effect (including recursively);
Each function execution sees its own working stack and memory segments;
Arguments and return values are passed, somehow.
Implementation
We’ll describe the handling of the function-call-and-return commands in two stages:
• The translation process
• The global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 36
Translation
VM code Generated code (pseudo assembly)
caller: function Foo.bar 4 Conventions
...
// Computes 3 + 8 * 5 Each VM function starts with
push constant 3 a function command, and ends
push constant 8
with a return command;
push constant 5
call Foo.mult 2 Each VM function returns a
add
value (void functions return a
... VM translator
return value which is ignored by the
callee: // Computes arg 0 * arg 1 caller). The return value is the
function Foo.mult 2 top value in the callee’s stack.
push constant 0
pop local 0
push constant 1
pop local 1
...
// Returns the result
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 37
Translation
VM code Generated code (pseudo assembly)
caller: function Foo.bar 4 // function Foo.bar 4
... (Foo.bar) // injected function’s entry point label
// Computes 3 + 8 * 5 // assembly code that initializes the function’s 4 local variables
push constant 3
push constant 8
push constant 5
call Foo.mult 2
add
... VM translator
return
callee: // Computes arg 0 * arg 1
function Foo.mult 2
push constant 0
pop local 0
push constant 1
pop local 1
...
// Returns the result
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 38
Translation
Blue: Generated by the
VM code Generated code (pseudo assembly)
basic VM translator
caller: function Foo.bar 4 // function Foo.bar 4 (project 7);
... (Foo.bar) // injected function’s entry point label
// Computes 3 + 8 * 5 // assembly code that initializes the function’s 4 local variables Black: Generated by
push constant 3 // assembly code that handles ..., push constant 3, ..., push constant 5 the completed VM
push constant 8 translator (project 8).
push constant 5
call Foo.mult 2
add
... VM translator
return
callee: // Computes arg 0 * arg 1
function Foo.mult 2
push constant 0
pop local 0
push constant 1
pop local 1
...
// Returns the result
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 39
Translation
Blue: Generated by the
VM code Generated code (pseudo assembly)
basic VM translator
caller: function Foo.bar 4 // function Foo.bar 4 (project 7);
... (Foo.bar) // injected function’s entry point label
// Computes 3 + 8 * 5 // assembly code that initializes the function’s 4 local variables Black: Generated by
push constant 3 // assembly code that handles ..., push constant 3, ..., push constant 5 the completed VM
push constant 8 // call Foo.mult 2 translator (project 8).
push constant 5 // Creates a return address label (Foo.bar$ret.1); Saves the return
call Foo.mult 2 // address and the caller’s segment pointers, and then generates:
add goto Foo.mult // injected branching to the called function
... VM translator (Foo.bar$ret.1) // injected return address label
return
callee: // Computes arg 0 * arg 1
function Foo.mult 2
push constant 0
pop local 0
push constant 1
pop local 1
...
// Returns the result
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 40
Translation
Blue: Generated by the
VM code Generated code (pseudo assembly)
basic VM translator
caller: function Foo.bar 4 // function Foo.bar 4 (project 7);
... (Foo.bar) // injected function’s entry point label
// Computes 3 + 8 * 5 // assembly code that initializes the function’s 4 local variables Black: Generated by
push constant 3 // assembly code that handles ..., push constant 3, ..., push constant 5 the completed VM
push constant 8 // call Foo.mult 2 translator (project 8).
push constant 5 // Creates a return address label (Foo.bar$ret.1); Saves the return
call Foo.mult 2 // address and the caller’s segment pointers, and then generates:
add goto Foo.mult // injected branching to the called function
... VM translator (Foo.bar$ret.1) // injected return address label
return // assembly code that handles add, ...
callee: // Computes arg 0 * arg 1
function Foo.mult 2
push constant 0
pop local 0
push constant 1
pop local 1
...
// Returns the result
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 41
Translation
VM code Generated code (pseudo assembly)
caller: function Foo.bar 4 // function Foo.bar 4
... (Foo.bar) // injected function’s entry point label
// Computes 3 + 8 * 5 // assembly code that initializes the function’s 4 local variables
push constant 3 // assembly code that handles ..., push constant 3, ..., push constant 5
push constant 8 // call Foo.mult 2
push constant 5 // Creates a return address label (Foo.bar$ret.1); Saves the return
call Foo.mult 2 // address and the caller’s segment pointers, and then generates:
add goto Foo.mult // injected branching to the called function
... VM translator (Foo.bar$ret.1) // injected return address label
return // assembly code that handles add, ...
callee: // Computes arg 0 * arg 1 // function Foo.mult 2
function Foo.mult 2 (Foo.mult) // injected function’s entry point label
push constant 0 // assembly code that initializes the function’s 2 local variables
pop local 0
push constant 1
pop local 1
...
// Returns the result
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 42
Translation
VM code Generated code (pseudo assembly)
caller: function Foo.bar 4 // function Foo.bar 4
... (Foo.bar) // injected function’s entry point label
// Computes 3 + 8 * 5 // assembly code that initializes the function’s 4 local variables
push constant 3 // assembly code that handles ..., push constant 3, ..., push constant 5
push constant 8 // call Foo.mult 2
push constant 5 // Creates a return address label (Foo.bar$ret.1); Saves the return
call Foo.mult 2 // address and the caller’s segment pointers, and then generates:
add goto Foo.mult // injected branching to the called function
... VM translator (Foo.bar$ret.1) // injected return address label
return // assembly code that handles add, ...
callee: // Computes arg 0 * arg 1 // function Foo.mult 2
function Foo.mult 2 (Foo.mult) // injected function’s entry point label
push constant 0 // assembly code that initializes the function’s 2 local variables
pop local 0 // assembly code that handles push constant 0 , ..., push local 0
push constant 1
pop local 1
...
// Returns the result
push local 0
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 43
Translation
VM code Generated code (pseudo assembly)
caller: function Foo.bar 4 // function Foo.bar 4
... (Foo.bar) // injected function’s entry point label
// Computes 3 + 8 * 5 // assembly code that initializes the function’s 4 local variables
push constant 3 // assembly code that handles ..., push constant 3, ..., push constant 5
push constant 8 // call Foo.mult 2
push constant 5 // Creates a return address label (Foo.bar$ret.1); Saves the return
call Foo.mult 2 // address and the caller’s segment pointers, and then generates:
add goto Foo.mult // injected branching to the called function
... VM translator (Foo.bar$ret.1) // injected return address label
return // assembly code that handles add, ...
callee: // Computes arg 0 * arg 1 // function Foo.mult 2
function Foo.mult 2 (Foo.mult) // injected function’s entry point label
push constant 0 // assembly code that initializes the function’s 2 local variables
pop local 0 // assembly code that handles push constant 0 , ..., push local 0
push constant 1 // return
pop local 1 // Retrieves the saved return address (which, in this example, happens to be
... // Foo.bar$ret.1), replaces the arguments pushed by the caller with the
// Returns the result // return value (stack’s top element), reinstates the segment pointers of the
push local 0 // caller, and then generates:
return goto Foo.bar$ret.1 // injected branching back to the calling site.
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 44
Translation
VM code Generated code (pseudo assembly)
caller: function Foo.bar 4 // function Foo.bar 4 Notes
... (Foo.bar) // injected function’s entry point label
// Computes 3 + 8 * 5 // assembly code that initializes the function’s 4 local variables This pseudocode must be
push constant 3 // assembly code that handles ..., push constant 3, ..., push constant 5 generated in the target
// call Foo.mult 2
push constant 8
// Creates a return address label (Foo.bar$ret.1); Saves the return
platform’s assembly language;
push constant 5
call Foo.mult 2 // address and the caller’s segment pointers, and then generates: When the resulting assembly
goto Foo.mult // injected branching to the called function
add
code will execute, it will
... VM translator (Foo.bar$ret.1) // injected return address label
return // assembly code that handles add, ... realize the semantics implied
callee: // Computes arg 0 * arg 1 // function Foo.mult 2 by the VM code.
function Foo.mult 2 (Foo.mult) // injected function’s entry point label
push constant 0 // assembly code that initializes the function’s 2 local variables
pop local 0 // assembly code that handles push constant 0 , ..., push local 0
push constant 1 // return
pop local 1 // Retrieves the saved return address (which, in this example, happens to be
... // Foo.bar$ret.1), replaces the arguments pushed by the caller with the
// Returns the result // return value (stack’s top element), reinstates the segment pointers of the
push local 0 // caller, and then generates:
return goto Foo.bar$ret.1 // injected branching back to the calling site.
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 45
Translation (detailed): call / function / return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 46
Translation (detailed): call / function / return
working stack
of the caller
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 47
Translation (detailed): call / function / return
working stack
of the caller
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 48
Translation (detailed): call / function / return
working stack
of the caller
nArgs
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 49
Translation (detailed): call / function / return
working stack
of the caller
nArgs
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 50
Translation (detailed): call / function / return
working stack
of the caller The address to which control
should return when the callee’s
nArgs execution is terminated
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 51
Translation (detailed): call / function / return
working stack
of the caller The address to which control
should return when the callee’s
nArgs execution is terminated
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 52
Translation (detailed): call / function / return
nArgs
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 53
Translation (detailed): call / function / return
nArgs
Saved “frame”
of the caller
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 54
Translation (detailed): call / function / return
nArgs
Saved “frame”
of the caller
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 55
Translation (detailed): call / function / return
Saved “frame”
of the caller
SP, LCL
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 56
Translation (detailed): call / function / return
Saved “frame”
of the caller
SP, LCL
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 57
Translation (detailed): call / function / return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 58
Translation (detailed): call / function / return
Saved “frame”
of the caller
SP, LCL
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 59
Translation (detailed): call / function / return
Saved “frame”
of the caller
SP, LCL
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 60
Translation (detailed): call / function / return
Saved “frame”
of the caller
LCL
nVars
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 61
Translation (detailed): call / function / return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 62
Translation (detailed): call / function / return
ARG
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 63
Translation (detailed): call / function / return
ARG
LCL
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 64
Translation (detailed): call / function / return
ARG
LCL
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 65
Translation (detailed): call / function / return
ARG
LCL
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 66
Translation (detailed): call / function / return
ARG
LCL
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 67
Translation (detailed): call / function / return
Handling return:
The callee says: We have to:
return
ARG
LCL
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 68
Translation (detailed): call / function / return
Handling return:
The callee says: We have to:
return 1. Replace the arguments that the caller pushed
with the value returned by the callee
LCL
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 69
Translation (detailed): call / function / return
Handling return:
The callee says: We have to:
return 1. Replace the arguments that the caller pushed
with the value returned by the callee
2. Recycle the memory used by the callee
LCL
SP
the global stack
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 70
Translation (detailed): call / function / return
Handling return:
The callee says: We have to:
return 1. Replace the arguments that the caller pushed
with the value returned by the callee
2. Recycle the memory used by the callee
LCL
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 71
Translation (detailed): call / function / return
Handling return:
The callee says: We have to:
return 1. Replace the arguments that the caller pushed
with the value returned by the callee
2. Recycle the memory used by the callee
3. Restore the caller’s segment pointers
ARG returned value 4. Jump to the return address
SP
LCL
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 72
Translation (detailed): call / function / return
Handling return:
The callee says: We have to:
return 1. Replace the arguments that the caller pushed
with the value returned by the callee
2. Recycle the memory used by the callee
3. Restore the caller’s segment pointers
ARG returned value 4. Jump to the return address
SP
Generated code
// The code below creates and uses two temporary variables:
// endFrame and retAddr;
// The pointer notation *addr is used to denote: RAM[addr].
endFrame = LCL // gets the address at the frame’s end
LCL retAddr = *(endFrame – 5) // gets the return address
*ARG = pop() // puts the return value for the caller
SP = ARG + 1 // repositions SP
THAT = *(endFrame – 1) // restores THAT
THIS = *(endFrame – 2) // restores THIS
ARG = *(endFrame – 3) // restores ARG
LCL = *(endFrame – 4) // restores LCL
the global stack goto retAddr // jumps to the return address
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 74
Translation (detailed): call / function / return
Implementation
Follows exactly the same scheme, once for every call-and-return scenario;
The global stack will grow and shrink telescopically: Last in, first out
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 75
Lecture plan
Abstraction
• VM branching commands
• VM function commands
Implementation (conceptual)
• VM branching commands
• VM function commands
Related topics
• Bootstrap
• Conventions
• Architecture
• Project 8
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 76
The big picture: Compilation
myProg folder
High level language conventions
Main.jack
(much more about it in lecture 9):
class Main
function main {. . . }
Jack program: a set of one or more class files, all in the same folder;
method bar {. . . } Jack class: a set of one or more methods, functions (static methods),
}
and constructors;
There must be at least one class file named Main.jack, and this file
Foo.jack must contain at least one method named main;
class Foo
Program’s entry point: Main.main()
constructor new {. . . }
method bar {. . . }
}
OS conventions
(much more about it in lecture 12):
The OS is written in Jack (just like Unix is written in C);
One OS class, Sys, contains a method named init
When the computer boots, it executes Sys.init
Sys.init calls Main.main.
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 77
The big picture: Compilation
myProg folder myProg folder myProg folder
Main.jack
Main.vm myProg.asm
class Main
function Main.main (Main.main)
function main {. . . } ... ...
method bar {. . . } (Main.bar)
function Main.bar
} ... ...
Each Jack class is a set Each method, function, All the VM functions
of methods, functions, and constructor is translated are translated into a
and constructors into a VM function single assembly file
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 78
Bootstrap code
Run-time conventions
The compiled code base includes the program: A set of VM functions, one of which is Main.main
The compiled code base also includes the operating system: Also a set of VM functions, one of
which is Sys.init
Sys.init initializes the operating system, calls Main.main, and enters an infinite loop
The stack is stored in the RAM, starting at address 256
// Bootstrap code
SP = 256
call Sys.init // (no arguments)
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 79
Standard mapping of the VM on the Hack platform
ROM RAM
0 0 SP
bootstrap
... code 1 LCL
segment pointers,
... 2 ARG temp segment,
... ... registers R13 – R15
OS 15
Managed by the run-time system
code 16
static (the code generated by the VM translator)
...
variables
255
256
global
...
stack
2047
program
2048
code
... heap
16383
16384
memory Managed by the OS
... mapped
24576 I/O (lecture 12)
24577
... ... unused
32767 32767
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 80
Symbols
Naming
conventions,
Read carefully
for project 8.
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 81
Lecture plan
Abstraction
• VM branching commands
• VM function commands
Implementation (conceptual)
• VM branching commands
• VM function commands
VM translator
• Bootstrap
• Conventions
• Architecture
• Project 8
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 82
VM translator
drives the
VMTranslator process
Parser CodeWriter
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 83
VM translator
Usage: (if the translator is implemented in Java)
$ java VMTranslator source
Where source is either a single fileName.vm, or a folderName containing one or more .vm files;
(The source may contain a file path; the first character of filename must be an uppercase letter)
Action
• Constructs a CodeWriter
• If source is a .vm file:
Constructs a Parser to handle the input file;
For each VM command in the input file:
uses the Parser to parse the command,
uses the CodeWriter to generate assembly code from it
• If source is a folder:
Handles every .vm file in the folder in the manner described above.
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 84
VM translator
drives the
process VMTranslator
Parser CodeWriter
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 85
Parser
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 86
VM translator: Proposed design
drives the
process VMTranslator
Parser CodeWriter
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 87
CodeWriter
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 88
CodeWriter
The generated assembly code must adhere to the symbol naming conventions.
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 89
Lecture plan
Abstraction
• VM branching commands
• VM function commands
Implementation (conceptual)
• VM branching commands
• VM function commands
VM translator
• Bootstrap
• Conventions
• Architecture
• Project 8
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 90
The Big Picture
software hierarchy
abstract Writing a
concept abstraction
program high-level
Building a p7 p8
abstraction
language
compiler Building a
OS VM code abstraction
VM
machine
translator
language
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 91
Test programs
ProgramFlow:
q BasicLoop
q FibonacciSeries
FunctionCalls:
q SimpleFunction
q FibonacciElement
q StaticsTest
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 92
Test programs: BasicLoop
ProgramFlow: BasicLoop.vm
u BasicLoop
// Computes the sum 1 + 2 + ... + argument[0],
BasicLoop.vm // and pushes the result onto the stack.
BasicLoopVME.tst push constant 0
BasicLoop.tst pop local 0
BasicLoop.cmp
label LOOP_START
q FibonacciSeries push argument 0
push local 0
FunctionCalls:
add
q SimpleFunction
pop local 0
q FibonacciElement push argument 0
q StaticsTest push constant 1
Tests the handling of
sub
the VM commands:
pop argument 0
label
push argument 0
if-goto LOOP_START if-goto
push local 0
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 93
Test programs
ProgramFlow:
q BasicLoop
q FibonacciSeries
FunctionCalls:
q SimpleFunction
q FibonacciElement
q StaticsTest
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 94
Test programs: FibonacciSeries
FibSeries.vm
ProgramFlow:
// Computes the first argument[0] elements of the Fibonacci series.
q BasicLoop // Puts the elements in the RAM, starting at the address given in argument[1].
u FibonacciSeries push argument 1
FibSeries.vm pop pointer 1
FibSeriesVME.tst push constant 0
FibSeries.tst pop that 0
FibSeries.cmp push constant 1
pop that 1
FunctionCalls: ...
q SimpleFunction label MAIN_LOOP_START
q FibonacciElement push argument 0
q StaticsTest if-goto COMPUTE_ELEMENT
goto END_PROGRAM
A more elaborate test of
label COMPUTE_ELEMENT handling the VM commands:
push that 0 label
push that 1 goto
add if-goto
...
goto MAIN_LOOP_START
label END_PROGRAM
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 95
Test programs
ProgramFlow:
q BasicLoop
q FibonacciSeries
FunctionCalls:
q SimpleFunction
q FibonacciElement
q StaticsTest
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 96
Test programs: SimpleFunction
SimpleFunction.vm
ProgramFlow:
q BasicLoop // Performs a simple (and meaningless) calculation involving local
// and argument values, and returns the result.
q FibonacciSeries
function SimpleFunction.test 2
FunctionCalls: push local 0
u SimpleFunction push local 1
SimpleFunction.vm add
SimpleFunctionVME.tst not
SimpleFunction.tst push argument 0
add
SimpleFunction.cmp
push argument 1
q FibonacciElement
sub
q StaticsTest
return Tests the handling of the VM commands
function
return
Basic test, involving no caller
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 97
Test programs
ProgramFlow:
q BasicLoop
q FibonacciSeries
FunctionCalls:
q SimpleFunction
q FibonacciElement
q StaticsTest
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 98
Test programs: FibonacciElement
Main.vm
ProgramFlow:
// Main.fibonacci: computes the n'th element of the Fibonacci series,
q BasicLoop
// recursively. The n value is supplied by the caller, and stored in
q FibonacciSeries // argument 0.
function Main.fibonacci 0
FunctionCalls:
push argument 0 • Tests that the VM translator can handle more than one VM file
q SimpleFunction
push constant 2 • Tests the handling of function, return, call
u FibonacciElement lt
Main.vm if-goto IF_TRUE
• Tests that the VM translator initializes the memory segments
Sys.vm goto IF_FALSE • Tests that the bootstrap code initializes the stack and calls Sys.init
FibElementVME.tst label IF_TRUE
FibElement.tst push argument 0 Sys.vm
FibElement.cmp return
label IF_FALSE // Sys.init: pushes n onto the stack,
q StaticsTest
// and calls Main.fibonacii to compute
push argument 0
// the n’th Fibonacci element.
push constant 2
sub // (Called by the bootstrap code generated
// by the VM translator ). Normally, Sys.init is used to
call Main.fibonacci 1 call Main.main;
function Sys.init 0
push argument 0 In Project 8 we use Sys.init to
push constant 4
push constant 1 call test functions, as needed.
call Main.fibonacci 1
sub
call Main.fibonacci 1 label WHILE
goto WHILE
add
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 99
Test programs: FibonacciElement
Main.vm
ProgramFlow:
// Main.fibonacci: computes the n'th element of the Fibonacci series,
q BasicLoop
// recursively. The n value is supplied by the caller, and stored in
q FibonacciSeries // argument 0.
function Main.fibonacci 0
FunctionCalls:
push argument 0
q SimpleFunction
push constant 2
u FibonacciElement lt
Usage: $ VMTranslator FibonacciElement (translates a folder)
Main.vm if-goto IF_TRUE (Should generates a single output file: FibonacciElement.asm)
Sys.vm goto IF_FALSE
FibElementVME.tst label IF_TRUE
FibElement.tst push argument 0 Sys.vm
FibElement.cmp return
label IF_FALSE // Sys.init: pushes n onto the stack,
q StaticsTest
// and calls Main.fibonacii to compute
push argument 0
// the n’th Fibonacci element.
push constant 2
sub // (Called by the bootstrap code generated
// by the VM translator ).
call Main.fibonacci 1
function Sys.init 0
push argument 0
push constant 4
push constant 1
call Main.fibonacci 1
sub
call Main.fibonacci 1 label WHILE
goto WHILE
add
return
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 100
Test programs
ProgramFlow:
q BasicLoop
q FibonacciSeries
FunctionCalls:
q SimpleFunction
q FibonacciElement
q StaticsTest
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 101
Test programs: StaticsTest
Class1.vm
ProgramFlow:
// Stores two supplied arguments in
q BasicLoop
// static 0 and static 1
q FibonacciSeries function Class1.set 0 Class2.vm
push argument 0
FunctionCalls: // Stores two supplied arguments in
pop static 0
q SimpleFunction static 0 and static 1
push argument 1
q FibonacciElement function Class2.set 0 Sys.vm
pop static 1
push argument 0
u StaticsTest push constant 0 function Sys.init 0
Class1.vm pop static 0 Class1.set with 6 and 8
// Calls
return
push argumentpush 1constant 6
Class2.vm
pop staticpush 1 constant 8
Sys.vm // Returns (static 0) – (static 1)
push constantcall 0Class1.set 2
StaticsTestVME.tst function Class1.get 0
return pop temp 0 // dumps the return value
StaticsTest.tst push static 0
push static 1 // Calls Class2.set with 23 and 15
StaticsTest.cmp // Returns (static 0) –constant
(static 1)
sub push 23
function Class2.get 0
push constant 15
return
push static call0 Class2.set 2
push static pop1 temp 0 // dumps the return value
sub // Checks the two resulting static segments
Tests the handling of return Same logic
call Class1.get 0
static variables in a
call Class2.get 0
program consisting of
label WHILE
more than one VM file
goto WHILE
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 102
Test programs
ProgramFlow:
q BasicLoop Testing routine for every test program Xxx:
q FibonacciSeries
0. Recommended: Load and run XxxVME.tst on the VM emulator;
FunctionCalls: This script loads the Xxx test program into the VM emulator,
q SimpleFunction allowing you to experiment with its code
q FibonacciElement 1. Use your VM translator to translate Xxx.vm, generating a file
q StaticsTest named Xxx.asm (if the test includes more than one .vm file,
apply your translator to the folder name)
2. Load and run Xxx.tst on the CPU emulator;
This script loads Xxx.asm into the emulator,
executes it, and compares the output to Xxx.cmp
Note: All the files mentioned above are supplied, except for Xxx.asm
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 103
Recap / Next
program folder program folder
(named, say, points) (points) points.asm points.hack
...
Main.jack Main.vm ...
1101010010101011
M=D 1100001101010101
class Main @i 0101010011101100
...
function void main { M=0 1100101111111111
push local 1
var Point p1; (LOOP) 0101110101010011
push const 3
... @i 1100111111010101
add 0101110110101011
} D=M
... 1100100000001011
} @n
compiler VM translator D=D-M assembler 0101110111100010
1111000111010100
@END 0010101000101011
D;JGT 0111000111010111
Point.jack Point.vm @addr 1010101000101011
class Point ... D=M 0101110110101011
@SP 1100100000001011
field int x,y; push arg 2
M=M+1 0101110111100010
... call Math.sqrt 0101110110101011
} ... @i
0101110111100011
D=M
...
...
Nand to Tetris / www.nand2tetris.org / Chapter 8 / Copyright © Noam Nisan and Shimon Schocken Slide 104