mirror of
https://github.com/usatiuk/nand2tetris.git
synced 2025-10-29 00:27:49 +01:00
init
This commit is contained in:
507
projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm
Normal file
507
projects/08/FunctionCalls/FibonacciElement/FibonacciElement.asm
Normal file
@@ -0,0 +1,507 @@
|
||||
@256
|
||||
D=A
|
||||
@SP
|
||||
M=D
|
||||
// call Sys.init 0
|
||||
@$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@5
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Sys.init
|
||||
-1;JMP
|
||||
($ret.0)
|
||||
// function Sys.init 0
|
||||
(Sys.init)
|
||||
// push constant 4
|
||||
@4
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// call Main.fibonacci 1
|
||||
@Sys.init$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@6
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Main.fibonacci
|
||||
-1;JMP
|
||||
(Sys.init$ret.0)
|
||||
// label WHILE 0
|
||||
(Sys.init$WHILE)
|
||||
// goto WHILE 0
|
||||
@Sys.init$WHILE
|
||||
-1;JMP
|
||||
// 0
|
||||
// function Main.fibonacci 0
|
||||
(Main.fibonacci)
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 2
|
||||
@2
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// lt 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
@T0
|
||||
D;JLT
|
||||
@END0
|
||||
D=0;JMP
|
||||
(T0)
|
||||
D=-1
|
||||
(END0)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// if-goto IF_TRUE 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@Main.fibonacci$IF_TRUE
|
||||
D;JNE
|
||||
// goto IF_FALSE 0
|
||||
@Main.fibonacci$IF_FALSE
|
||||
-1;JMP
|
||||
// label IF_TRUE 0
|
||||
(Main.fibonacci$IF_TRUE)
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// label IF_FALSE 0
|
||||
(Main.fibonacci$IF_FALSE)
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 2
|
||||
@2
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END1)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// call Main.fibonacci 1
|
||||
@Main.fibonacci$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@6
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Main.fibonacci
|
||||
-1;JMP
|
||||
(Main.fibonacci$ret.0)
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 1
|
||||
@1
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END2)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// call Main.fibonacci 1
|
||||
@Main.fibonacci$ret.1
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@6
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Main.fibonacci
|
||||
-1;JMP
|
||||
(Main.fibonacci$ret.1)
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END3)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// 0
|
||||
@@ -0,0 +1,2 @@
|
||||
| RAM[0] |RAM[261]|
|
||||
| 262 | 3 |
|
||||
@@ -0,0 +1,18 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/FibonacciElement/FibonacciElement.tst
|
||||
|
||||
// FibonacciElement.asm results from translating both Main.vm and Sys.vm into
|
||||
// a single assembly program, stored in the file FibonacciElement.asm.
|
||||
|
||||
load FibonacciElement.asm,
|
||||
output-file FibonacciElement.out,
|
||||
compare-to FibonacciElement.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[261]%D1.6.1;
|
||||
|
||||
repeat 9000 {
|
||||
ticktock;
|
||||
}
|
||||
|
||||
output;
|
||||
@@ -0,0 +1,17 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/FibonacciElement/FibonacciElementVME.tst
|
||||
|
||||
load, // Load all the VM files from the current directory
|
||||
output-file FibonacciElement.out,
|
||||
compare-to FibonacciElement.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[261]%D1.6.1;
|
||||
|
||||
set sp 261,
|
||||
|
||||
repeat 110 {
|
||||
vmstep;
|
||||
}
|
||||
|
||||
output;
|
||||
30
projects/08/FunctionCalls/FibonacciElement/Main.vm
Normal file
30
projects/08/FunctionCalls/FibonacciElement/Main.vm
Normal file
@@ -0,0 +1,30 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/FibonacciElement/Main.vm
|
||||
|
||||
// Computes the n'th element of the Fibonacci series, recursively.
|
||||
// n is given in argument[0]. Called by the Sys.init function
|
||||
// (part of the Sys.vm file), which also pushes the argument[0]
|
||||
// parameter before this code starts running.
|
||||
|
||||
function Main.fibonacci 0
|
||||
push argument 0
|
||||
push constant 2
|
||||
lt // checks if n<2
|
||||
if-goto IF_TRUE
|
||||
goto IF_FALSE
|
||||
label IF_TRUE // if n<2, return n
|
||||
push argument 0
|
||||
return
|
||||
label IF_FALSE // if n>=2, returns fib(n-2)+fib(n-1)
|
||||
push argument 0
|
||||
push constant 2
|
||||
sub
|
||||
call Main.fibonacci 1 // computes fib(n-2)
|
||||
push argument 0
|
||||
push constant 1
|
||||
sub
|
||||
call Main.fibonacci 1 // computes fib(n-1)
|
||||
add // returns fib(n-1) + fib(n-2)
|
||||
return
|
||||
15
projects/08/FunctionCalls/FibonacciElement/Sys.vm
Normal file
15
projects/08/FunctionCalls/FibonacciElement/Sys.vm
Normal file
@@ -0,0 +1,15 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/FibonacciElement/Sys.vm
|
||||
|
||||
// Pushes a constant, say n, onto the stack, and calls the Main.fibonacii
|
||||
// function, which computes the n'th element of the Fibonacci series.
|
||||
// Note that by convention, the Sys.init function is called "automatically"
|
||||
// by the bootstrap code.
|
||||
|
||||
function Sys.init 0
|
||||
push constant 4
|
||||
call Main.fibonacci 1 // computes the 4'th fibonacci element
|
||||
label WHILE
|
||||
goto WHILE // loops infinitely
|
||||
651
projects/08/FunctionCalls/NestedCall/.asm
Normal file
651
projects/08/FunctionCalls/NestedCall/.asm
Normal file
@@ -0,0 +1,651 @@
|
||||
@Sys.init
|
||||
0;JMP
|
||||
// function Sys.init 0
|
||||
(Sys.init)
|
||||
// push constant 4000
|
||||
@4000
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THIS
|
||||
M=D
|
||||
// push constant 5000
|
||||
@5000
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// call Sys.main 0
|
||||
@Sys.init$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@5
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Sys.main
|
||||
-1;JMP
|
||||
(Sys.init$ret.0)
|
||||
// pop temp 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@R6
|
||||
M=D
|
||||
// label LOOP 0
|
||||
(Sys.init$LOOP)
|
||||
// goto LOOP 0
|
||||
@Sys.init$LOOP
|
||||
-1;JMP
|
||||
// function Sys.main 5
|
||||
(Sys.main)
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 4001
|
||||
@4001
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THIS
|
||||
M=D
|
||||
// push constant 5001
|
||||
@5001
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// push constant 200
|
||||
@200
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@1
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// push constant 40
|
||||
@40
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 2
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@2
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// push constant 6
|
||||
@6
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 3
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@3
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// push constant 123
|
||||
@123
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// call Sys.add12 1
|
||||
@Sys.main$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@6
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Sys.add12
|
||||
-1;JMP
|
||||
(Sys.main$ret.0)
|
||||
// pop temp 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@R5
|
||||
M=D
|
||||
// push local 0
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 1
|
||||
@1
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 2
|
||||
@2
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 3
|
||||
@3
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 4
|
||||
@4
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END0)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END1)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END2)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END3)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// function Sys.add12 0
|
||||
(Sys.add12)
|
||||
// push constant 4002
|
||||
@4002
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THIS
|
||||
M=D
|
||||
// push constant 5002
|
||||
@5002
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 12
|
||||
@12
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END4)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// 0
|
||||
707
projects/08/FunctionCalls/NestedCall/NestedCall.asm
Normal file
707
projects/08/FunctionCalls/NestedCall/NestedCall.asm
Normal file
@@ -0,0 +1,707 @@
|
||||
@256
|
||||
D=A
|
||||
@SP
|
||||
M=D
|
||||
// call Sys.init 0
|
||||
@$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@5
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Sys.init
|
||||
-1;JMP
|
||||
($ret.0)
|
||||
// function Sys.init 0
|
||||
(Sys.init)
|
||||
// push constant 4000
|
||||
@4000
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@THIS
|
||||
M=D
|
||||
// push constant 5000
|
||||
@5000
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// call Sys.main 0
|
||||
@Sys.init$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@5
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Sys.main
|
||||
-1;JMP
|
||||
(Sys.init$ret.0)
|
||||
// pop temp 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R6
|
||||
M=D
|
||||
// label LOOP 0
|
||||
(Sys.init$LOOP)
|
||||
// goto LOOP 0
|
||||
@Sys.init$LOOP
|
||||
-1;JMP
|
||||
// function Sys.main 5
|
||||
(Sys.main)
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 4001
|
||||
@4001
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@THIS
|
||||
M=D
|
||||
// push constant 5001
|
||||
@5001
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// push constant 200
|
||||
@200
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@1
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R15
|
||||
M=D
|
||||
@R14
|
||||
D=M
|
||||
@R15
|
||||
A=M
|
||||
M=D
|
||||
// push constant 40
|
||||
@40
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 2
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@2
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R15
|
||||
M=D
|
||||
@R14
|
||||
D=M
|
||||
@R15
|
||||
A=M
|
||||
M=D
|
||||
// push constant 6
|
||||
@6
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 3
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@3
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R15
|
||||
M=D
|
||||
@R14
|
||||
D=M
|
||||
@R15
|
||||
A=M
|
||||
M=D
|
||||
// push constant 123
|
||||
@123
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// call Sys.add12 1
|
||||
@Sys.main$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@6
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Sys.add12
|
||||
-1;JMP
|
||||
(Sys.main$ret.0)
|
||||
// pop temp 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R5
|
||||
M=D
|
||||
// push local 0
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 1
|
||||
@1
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 2
|
||||
@2
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 3
|
||||
@3
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 4
|
||||
@4
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END0)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END1)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END2)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END3)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// function Sys.add12 0
|
||||
(Sys.add12)
|
||||
// push constant 4002
|
||||
@4002
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@THIS
|
||||
M=D
|
||||
// push constant 5002
|
||||
@5002
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 12
|
||||
@12
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END4)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// 0
|
||||
2
projects/08/FunctionCalls/NestedCall/NestedCall.cmp
Normal file
2
projects/08/FunctionCalls/NestedCall/NestedCall.cmp
Normal file
@@ -0,0 +1,2 @@
|
||||
| RAM[0] | RAM[1] | RAM[2] | RAM[3] | RAM[4] | RAM[5] | RAM[6] |
|
||||
| 261 | 261 | 256 | 4000 | 5000 | 135 | 246 |
|
||||
196
projects/08/FunctionCalls/NestedCall/NestedCall.html
Normal file
196
projects/08/FunctionCalls/NestedCall/NestedCall.html
Normal file
@@ -0,0 +1,196 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>NestedCall.tst — Nand2Tetris Calling Convention Test</title>
|
||||
<style type="text/css">
|
||||
.code {font-family:"Courier New", Courier, monospace; font-size:90%;}
|
||||
pre {margin-left:2em;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<h3>Synopsis</h3>
|
||||
<b>NestedCall.tst</b> is an intermediate test (in terms of complexity) intended to be used between the SimpleFunction and
|
||||
FibonacciElement tests. It may be useful when SimpleFunction passes but FibonacciElement fails or crashes. NestedCall also
|
||||
tests several requirements of the Function Calling Protocol that are not verified by the other
|
||||
supplied tests. NestedCall can be used with or without the VM bootstrap code.
|
||||
<p>
|
||||
<b>NestedCallVME.tst</b> runs the same test on the VM Emulator.
|
||||
<p>
|
||||
<b>The NestedCall</b> tests and supporting documentation were written by Mark Armbrust.
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<h3>Test Structure</h3>
|
||||
<h4>Startup</h4>
|
||||
NestedCall is implemented entirely within the Sys.vm file. The first function in Sys.vm is
|
||||
Sys.init(). This allows it to be used before the bootstrap code has been added to the VM Translator
|
||||
since there will be no file processing order issues.
|
||||
<p>
|
||||
NestedCall loads Sys.asm, sets up the stack to simulate the bootstrap's call to Sys.init(), then
|
||||
begins execution at the beginning of Sys.asm. If the bootstrap is not present, the program begins
|
||||
running with Sys.init() since it is the first function in Sys.vm.
|
||||
<p>
|
||||
If Sys.asm includes the bootstrap, the bootstrap will (re)initialize the stack and call Sys.init(),
|
||||
so the test should see the same environment either way it gets to Sys.init().
|
||||
<p>
|
||||
The test setup also initializes the
|
||||
|
||||
<h4>Sys.init()</h4>
|
||||
|
||||
<span class="code">THIS</span> and <span class="code">THAT</span> are set to known values so that context save and restore can be tested.
|
||||
<p>
|
||||
Sys.init() calls Sys.main() and stores the return value in <span class="code">temp 1</span>. This tests call to and
|
||||
return from a function with no arguments.
|
||||
|
||||
<h4>Sys.main()</h4>
|
||||
Sys.init() allocates 5 local variables. It sets <span class="code">local 1</span>, <span class="code">local 2</span> and
|
||||
<span class="code">local 3</span>. <span class="code">local 0</span> and <span class="code">local 4</span> are intentionally not set.
|
||||
<p>
|
||||
<span class="code">THIS</span> and <span class="code">THAT</span> are changed so that context save and restore can be tested.
|
||||
<p>
|
||||
Sys.main() calls Sys.add12(123) and stores the return value in <span class="code">temp 0</span>. This tests call to and
|
||||
return from a function with arguments.
|
||||
<p>
|
||||
After Sys.add12() returns, Sys.main() sums <span class="code">local 0</span> through <span class="code">local 4</span> and returns the
|
||||
result. This tests that the local segment was properly allocated on the stack and that the local
|
||||
variables were not overwritten by the call to Sys.main(). It also tests that <span class="code">local 0</span> and
|
||||
<span class="code">local 4</span> were properly initialized to 0.
|
||||
|
||||
<h4>Sys.add12()</h4>
|
||||
|
||||
<span class="code">THIS</span> and <span class="code">THAT</span> are set to known values so that context save and restore can be tested.
|
||||
<p>
|
||||
Returns <span class="code">argument 0</span> plus 12.
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<h3>Test Coverage</h3>
|
||||
|
||||
<p style="margin-left:1em; text-indent:-1em;">
|
||||
Functions with no arguments return to correct RIP (Return Instruction Point) with correct return value on stack.<br>
|
||||
This can fail if the RIP is not correctly pushed on the stack by the calling code, or if the returning
|
||||
code does not store the RIP in a temporary register before overwriting it with the return value.
|
||||
|
||||
<p style="margin-left:1em; text-indent:-1em;">
|
||||
Functions with arguments return to correct RIP with correct return value on stack.<br>
|
||||
This can fail if it is assumed that <span class="code">ARG</span> points to the RIP.
|
||||
|
||||
<p style="margin-left:1em; text-indent:-1em;">
|
||||
Functions with local variables allocate space on the stack for the local variables.<br>
|
||||
This can fail if the function prologue is not written or if the SP is not updated after zeroing
|
||||
the local variables.
|
||||
|
||||
<p style="margin-left:1em; text-indent:-1em;">
|
||||
All local variables are initialized to 0.<br>
|
||||
Common errors are to forget this completely, or for the zeroing loop to be off by one.
|
||||
|
||||
<p style="margin-left:1em; text-indent:-1em;">
|
||||
<span class="code">THIS</span> and <span class="code">THAT</span> are correctly retained across function calls. Looking ahead, in Project 9 you will be asked to write a simple computer game in the high-level Jack language. You can run your game (following compilation) on the supplied VM Emulator. But, if you choose to translate the VM code that the compiler generates using <em>your</em> VM Translator, then code like
|
||||
"<span class="code">push THIS</span>, <span class="code">push THAT</span> ... <span class="code">pop THIS</span>, <span class="code">pop THAT</span>" can cause some interesting failures!
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<h3>Debugging</h3>
|
||||
These comments assume that your VM translator has passed the SimpleFunction test.
|
||||
<p>
|
||||
If <span class="code">RAM[0]</span> is incorrect, you have a stack skew. More data was pushed onto the stack by
|
||||
<span class="code">call</span> than was popped by <span class="code">return</span>, or vice versa. See <i>debugging with
|
||||
breakpoints</i> later in this section.
|
||||
<p>
|
||||
If one or more of <span class="code">RAM[1]</span> through <span class="code">RAM[4]</span> is incorrect, the <span class="code">LCL</span>,
|
||||
<span class="code">ARG</span>, <span class="code">THIS</span> and <span class="code">THAT</span> pointers are not being correctly saved or restored.
|
||||
Most likely problem is when they are being saved; the SimpleFunction test verified that
|
||||
<span class="code">return</span> restored them correctly.
|
||||
<p>
|
||||
If <span class="code">RAM[5]</span> is incorrect there may be a problem with setting up the <span class="code">ARG</span> pointer.
|
||||
<p>
|
||||
If <span class="code">RAM[4]</span> is incorrect and <span class="code">RAM[5]</span> is correct, there may be a problem with
|
||||
allocation or initialization of local variables.
|
||||
|
||||
<h4>Debugging with breakpoints</h4>
|
||||
|
||||
To find tough bugs you can use the "breakpoint" facility in the CPU Emulator (red flag button).
|
||||
You can use breakpoints to have you program stop when it gets to a particular RAM address. For
|
||||
example:<br>
|
||||
 • load the NestedCall.tst file,<br>
|
||||
 • set a PC breakpoint at the ROM address for <span class="code">(Sys.main)</span>,<br>
|
||||
 • hit the run button.<br>
|
||||
When the CPU Emulator stops at the breakpoint you can inspect the RAM to check the stack and pointers values.
|
||||
(If the breakpoint isn't hit, you will need to to single-step debug through
|
||||
your calling code to see why it didn't get there.)
|
||||
<p>
|
||||
Other useful places to set breakpoints are the entry points to the other functions and at the
|
||||
first and final instructions generated for <span class="code">return</span> commands.
|
||||
<p>
|
||||
<a href="NestedCallStack.html">NestedCallStack.html</a> shows the expected stack values at various points
|
||||
during the test.
|
||||
|
||||
<h4>Finding ROM address in your ASM code</h4>
|
||||
It is not easy to find the ROM locations where you want to set breakpoints, because there is no
|
||||
one-to-one correspondence between the ASM file line numbers and the ROM addresses. This is made even more
|
||||
difficult because the supplied CPU Emulator does not display the (LABELS) in its ROM panel.
|
||||
<p>
|
||||
There are two things that you can do to make this easier.
|
||||
<p>
|
||||
<h5>Modify your assembler to generate a listing file.</h5>
|
||||
A listing file shows all the ASM source lines, including comments, as well as the ROM addresses and
|
||||
the values of the labels and the instructions. For example, here is a snippet of a listing file generated by an assembler written by Mark Armbrust:
|
||||
<pre>
|
||||
20 16 @i // i -= 1
|
||||
21 FC88 M=M-1
|
||||
|
||||
22 FC10 D=M // if i > 0
|
||||
23 6 @LOOP
|
||||
24 E301 D;JGT // goto LOOP
|
||||
|
||||
25 (STOP)
|
||||
25 25 @STOP
|
||||
26 EA87 0;JMP
|
||||
|
||||
Data Symbols
|
||||
|
||||
16 D i
|
||||
|
||||
Code Symbols
|
||||
|
||||
6 C LOOP
|
||||
17 C SKIP
|
||||
25 C STOP
|
||||
</pre>
|
||||
For the Nand2Tetris environment, it is most useful to list the ROM addresses and A-instruction
|
||||
values in decimal. In the above snippet, the C-instruction values are
|
||||
listed in hexadecimal.
|
||||
<p>
|
||||
The list file is generated during pass 2 of the Assembler, parallel to generating the .hack file. To
|
||||
make it easier to handle blank and comment only lines, Mark has Parser.commandType() return
|
||||
NO_COMMAND for source lines with no command. Mark also added Parser.sourceLine() that returns the
|
||||
unmodified source line.
|
||||
<p>
|
||||
<h5>Have your VM Translator write the VM source lines as comments in the ASM output.</h5>
|
||||
For example:
|
||||
<pre>
|
||||
// label LOOP
|
||||
(Sys.init$LOOP)
|
||||
// goto LOOP
|
||||
@Sys.init$LOOP
|
||||
0;JMP
|
||||
//
|
||||
// // Sys.main()
|
||||
//
|
||||
// // Sets locals 1, 2 and 3, leaving locals 0 and 4 unchanged to test
|
||||
// // default local initialization to 0. (RAM set to -1 by test setup.)
|
||||
// // Calls Sys.add12(123) and stores return value (135) in temp 0.
|
||||
// // Returns local 0 + local 1 + local 2 + local 3 + local 4 (456) to confirm
|
||||
// // that locals were not mangled by function call.
|
||||
//
|
||||
// function Sys.main 5
|
||||
(Sys.main)
|
||||
@5
|
||||
D=-A
|
||||
($3)
|
||||
@SP
|
||||
</pre>
|
||||
Note that comments in the VM source become double comments. Looking ahead, in Project 11 you will be asked to write a compiler for the Jack language. If your compiler will write the Jack source lines as comments in the
|
||||
generated VM files, this convention will be quite useful.
|
||||
|
||||
</body>
|
||||
</html>
|
||||
65
projects/08/FunctionCalls/NestedCall/NestedCall.tst
Normal file
65
projects/08/FunctionCalls/NestedCall/NestedCall.tst
Normal file
@@ -0,0 +1,65 @@
|
||||
// Test file for NestedCall test.
|
||||
|
||||
load NestedCall.asm,
|
||||
output-file NestedCall.out,
|
||||
compare-to NestedCall.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[1]%D1.6.1 RAM[2]%D1.6.1 RAM[3]%D1.6.1 RAM[4]%D1.6.1 RAM[5]%D1.6.1 RAM[6]%D1.6.1;
|
||||
|
||||
set RAM[0] 261,
|
||||
set RAM[1] 261,
|
||||
set RAM[2] 256,
|
||||
set RAM[3] -3,
|
||||
set RAM[4] -4,
|
||||
set RAM[5] -1, // test results
|
||||
set RAM[6] -1,
|
||||
set RAM[256] 1234, // fake stack frame from call Sys.init
|
||||
set RAM[257] -1,
|
||||
set RAM[258] -2,
|
||||
set RAM[259] -3,
|
||||
set RAM[260] -4,
|
||||
|
||||
set RAM[261] -1, // Initialize stack to check for local segment
|
||||
set RAM[262] -1, // being cleared to zero.
|
||||
set RAM[263] -1,
|
||||
set RAM[264] -1,
|
||||
set RAM[265] -1,
|
||||
set RAM[266] -1,
|
||||
set RAM[267] -1,
|
||||
set RAM[268] -1,
|
||||
set RAM[269] -1,
|
||||
set RAM[270] -1,
|
||||
set RAM[271] -1,
|
||||
set RAM[272] -1,
|
||||
set RAM[273] -1,
|
||||
set RAM[274] -1,
|
||||
set RAM[275] -1,
|
||||
set RAM[276] -1,
|
||||
set RAM[277] -1,
|
||||
set RAM[278] -1,
|
||||
set RAM[279] -1,
|
||||
set RAM[280] -1,
|
||||
set RAM[281] -1,
|
||||
set RAM[282] -1,
|
||||
set RAM[283] -1,
|
||||
set RAM[284] -1,
|
||||
set RAM[285] -1,
|
||||
set RAM[286] -1,
|
||||
set RAM[287] -1,
|
||||
set RAM[288] -1,
|
||||
set RAM[289] -1,
|
||||
set RAM[290] -1,
|
||||
set RAM[291] -1,
|
||||
set RAM[292] -1,
|
||||
set RAM[293] -1,
|
||||
set RAM[294] -1,
|
||||
set RAM[295] -1,
|
||||
set RAM[296] -1,
|
||||
set RAM[297] -1,
|
||||
set RAM[298] -1,
|
||||
set RAM[299] -1,
|
||||
|
||||
repeat 4000 {
|
||||
ticktock;
|
||||
}
|
||||
|
||||
output;
|
||||
306
projects/08/FunctionCalls/NestedCall/NestedCallStack.html
Normal file
306
projects/08/FunctionCalls/NestedCall/NestedCallStack.html
Normal file
@@ -0,0 +1,306 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>NestedCall.tst — Stack Frames</title>
|
||||
<style type="text/css">
|
||||
.stack {border-collapse:collapse; font-size:80%;}
|
||||
.stack td {padding-left:.25em;padding-right:.25em;white-space:nowrap;}
|
||||
.stack td:first-child {text-align:right;}
|
||||
.stack td:first-child + td {text-align:right;}
|
||||
.stack td:first-child + td + td {text-align:left;}
|
||||
.stack td:first-child + td + td + td {text-align:left;}
|
||||
.stack .reg {border-left:1px solid; border-right:1px solid;}
|
||||
.stack .reg th {border:1px solid;}
|
||||
.stack .stack {border-left:1px solid; border-right:1px solid;}
|
||||
.stack .stack th {border:1px solid;}
|
||||
.stack .tos {border-left:1px solid; border-right:1px solid;border-bottom:1px solid;}
|
||||
.stack .frame {border-left:1px solid; border-right:1px solid;}
|
||||
.stack .frame td:first-child + td {border-left:1px solid;}
|
||||
.stack .frame td:first-child + td + td {border-right:1px solid;}
|
||||
.stack .framet {border-left:1px solid; border-right:1px solid;}
|
||||
.stack .framet td:first-child + td {border-left:1px solid;border-top:1px solid;}
|
||||
.stack .framet td:first-child + td + td {border-right:1px solid;border-top:1px solid;}
|
||||
.stack .bframe {border-left:1px solid; border-right:1px solid;}
|
||||
.stack .bframe td:first-child + td {border-left:2px solid;}
|
||||
.stack .bframe td:first-child + td + td {border-right:2px solid;}
|
||||
.stack .bframet {border-left:1px solid; border-right:1px solid;}
|
||||
.stack .bframet td:first-child + td {border-left:2px solid;border-top:2px solid;}
|
||||
.stack .bframet td:first-child + td + td {border-right:2px solid;border-top:2px solid;}
|
||||
.stack .bframeb {border-left:1px solid; border-right:1px solid;}
|
||||
.stack .bframeb td:first-child + td {border-left:2px solid;border-bottom:2px solid;}
|
||||
.stack .bframeb td:first-child + td + td {border-right:2px solid;border-bottom:2px solid;}
|
||||
.stack .note td {padding-left:.5em;padding-right:.5em;white-space:normal;text-align:justify;}
|
||||
.stack .fid {font-style:italic}
|
||||
.master {width: 10%;}
|
||||
.master td {vertical-align:top;padding-right:.5em; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<table class="master">
|
||||
<tr>
|
||||
<td>
|
||||
<table class="stack">
|
||||
<tr><th colspan="4">Bootstrap init</th></tr>
|
||||
<tr class="reg"><th colspan="4">Pointers</th></tr>
|
||||
<tr class="reg"><td>0</td><td>256</td><td>SP</td><td></td></tr>
|
||||
<tr class="reg"><td>1</td><td>-1</td><td>LCL</td><td></td></tr>
|
||||
<tr class="reg"><td>2</td><td>-2</td><td>ARG</td><td></td></tr>
|
||||
<tr class="reg"><td>3</td><td>-3</td><td>THIS</td><td></td></tr>
|
||||
<tr class="reg"><td>4</td><td>-4</td><td>THAT</td><td></td></tr>
|
||||
<tr class="stack"><th colspan="4">Stack</th></tr>
|
||||
<tr class="tos"><td>256</td><td>???</td><td></td><td>←SP</td></tr>
|
||||
<tr class="note"><td colspan="4"><br>
|
||||
This is how my boot­strap code initial­izes the pointers before calling Sys.init().
|
||||
<p>
|
||||
Setting the LCL, ARG, THIS and THAT point­ers to known illegal values helps identify
|
||||
when a pointer is used before it is initial­ized.
|
||||
<p>
|
||||
(If you are running the NestedCall test with­out boot­strap code, you will not see this state.)</td></tr>
|
||||
</table>
|
||||
</td><td>
|
||||
<table class="stack">
|
||||
<tr><th colspan="4">Entry to Sys.init()</th></tr>
|
||||
<tr class="reg"><th colspan="4">Pointers</th></tr>
|
||||
<tr class="reg"><td>0</td><td>261</td><td>SP</td><td></td></tr>
|
||||
<tr class="reg"><td>1</td><td>261</td><td>LCL</td><td></td></tr>
|
||||
<tr class="reg"><td>2</td><td>256</td><td>ARG</td><td></td></tr>
|
||||
<tr class="reg"><td>3</td><td>-3</td><td>THIS</td><td></td></tr>
|
||||
<tr class="reg"><td>4</td><td>-4</td><td>THAT</td><td></td></tr>
|
||||
<tr class="stack"><th colspan="4">Stack</th></tr>
|
||||
<tr class="bframet"><td>256</td><td>*</td><td>Return IP</td><td>←ARG</td></tr>
|
||||
<tr class="bframe"><td>257</td><td>-1</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="bframe"><td>258</td><td>-2</td><td>Saved ARG</td><td class="fid">Sys.init</td></tr>
|
||||
<tr class="bframe"><td>259</td><td>-3</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="bframeb"><td>260</td><td>-4</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="tos"><td>261</td><td>???</td><td></td><td>←LCL, SP</td></tr>
|
||||
<tr class="note"><td colspan="4"><br>
|
||||
This is how NestedCall.tst initial­izes the pointers and stack. This is what RAM looks
|
||||
like after my boot­strap calls Sys.init().
|
||||
<p>
|
||||
(If your VM trans­lation includes the boot­strap, the -1 through -4 values may be
|
||||
different if your boot­strap initial­izes them.)</td></tr>
|
||||
</table>
|
||||
</td><td>
|
||||
<table class="stack">
|
||||
<tr><th colspan="4">Entry to Sys.main()</th></tr>
|
||||
<tr class="reg"><th colspan="4">Pointers</th></tr>
|
||||
<tr class="reg"><td>0</td><td>266</td><td>SP</td><td></td></tr>
|
||||
<tr class="reg"><td>1</td><td>266</td><td>LCL</td><td></td></tr>
|
||||
<tr class="reg"><td>2</td><td>261</td><td>ARG</td><td></td></tr>
|
||||
<tr class="reg"><td>3</td><td>4000</td><td>THIS</td><td></td></tr>
|
||||
<tr class="reg"><td>4</td><td>5000</td><td>THAT</td><td></td></tr>
|
||||
<tr class="stack"><th colspan="4">Stack</th></tr>
|
||||
<tr class="framet"><td>256</td><td>*</td><td>Return IP</td><td></td></tr>
|
||||
<tr class="frame"><td>257</td><td>-1</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="frame"><td>258</td><td>-2</td><td>Saved ARG</td><td class="fid">Sys.init</td></tr>
|
||||
<tr class="frame"><td>259</td><td>-3</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="frame"><td>260</td><td>-4</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="bframet"><td>261</td><td>*</td><td>Return IP</td><td>←ARG</td></tr>
|
||||
<tr class="bframe"><td>262</td><td>261</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="bframe"><td>263</td><td>256</td><td>Saved ARG</td><td class="fid">Sys.main</td></tr>
|
||||
<tr class="bframe"><td>264</td><td>4000</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="bframeb"><td>265</td><td>5000</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="tos"><td>266</td><td>???</td><td></td><td>←LCL, SP</td></tr>
|
||||
</table>
|
||||
</td><td>
|
||||
<table class="stack">
|
||||
<tr><th colspan="4">After Sys.main() prologue</th></tr>
|
||||
<tr class="reg"><th colspan="4">Pointers</th></tr>
|
||||
<tr class="reg"><td>0</td><td>271</td><td>SP</td><td></td></tr>
|
||||
<tr class="reg"><td>1</td><td>266</td><td>LCL</td><td></td></tr>
|
||||
<tr class="reg"><td>2</td><td>261</td><td>ARG</td><td></td></tr>
|
||||
<tr class="reg"><td>3</td><td>4000</td><td>THIS</td><td></td></tr>
|
||||
<tr class="reg"><td>4</td><td>5000</td><td>THAT</td><td></td></tr>
|
||||
<tr class="stack"><th colspan="4">Stack</th></tr>
|
||||
<tr class="framet"><td>256</td><td>*</td><td>Return IP</td><td></td></tr>
|
||||
<tr class="frame"><td>257</td><td>-1</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="frame"><td>258</td><td>-2</td><td>Saved ARG</td><td class="fid">Sys.init</td></tr>
|
||||
<tr class="frame"><td>259</td><td>-3</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="frame"><td>260</td><td>-4</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="bframet"><td>261</td><td>*</td><td>Return IP</td><td>←ARG</td></tr>
|
||||
<tr class="bframe"><td>262</td><td>261</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="bframe"><td>263</td><td>256</td><td>Saved ARG</td><td class="fid">Sys.main</td></tr>
|
||||
<tr class="bframe"><td>264</td><td>4000</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="bframe"><td>265</td><td>5000</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="bframe"><td>266</td><td>0</td><td>local 0</td><td>←LCL</td></tr>
|
||||
<tr class="bframe"><td>267</td><td>0</td><td>local 1</td><td></td></tr>
|
||||
<tr class="bframe"><td>268</td><td>0</td><td>local 2</td><td></td></tr>
|
||||
<tr class="bframe"><td>269</td><td>0</td><td>local 3</td><td></td></tr>
|
||||
<tr class="bframeb"><td>270</td><td>0</td><td>local 4</td><td></td></tr>
|
||||
<tr class="tos"><td>271</td><td>???</td><td></td><td>←SP</td></tr>
|
||||
<tr class="note"><td colspan="4"><br>
|
||||
The <i>function prologue</i> is the assembly language code generated for the
|
||||
"function" VM command.
|
||||
</table>
|
||||
</td><td>
|
||||
<table class="stack">
|
||||
<tr><th colspan="4">Entry to Sys.add12(123)</th></tr>
|
||||
<tr class="reg"><th colspan="4">Pointers</th></tr>
|
||||
<tr class="reg"><td>0</td><td>277</td><td>SP</td><td></td></tr>
|
||||
<tr class="reg"><td>1</td><td>277</td><td>LCL</td><td></td></tr>
|
||||
<tr class="reg"><td>2</td><td>271</td><td>ARG</td><td></td></tr>
|
||||
<tr class="reg"><td>3</td><td>4001</td><td>THIS</td><td></td></tr>
|
||||
<tr class="reg"><td>4</td><td>5001</td><td>THAT</td><td></td></tr>
|
||||
<tr class="stack"><th colspan="4">Stack</th></tr>
|
||||
<tr class="framet"><td>256</td><td>*</td><td>Return IP</td><td></td></tr>
|
||||
<tr class="frame"><td>257</td><td>-1</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="frame"><td>258</td><td>-2</td><td>Saved ARG</td><td class="fid">Sys.init</td></tr>
|
||||
<tr class="frame"><td>259</td><td>-3</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="frame"><td>260</td><td>-4</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="framet"><td>261</td><td>*</td><td>Return IP</td><td></td></tr>
|
||||
<tr class="frame"><td>262</td><td>261</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="frame"><td>263</td><td>256</td><td>Saved ARG</td><td class="fid">Sys.main</td></tr>
|
||||
<tr class="frame"><td>264</td><td>4000</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="frame"><td>265</td><td>5000</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="frame"><td>266</td><td>0</td><td>local 0</td><td></td></tr>
|
||||
<tr class="frame"><td>267</td><td>200</td><td>local 1</td><td></td></tr>
|
||||
<tr class="frame"><td>268</td><td>40</td><td>local 2</td><td></td></tr>
|
||||
<tr class="frame"><td>269</td><td>6</td><td>local 3</td><td></td></tr>
|
||||
<tr class="frame"><td>270</td><td>0</td><td>local 4</td><td></td></tr>
|
||||
<tr class="bframet"><td>271</td><td>123</td><td>argument 0</td><td>←ARG</td></tr>
|
||||
<tr class="bframe"><td>272</td><td>*</td><td>Return IP</td><td></td></tr>
|
||||
<tr class="bframe"><td>273</td><td>266</td><td>Saved LCL</td><td class="fid">Sys.add12</td></tr>
|
||||
<tr class="bframe"><td>274</td><td>261</td><td>Saved ARG</td><td class="fid"> frame</td></tr>
|
||||
<tr class="bframe"><td>275</td><td>4001</td><td>Saved THIS</td><td></td></tr>
|
||||
<tr class="bframeb"><td>276</td><td>5001</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="tos"><td>277</td><td>???</td><td></td><td>←LCL, SP</td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr></table>
|
||||
|
||||
<p>
|
||||
|
||||
<table class="master">
|
||||
<tr>
|
||||
<td>
|
||||
<table class="stack">
|
||||
<tr><th colspan="4">Before Sys.add12() return</th></tr>
|
||||
<tr class="reg"><th colspan="4">Pointers</th></tr>
|
||||
<tr class="reg"><td>0</td><td>278</td><td>SP</td><td></td></tr>
|
||||
<tr class="reg"><td>1</td><td>277</td><td>LCL</td><td></td></tr>
|
||||
<tr class="reg"><td>2</td><td>271</td><td>ARG</td><td></td></tr>
|
||||
<tr class="reg"><td>3</td><td>4002</td><td>THIS</td><td></td></tr>
|
||||
<tr class="reg"><td>4</td><td>5002</td><td>THAT</td><td></td></tr>
|
||||
<tr class="stack"><th colspan="4">Stack</th></tr>
|
||||
<tr class="framet"><td>256</td><td>*</td><td>Return IP</td><td></td></tr>
|
||||
<tr class="frame"><td>257</td><td>-1</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="frame"><td>258</td><td>-2</td><td>Saved ARG</td><td class="fid">Sys.init</td></tr>
|
||||
<tr class="frame"><td>259</td><td>-3</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="frame"><td>260</td><td>-4</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="framet"><td>261</td><td>*</td><td>Return IP</td><td></td></tr>
|
||||
<tr class="frame"><td>262</td><td>261</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="frame"><td>263</td><td>256</td><td>Saved ARG</td><td class="fid">Sys.main</td></tr>
|
||||
<tr class="frame"><td>264</td><td>4000</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="frame"><td>265</td><td>5000</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="frame"><td>266</td><td>0</td><td>local 0</td><td></td></tr>
|
||||
<tr class="frame"><td>267</td><td>200</td><td>local 1</td><td></td></tr>
|
||||
<tr class="frame"><td>268</td><td>40</td><td>local 2</td><td></td></tr>
|
||||
<tr class="frame"><td>269</td><td>6</td><td>local 3</td><td></td></tr>
|
||||
<tr class="frame"><td>270</td><td>0</td><td>local 4</td><td></td></tr>
|
||||
<tr class="bframet"><td>271</td><td>123</td><td>argument 0</td><td>←ARG</td></tr>
|
||||
<tr class="bframe"><td>272</td><td>*</td><td>Return IP</td><td></td></tr>
|
||||
<tr class="bframe"><td>273</td><td>266</td><td>Saved LCL</td><td class="fid">Sys.add12</td></tr>
|
||||
<tr class="bframe"><td>274</td><td>261</td><td>Saved ARG</td><td class="fid"> frame</td></tr>
|
||||
<tr class="bframe"><td>275</td><td>4001</td><td>Saved THIS</td><td></td></tr>
|
||||
<tr class="bframe"><td>276</td><td>5001</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="bframeb"><td>277</td><td>135</td><td>Return value</td><td>←LCL</td></tr>
|
||||
<tr class="tos"><td>278</td><td>???</td><td></td><td>←SP</td></tr>
|
||||
</table>
|
||||
</td><td>
|
||||
<table class="stack">
|
||||
<tr><th colspan="4">After Sys.add12() return</th></tr>
|
||||
<tr class="reg"><th colspan="4">Pointers</th></tr>
|
||||
<tr class="reg"><td>0</td><td>272</td><td>SP</td><td></td></tr>
|
||||
<tr class="reg"><td>1</td><td>266</td><td>LCL</td><td></td></tr>
|
||||
<tr class="reg"><td>2</td><td>261</td><td>ARG</td><td></td></tr>
|
||||
<tr class="reg"><td>3</td><td>4001</td><td>THIS</td><td></td></tr>
|
||||
<tr class="reg"><td>4</td><td>5001</td><td>THAT</td><td></td></tr>
|
||||
<tr class="stack"><th colspan="4">Stack</th></tr>
|
||||
<tr class="framet"><td>256</td><td>*</td><td>Return IP</td><td></td></tr>
|
||||
<tr class="frame"><td>257</td><td>-1</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="frame"><td>258</td><td>-2</td><td>Saved ARG</td><td class="fid">Sys.init</td></tr>
|
||||
<tr class="frame"><td>259</td><td>-3</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="frame"><td>260</td><td>-4</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="bframet"><td>261</td><td>*</td><td>Return IP</td><td>←ARG</td></tr>
|
||||
<tr class="bframe"><td>262</td><td>261</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="bframe"><td>263</td><td>256</td><td>Saved ARG</td><td class="fid">Sys.main</td></tr>
|
||||
<tr class="bframe"><td>264</td><td>4000</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="bframe"><td>265</td><td>5000</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="bframe"><td>266</td><td>0</td><td>local 0</td><td>←LCL</td></tr>
|
||||
<tr class="bframe"><td>267</td><td>200</td><td>local 1</td><td></td></tr>
|
||||
<tr class="bframe"><td>268</td><td>40</td><td>local 2</td><td></td></tr>
|
||||
<tr class="bframe"><td>269</td><td>6</td><td>local 3</td><td></td></tr>
|
||||
<tr class="bframe"><td>270</td><td>0</td><td>local 4</td><td></td></tr>
|
||||
<tr class="bframeb"><td>271</td><td>135</td><td>Return value</td><td></td></tr>
|
||||
<tr class="tos"><td>272</td><td>???</td><td></td><td>←SP</td></tr>
|
||||
</table>
|
||||
</td><td>
|
||||
<table class="stack">
|
||||
<tr><th colspan="4">Before Sys.main() return</th></tr>
|
||||
<tr class="reg"><th colspan="4">Pointers</th></tr>
|
||||
<tr class="reg"><td>0</td><td>272</td><td>SP</td><td></td></tr>
|
||||
<tr class="reg"><td>1</td><td>266</td><td>LCL</td><td></td></tr>
|
||||
<tr class="reg"><td>2</td><td>261</td><td>ARG</td><td></td></tr>
|
||||
<tr class="reg"><td>3</td><td>4001</td><td>THIS</td><td></td></tr>
|
||||
<tr class="reg"><td>4</td><td>5001</td><td>THAT</td><td></td></tr>
|
||||
<tr class="stack"><th colspan="4">Stack</th></tr>
|
||||
<tr class="framet"><td>256</td><td>*</td><td>Return IP</td><td></td></tr>
|
||||
<tr class="frame"><td>257</td><td>-1</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="frame"><td>258</td><td>-2</td><td>Saved ARG</td><td class="fid">Sys.init</td></tr>
|
||||
<tr class="frame"><td>259</td><td>-3</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="frame"><td>260</td><td>-4</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="bframet"><td>261</td><td>*</td><td>Return IP</td><td>←ARG</td></tr>
|
||||
<tr class="bframe"><td>262</td><td>261</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="bframe"><td>263</td><td>256</td><td>Saved ARG</td><td class="fid">Sys.main</td></tr>
|
||||
<tr class="bframe"><td>264</td><td>4000</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="bframe"><td>265</td><td>5000</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="bframe"><td>266</td><td>0</td><td>local 0</td><td>←LCL</td></tr>
|
||||
<tr class="bframe"><td>267</td><td>200</td><td>local 1</td><td></td></tr>
|
||||
<tr class="bframe"><td>268</td><td>40</td><td>local 2</td><td></td></tr>
|
||||
<tr class="bframe"><td>269</td><td>6</td><td>local 3</td><td></td></tr>
|
||||
<tr class="bframe"><td>270</td><td>0</td><td>local 4</td><td></td></tr>
|
||||
<tr class="bframeb"><td>271</td><td>246</td><td>Return value</td><td></td></tr>
|
||||
<tr class="tos"><td>272</td><td>???</td><td></td><td>←SP</td></tr>
|
||||
</table>
|
||||
</td><td>
|
||||
<table class="stack">
|
||||
<tr><th colspan="4">After Sys.main() return</th></tr>
|
||||
<tr class="reg"><th colspan="4">Pointers</th></tr>
|
||||
<tr class="reg"><td>0</td><td>262</td><td>SP</td><td></td></tr>
|
||||
<tr class="reg"><td>1</td><td>261</td><td>LCL</td><td></td></tr>
|
||||
<tr class="reg"><td>2</td><td>256</td><td>ARG</td><td></td></tr>
|
||||
<tr class="reg"><td>3</td><td>4000</td><td>THIS</td><td></td></tr>
|
||||
<tr class="reg"><td>4</td><td>5000</td><td>THAT</td><td></td></tr>
|
||||
<tr class="stack"><th colspan="4">Stack</th></tr>
|
||||
<tr class="bframet"><td>256</td><td>*</td><td>Return IP</td><td>←ARG</td></tr>
|
||||
<tr class="bframe"><td>257</td><td>-1</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="bframe"><td>258</td><td>-2</td><td>Saved ARG</td><td class="fid">Sys.init</td></tr>
|
||||
<tr class="bframe"><td>259</td><td>-3</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="bframe"><td>260</td><td>-4</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="bframeb"><td>261</td><td>246</td><td>Return value</td><td>←LCL</td></tr>
|
||||
<tr class="tos"><td>262</td><td>???</td><td></td><td>←SP</td></tr>
|
||||
</table>
|
||||
</td><td>
|
||||
<table class="stack">
|
||||
<tr><th colspan="4">In Sys.init() halt loop</th></tr>
|
||||
<tr class="reg"><th colspan="4">Pointers</th></tr>
|
||||
<tr class="reg"><td>0</td><td>261</td><td>SP</td><td></td></tr>
|
||||
<tr class="reg"><td>1</td><td>261</td><td>LCL</td><td></td></tr>
|
||||
<tr class="reg"><td>2</td><td>256</td><td>ARG</td><td></td></tr>
|
||||
<tr class="reg"><td>3</td><td>4000</td><td>THIS</td><td></td></tr>
|
||||
<tr class="reg"><td>4</td><td>5000</td><td>THAT</td><td></td></tr>
|
||||
<tr class="stack"><th colspan="4">Stack</th></tr>
|
||||
<tr class="bframet"><td>256</td><td>*</td><td>Return IP</td><td>←ARG</td></tr>
|
||||
<tr class="bframe"><td>257</td><td>-1</td><td>Saved LCL</td><td></td></tr>
|
||||
<tr class="bframe"><td>258</td><td>-2</td><td>Saved ARG</td><td class="fid">Sys.init</td></tr>
|
||||
<tr class="bframe"><td>259</td><td>-3</td><td>Saved THIS</td><td class="fid"> frame</td></tr>
|
||||
<tr class="bframeb"><td>260</td><td>-4</td><td>Saved THAT</td><td></td></tr>
|
||||
<tr class="tos"><td>261</td><td>???</td><td></td><td>←LCL, SP</td></tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr></table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
70
projects/08/FunctionCalls/NestedCall/NestedCallVME.tst
Normal file
70
projects/08/FunctionCalls/NestedCall/NestedCallVME.tst
Normal file
@@ -0,0 +1,70 @@
|
||||
// Test file for NestedCall test.
|
||||
|
||||
load Sys.vm,
|
||||
output-file NestedCall.out,
|
||||
compare-to NestedCall.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[1]%D1.6.1 RAM[2]%D1.6.1 RAM[3]%D1.6.1 RAM[4]%D1.6.1 RAM[5]%D1.6.1 RAM[6]%D1.6.1;
|
||||
|
||||
set RAM[0] 261,
|
||||
set RAM[1] 261,
|
||||
set RAM[2] 256,
|
||||
set RAM[3] -3,
|
||||
set RAM[4] -4,
|
||||
set RAM[5] -1, // test results
|
||||
set RAM[6] -1,
|
||||
set RAM[256] 1234, // fake stack frame from call Sys.init
|
||||
set RAM[257] -1,
|
||||
set RAM[258] -2,
|
||||
set RAM[259] -3,
|
||||
set RAM[260] -4,
|
||||
|
||||
set RAM[261] -1, // Initialize stack to check for local segment
|
||||
set RAM[262] -1, // being cleared to zero.
|
||||
set RAM[263] -1,
|
||||
set RAM[264] -1,
|
||||
set RAM[265] -1,
|
||||
set RAM[266] -1,
|
||||
set RAM[267] -1,
|
||||
set RAM[268] -1,
|
||||
set RAM[269] -1,
|
||||
set RAM[270] -1,
|
||||
set RAM[271] -1,
|
||||
set RAM[272] -1,
|
||||
set RAM[273] -1,
|
||||
set RAM[274] -1,
|
||||
set RAM[275] -1,
|
||||
set RAM[276] -1,
|
||||
set RAM[277] -1,
|
||||
set RAM[278] -1,
|
||||
set RAM[279] -1,
|
||||
set RAM[280] -1,
|
||||
set RAM[281] -1,
|
||||
set RAM[282] -1,
|
||||
set RAM[283] -1,
|
||||
set RAM[284] -1,
|
||||
set RAM[285] -1,
|
||||
set RAM[286] -1,
|
||||
set RAM[287] -1,
|
||||
set RAM[288] -1,
|
||||
set RAM[289] -1,
|
||||
set RAM[290] -1,
|
||||
set RAM[291] -1,
|
||||
set RAM[292] -1,
|
||||
set RAM[293] -1,
|
||||
set RAM[294] -1,
|
||||
set RAM[295] -1,
|
||||
set RAM[296] -1,
|
||||
set RAM[297] -1,
|
||||
set RAM[298] -1,
|
||||
set RAM[299] -1,
|
||||
|
||||
set sp 261,
|
||||
set local 261,
|
||||
set argument 256,
|
||||
set this 3000,
|
||||
set that 4000;
|
||||
|
||||
repeat 50 {
|
||||
vmstep;
|
||||
}
|
||||
output;
|
||||
649
projects/08/FunctionCalls/NestedCall/Sys.asm
Normal file
649
projects/08/FunctionCalls/NestedCall/Sys.asm
Normal file
@@ -0,0 +1,649 @@
|
||||
// function Sys.init 0
|
||||
(Sys.init)
|
||||
// push constant 4000
|
||||
@4000
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THIS
|
||||
M=D
|
||||
// push constant 5000
|
||||
@5000
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// call Sys.main 0
|
||||
@Sys.init$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@5
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Sys.main
|
||||
-1;JMP
|
||||
(Sys.init$ret.0)
|
||||
// pop temp 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@R6
|
||||
M=D
|
||||
// label LOOP 0
|
||||
(Sys.init$LOOP)
|
||||
// goto LOOP 0
|
||||
@Sys.init$LOOP
|
||||
-1;JMP
|
||||
// function Sys.main 5
|
||||
(Sys.main)
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 4001
|
||||
@4001
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THIS
|
||||
M=D
|
||||
// push constant 5001
|
||||
@5001
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// push constant 200
|
||||
@200
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@1
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// push constant 40
|
||||
@40
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 2
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@2
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// push constant 6
|
||||
@6
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 3
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@3
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// push constant 123
|
||||
@123
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// call Sys.add12 1
|
||||
@Sys.main$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@6
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Sys.add12
|
||||
-1;JMP
|
||||
(Sys.main$ret.0)
|
||||
// pop temp 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@R5
|
||||
M=D
|
||||
// push local 0
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 1
|
||||
@1
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 2
|
||||
@2
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 3
|
||||
@3
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 4
|
||||
@4
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END0)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END1)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END2)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END3)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// function Sys.add12 0
|
||||
(Sys.add12)
|
||||
// push constant 4002
|
||||
@4002
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THIS
|
||||
M=D
|
||||
// push constant 5002
|
||||
@5002
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 12
|
||||
@12
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END4)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// 0
|
||||
63
projects/08/FunctionCalls/NestedCall/Sys.vm
Normal file
63
projects/08/FunctionCalls/NestedCall/Sys.vm
Normal file
@@ -0,0 +1,63 @@
|
||||
// Sys.vm for NestedCall test.
|
||||
|
||||
// Sys.init()
|
||||
//
|
||||
// Calls Sys.main() and stores return value in temp 1.
|
||||
// Does not return. (Enters infinite loop.)
|
||||
|
||||
function Sys.init 0
|
||||
push constant 4000 // test THIS and THAT context save
|
||||
pop pointer 0
|
||||
push constant 5000
|
||||
pop pointer 1
|
||||
call Sys.main 0
|
||||
pop temp 1
|
||||
label LOOP
|
||||
goto LOOP
|
||||
|
||||
// Sys.main()
|
||||
//
|
||||
// Sets locals 1, 2 and 3, leaving locals 0 and 4 unchanged to test
|
||||
// default local initialization to 0. (RAM set to -1 by test setup.)
|
||||
// Calls Sys.add12(123) and stores return value (135) in temp 0.
|
||||
// Returns local 0 + local 1 + local 2 + local 3 + local 4 (456) to confirm
|
||||
// that locals were not mangled by function call.
|
||||
|
||||
function Sys.main 5
|
||||
push constant 4001
|
||||
pop pointer 0
|
||||
push constant 5001
|
||||
pop pointer 1
|
||||
push constant 200
|
||||
pop local 1
|
||||
push constant 40
|
||||
pop local 2
|
||||
push constant 6
|
||||
pop local 3
|
||||
push constant 123
|
||||
call Sys.add12 1
|
||||
pop temp 0
|
||||
push local 0
|
||||
push local 1
|
||||
push local 2
|
||||
push local 3
|
||||
push local 4
|
||||
add
|
||||
add
|
||||
add
|
||||
add
|
||||
return
|
||||
|
||||
// Sys.add12(int n)
|
||||
//
|
||||
// Returns n+12.
|
||||
|
||||
function Sys.add12 0
|
||||
push constant 4002
|
||||
pop pointer 0
|
||||
push constant 5002
|
||||
pop pointer 1
|
||||
push argument 0
|
||||
push constant 12
|
||||
add
|
||||
return
|
||||
1
projects/08/FunctionCalls/SimpleFunction.asm
Normal file
1
projects/08/FunctionCalls/SimpleFunction.asm
Normal file
@@ -0,0 +1 @@
|
||||
// 0
|
||||
195
projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm
Normal file
195
projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm
Normal file
@@ -0,0 +1,195 @@
|
||||
// function SimpleFunction.test 2
|
||||
(SimpleFunction.test)
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 0
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 1
|
||||
@1
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END0)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// not 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=!M
|
||||
(END1)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END2)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push argument 1
|
||||
@1
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END3)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// 0
|
||||
@@ -0,0 +1,2 @@
|
||||
| RAM[0] | RAM[1] | RAM[2] | RAM[3] | RAM[4] |RAM[310]|
|
||||
| 311 | 305 | 300 | 3010 | 4010 | 1196 |
|
||||
29
projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst
Normal file
29
projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst
Normal file
@@ -0,0 +1,29 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst
|
||||
|
||||
load SimpleFunction.asm,
|
||||
output-file SimpleFunction.out,
|
||||
compare-to SimpleFunction.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[1]%D1.6.1 RAM[2]%D1.6.1
|
||||
RAM[3]%D1.6.1 RAM[4]%D1.6.1 RAM[310]%D1.6.1;
|
||||
|
||||
set RAM[0] 317,
|
||||
set RAM[1] 317,
|
||||
set RAM[2] 310,
|
||||
set RAM[3] 3000,
|
||||
set RAM[4] 4000,
|
||||
set RAM[310] 1234,
|
||||
set RAM[311] 37,
|
||||
set RAM[312] 1000,
|
||||
set RAM[313] 305,
|
||||
set RAM[314] 300,
|
||||
set RAM[315] 3010,
|
||||
set RAM[316] 4010,
|
||||
|
||||
repeat 300 {
|
||||
ticktock;
|
||||
}
|
||||
|
||||
output;
|
||||
16
projects/08/FunctionCalls/SimpleFunction/SimpleFunction.vm
Normal file
16
projects/08/FunctionCalls/SimpleFunction/SimpleFunction.vm
Normal file
@@ -0,0 +1,16 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/SimpleFunction/SimpleFunction.vm
|
||||
|
||||
// Performs a simple calculation and returns the result.
|
||||
function SimpleFunction.test 2
|
||||
push local 0
|
||||
push local 1
|
||||
add
|
||||
not
|
||||
push argument 0
|
||||
add
|
||||
push argument 1
|
||||
sub
|
||||
return
|
||||
@@ -0,0 +1,29 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/SimpleFunction/SimpleFunctionVME.tst
|
||||
|
||||
load SimpleFunction.vm,
|
||||
output-file SimpleFunction.out,
|
||||
compare-to SimpleFunction.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[1]%D1.6.1 RAM[2]%D1.6.1
|
||||
RAM[3]%D1.6.1 RAM[4]%D1.6.1 RAM[310]%D1.6.1;
|
||||
|
||||
set sp 317,
|
||||
set local 317,
|
||||
set argument 310,
|
||||
set this 3000,
|
||||
set that 4000,
|
||||
set argument[0] 1234,
|
||||
set argument[1] 37,
|
||||
set argument[2] 9,
|
||||
set argument[3] 305,
|
||||
set argument[4] 300,
|
||||
set argument[5] 3010,
|
||||
set argument[6] 4010,
|
||||
|
||||
repeat 10 {
|
||||
vmstep;
|
||||
}
|
||||
|
||||
output;
|
||||
531
projects/08/FunctionCalls/StaticsTest/.asm
Normal file
531
projects/08/FunctionCalls/StaticsTest/.asm
Normal file
@@ -0,0 +1,531 @@
|
||||
// add Class2.set 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END0)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop static 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@.0
|
||||
M=D
|
||||
// push argument 1
|
||||
@1
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop static 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@.1
|
||||
M=D
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END1)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add Class2.get 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END2)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push static 0
|
||||
@.0
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push static 1
|
||||
@.1
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END3)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END4)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// 0
|
||||
// add Class1.set 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END5)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop static 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@.0
|
||||
M=D
|
||||
// push argument 1
|
||||
@1
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop static 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@.1
|
||||
M=D
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END6)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add Class1.get 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END7)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push static 0
|
||||
@.0
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push static 1
|
||||
@.1
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END8)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END9)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// 0
|
||||
// add Sys.init 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END10)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 6
|
||||
@6
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 8
|
||||
@8
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add Class1.set 2
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END11)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop temp 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@R5
|
||||
M=D
|
||||
// push constant 23
|
||||
@23
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 15
|
||||
@15
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add Class2.set 2
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END12)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop temp 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@R5
|
||||
M=D
|
||||
// add Class1.get 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END13)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add Class2.get 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END14)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// label WHILE 0
|
||||
(LWHILE)
|
||||
// goto WHILE 0
|
||||
@LWHILE
|
||||
-1;JMP
|
||||
// 0
|
||||
20
projects/08/FunctionCalls/StaticsTest/Class1.vm
Normal file
20
projects/08/FunctionCalls/StaticsTest/Class1.vm
Normal file
@@ -0,0 +1,20 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/StaticsTest/Class1.vm
|
||||
|
||||
// Stores two supplied arguments in static[0] and static[1].
|
||||
function Class1.set 0
|
||||
push argument 0
|
||||
pop static 0
|
||||
push argument 1
|
||||
pop static 1
|
||||
push constant 0
|
||||
return
|
||||
|
||||
// Returns static[0] - static[1].
|
||||
function Class1.get 0
|
||||
push static 0
|
||||
push static 1
|
||||
sub
|
||||
return
|
||||
20
projects/08/FunctionCalls/StaticsTest/Class2.vm
Normal file
20
projects/08/FunctionCalls/StaticsTest/Class2.vm
Normal file
@@ -0,0 +1,20 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/StaticsTest/Class2.vm
|
||||
|
||||
// Stores two supplied arguments in static[0] and static[1].
|
||||
function Class2.set 0
|
||||
push argument 0
|
||||
pop static 0
|
||||
push argument 1
|
||||
pop static 1
|
||||
push constant 0
|
||||
return
|
||||
|
||||
// Returns static[0] - static[1].
|
||||
function Class2.get 0
|
||||
push static 0
|
||||
push static 1
|
||||
sub
|
||||
return
|
||||
701
projects/08/FunctionCalls/StaticsTest/StaticsTest.asm
Normal file
701
projects/08/FunctionCalls/StaticsTest/StaticsTest.asm
Normal file
@@ -0,0 +1,701 @@
|
||||
@256
|
||||
D=A
|
||||
@SP
|
||||
M=D
|
||||
// call Sys.init 0
|
||||
@$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@5
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Sys.init
|
||||
-1;JMP
|
||||
($ret.0)
|
||||
// function Class2.set 0
|
||||
(Class2.set)
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop static 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@Class2.0
|
||||
M=D
|
||||
// push argument 1
|
||||
@1
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop static 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@Class2.1
|
||||
M=D
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// function Class2.get 0
|
||||
(Class2.get)
|
||||
// push static 0
|
||||
@Class2.0
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push static 1
|
||||
@Class2.1
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END0)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// 0
|
||||
// function Class1.set 0
|
||||
(Class1.set)
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop static 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@Class1.0
|
||||
M=D
|
||||
// push argument 1
|
||||
@1
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop static 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@Class1.1
|
||||
M=D
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// function Class1.get 0
|
||||
(Class1.get)
|
||||
// push static 0
|
||||
@Class1.0
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push static 1
|
||||
@Class1.1
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END1)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// return 0
|
||||
@LCL
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@5
|
||||
A=D-A
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@ARG
|
||||
A=M
|
||||
M=D
|
||||
@ARG
|
||||
D=M+1
|
||||
@SP
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@1
|
||||
A=D-A
|
||||
D=M
|
||||
@THAT
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@2
|
||||
A=D-A
|
||||
D=M
|
||||
@THIS
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@3
|
||||
A=D-A
|
||||
D=M
|
||||
@ARG
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@4
|
||||
A=D-A
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@R14
|
||||
A=M
|
||||
0;JMP
|
||||
// 0
|
||||
// function Sys.init 0
|
||||
(Sys.init)
|
||||
// push constant 6
|
||||
@6
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 8
|
||||
@8
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// call Class1.set 2
|
||||
@Sys.init$ret.0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@7
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Class1.set
|
||||
-1;JMP
|
||||
(Sys.init$ret.0)
|
||||
// pop temp 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R5
|
||||
M=D
|
||||
// push constant 23
|
||||
@23
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 15
|
||||
@15
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// call Class2.set 2
|
||||
@Sys.init$ret.1
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@7
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Class2.set
|
||||
-1;JMP
|
||||
(Sys.init$ret.1)
|
||||
// pop temp 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R5
|
||||
M=D
|
||||
// call Class1.get 0
|
||||
@Sys.init$ret.2
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@5
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Class1.get
|
||||
-1;JMP
|
||||
(Sys.init$ret.2)
|
||||
// call Class2.get 0
|
||||
@Sys.init$ret.3
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@LCL
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@ARG
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THIS
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
@SP
|
||||
D=M
|
||||
@5
|
||||
D=D-A
|
||||
@ARG
|
||||
M=D
|
||||
@SP
|
||||
D=M
|
||||
@LCL
|
||||
M=D
|
||||
@Class2.get
|
||||
-1;JMP
|
||||
(Sys.init$ret.3)
|
||||
// label WHILE 0
|
||||
(Sys.init$WHILE)
|
||||
// goto WHILE 0
|
||||
@Sys.init$WHILE
|
||||
-1;JMP
|
||||
// 0
|
||||
2
projects/08/FunctionCalls/StaticsTest/StaticsTest.cmp
Normal file
2
projects/08/FunctionCalls/StaticsTest/StaticsTest.cmp
Normal file
@@ -0,0 +1,2 @@
|
||||
| RAM[0] |RAM[261]|RAM[262]|
|
||||
| 263 | -2 | 8 |
|
||||
17
projects/08/FunctionCalls/StaticsTest/StaticsTest.tst
Normal file
17
projects/08/FunctionCalls/StaticsTest/StaticsTest.tst
Normal file
@@ -0,0 +1,17 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/StaticsTest/StaticsTest.tst
|
||||
|
||||
load StaticsTest.asm,
|
||||
output-file StaticsTest.out,
|
||||
compare-to StaticsTest.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[261]%D1.6.1 RAM[262]%D1.6.1;
|
||||
|
||||
set RAM[0] 256,
|
||||
|
||||
repeat 2500 {
|
||||
ticktock;
|
||||
}
|
||||
|
||||
output;
|
||||
17
projects/08/FunctionCalls/StaticsTest/StaticsTestVME.tst
Normal file
17
projects/08/FunctionCalls/StaticsTest/StaticsTestVME.tst
Normal file
@@ -0,0 +1,17 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/StaticsTest/StaticsTestVME.tst
|
||||
|
||||
load, // loads all the VM files from the current directory.
|
||||
output-file StaticsTest.out,
|
||||
compare-to StaticsTest.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[261]%D1.6.1 RAM[262]%D1.6.1;
|
||||
|
||||
set sp 261,
|
||||
|
||||
repeat 36 {
|
||||
vmstep;
|
||||
}
|
||||
|
||||
output;
|
||||
1
projects/08/FunctionCalls/StaticsTest/Sys.asm
Normal file
1
projects/08/FunctionCalls/StaticsTest/Sys.asm
Normal file
@@ -0,0 +1 @@
|
||||
// 0
|
||||
20
projects/08/FunctionCalls/StaticsTest/Sys.vm
Normal file
20
projects/08/FunctionCalls/StaticsTest/Sys.vm
Normal file
@@ -0,0 +1,20 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/FunctionCalls/StaticsTest/Sys.vm
|
||||
|
||||
// Tests that different functions, stored in two different
|
||||
// class files, manipulate the static segment correctly.
|
||||
function Sys.init 0
|
||||
push constant 6
|
||||
push constant 8
|
||||
call Class1.set 2
|
||||
pop temp 0 // Dumps the return value
|
||||
push constant 23
|
||||
push constant 15
|
||||
call Class2.set 2
|
||||
pop temp 0 // Dumps the return value
|
||||
call Class1.get 0
|
||||
call Class2.get 0
|
||||
label WHILE
|
||||
goto WHILE
|
||||
185
projects/08/ProgramFlow/BasicLoop/.asm
Normal file
185
projects/08/ProgramFlow/BasicLoop/.asm
Normal file
@@ -0,0 +1,185 @@
|
||||
@SP
|
||||
M=256
|
||||
@Sys.init
|
||||
0;JMP
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// label LOOP_START 0
|
||||
(LLOOP_START)
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 0
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END0)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 1
|
||||
@1
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END1)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop argument 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// if-goto LOOP_START 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@LLOOP_START
|
||||
D;JGT
|
||||
// push local 0
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// 0
|
||||
181
projects/08/ProgramFlow/BasicLoop/BasicLoop.asm
Normal file
181
projects/08/ProgramFlow/BasicLoop/BasicLoop.asm
Normal file
@@ -0,0 +1,181 @@
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// label LOOP_START 0
|
||||
($LOOP_START)
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push local 0
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END0)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop local 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 1
|
||||
@1
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END1)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop argument 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R13
|
||||
M=D
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
D=M+D
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
A=M
|
||||
M=D
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// if-goto LOOP_START 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@$LOOP_START
|
||||
D;JGT
|
||||
// push local 0
|
||||
@0
|
||||
D=A
|
||||
@LCL
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// 0
|
||||
2
projects/08/ProgramFlow/BasicLoop/BasicLoop.cmp
Normal file
2
projects/08/ProgramFlow/BasicLoop/BasicLoop.cmp
Normal file
@@ -0,0 +1,2 @@
|
||||
| RAM[0] |RAM[256]|
|
||||
| 257 | 6 |
|
||||
20
projects/08/ProgramFlow/BasicLoop/BasicLoop.tst
Normal file
20
projects/08/ProgramFlow/BasicLoop/BasicLoop.tst
Normal file
@@ -0,0 +1,20 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/ProgramFlow/BasicLoop/BasicLoop.tst
|
||||
|
||||
load BasicLoop.asm,
|
||||
output-file BasicLoop.out,
|
||||
compare-to BasicLoop.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[256]%D1.6.1;
|
||||
|
||||
set RAM[0] 256,
|
||||
set RAM[1] 300,
|
||||
set RAM[2] 400,
|
||||
set RAM[400] 3,
|
||||
|
||||
repeat 600 {
|
||||
ticktock;
|
||||
}
|
||||
|
||||
output;
|
||||
22
projects/08/ProgramFlow/BasicLoop/BasicLoop.vm
Normal file
22
projects/08/ProgramFlow/BasicLoop/BasicLoop.vm
Normal file
@@ -0,0 +1,22 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/ProgramFlow/BasicLoop/BasicLoop.vm
|
||||
|
||||
// Computes the sum 1 + 2 + ... + argument[0] and pushes the
|
||||
// result onto the stack. Argument[0] is initialized by the test
|
||||
// script before this code starts running.
|
||||
push constant 0
|
||||
pop local 0 // initializes sum = 0
|
||||
label LOOP_START
|
||||
push argument 0
|
||||
push local 0
|
||||
add
|
||||
pop local 0 // sum = sum + counter
|
||||
push argument 0
|
||||
push constant 1
|
||||
sub
|
||||
pop argument 0 // counter--
|
||||
push argument 0
|
||||
if-goto LOOP_START // If counter > 0, goto LOOP_START
|
||||
push local 0
|
||||
20
projects/08/ProgramFlow/BasicLoop/BasicLoopVME.tst
Normal file
20
projects/08/ProgramFlow/BasicLoop/BasicLoopVME.tst
Normal file
@@ -0,0 +1,20 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/ProgramFlow/BasicLoop/BasicLoopVME.tst
|
||||
|
||||
load BasicLoop.vm,
|
||||
output-file BasicLoop.out,
|
||||
compare-to BasicLoop.cmp,
|
||||
output-list RAM[0]%D1.6.1 RAM[256]%D1.6.1;
|
||||
|
||||
set sp 256,
|
||||
set local 300,
|
||||
set argument 400,
|
||||
set argument[0] 3,
|
||||
|
||||
repeat 33 {
|
||||
vmstep;
|
||||
}
|
||||
|
||||
output;
|
||||
338
projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm
Normal file
338
projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.asm
Normal file
@@ -0,0 +1,338 @@
|
||||
// push argument 1
|
||||
@1
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// push constant 0
|
||||
@0
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop that 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@0
|
||||
D=A
|
||||
@THAT
|
||||
D=M+D
|
||||
@R15
|
||||
M=D
|
||||
@R14
|
||||
D=M
|
||||
@R15
|
||||
A=M
|
||||
M=D
|
||||
// push constant 1
|
||||
@1
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop that 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@1
|
||||
D=A
|
||||
@THAT
|
||||
D=M+D
|
||||
@R15
|
||||
M=D
|
||||
@R14
|
||||
D=M
|
||||
@R15
|
||||
A=M
|
||||
M=D
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 2
|
||||
@2
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END0)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop argument 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
D=M+D
|
||||
@R15
|
||||
M=D
|
||||
@R14
|
||||
D=M
|
||||
@R15
|
||||
A=M
|
||||
M=D
|
||||
// label MAIN_LOOP_START 0
|
||||
($MAIN_LOOP_START)
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// if-goto COMPUTE_ELEMENT 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@$COMPUTE_ELEMENT
|
||||
D;JNE
|
||||
// goto END_PROGRAM 0
|
||||
@$END_PROGRAM
|
||||
-1;JMP
|
||||
// label COMPUTE_ELEMENT 0
|
||||
($COMPUTE_ELEMENT)
|
||||
// push that 0
|
||||
@0
|
||||
D=A
|
||||
@THAT
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push that 1
|
||||
@1
|
||||
D=A
|
||||
@THAT
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END1)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop that 2
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@2
|
||||
D=A
|
||||
@THAT
|
||||
D=M+D
|
||||
@R15
|
||||
M=D
|
||||
@R14
|
||||
D=M
|
||||
@R15
|
||||
A=M
|
||||
M=D
|
||||
// push pointer 1
|
||||
@THAT
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 1
|
||||
@1
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// add 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M+D
|
||||
(END2)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop pointer 1
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@THAT
|
||||
M=D
|
||||
// push argument 0
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
A=M+D
|
||||
D=M
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// push constant 1
|
||||
@1
|
||||
D=A
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// sub 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
M=0
|
||||
@R13
|
||||
M=D
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@R13
|
||||
D=M
|
||||
@R14
|
||||
D=M-D
|
||||
(END3)
|
||||
@SP
|
||||
A=M
|
||||
M=D
|
||||
@SP
|
||||
M=M+1
|
||||
// pop argument 0
|
||||
@SP
|
||||
M=M-1
|
||||
A=M
|
||||
D=M
|
||||
@R14
|
||||
M=D
|
||||
@0
|
||||
D=A
|
||||
@ARG
|
||||
D=M+D
|
||||
@R15
|
||||
M=D
|
||||
@R14
|
||||
D=M
|
||||
@R15
|
||||
A=M
|
||||
M=D
|
||||
// goto MAIN_LOOP_START 0
|
||||
@$MAIN_LOOP_START
|
||||
-1;JMP
|
||||
// label END_PROGRAM 0
|
||||
($END_PROGRAM)
|
||||
// 0
|
||||
@@ -0,0 +1,2 @@
|
||||
|RAM[3000]|RAM[3001]|RAM[3002]|RAM[3003]|RAM[3004]|RAM[3005]|
|
||||
| 0 | 1 | 1 | 2 | 3 | 5 |
|
||||
22
projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.tst
Normal file
22
projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.tst
Normal file
@@ -0,0 +1,22 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.tst
|
||||
|
||||
load FibonacciSeries.asm,
|
||||
output-file FibonacciSeries.out,
|
||||
compare-to FibonacciSeries.cmp,
|
||||
output-list RAM[3000]%D1.6.2 RAM[3001]%D1.6.2 RAM[3002]%D1.6.2
|
||||
RAM[3003]%D1.6.2 RAM[3004]%D1.6.2 RAM[3005]%D1.6.2;
|
||||
|
||||
set RAM[0] 256,
|
||||
set RAM[1] 300,
|
||||
set RAM[2] 400,
|
||||
set RAM[400] 6,
|
||||
set RAM[401] 3000,
|
||||
|
||||
repeat 1100 {
|
||||
ticktock;
|
||||
}
|
||||
|
||||
output;
|
||||
49
projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.vm
Normal file
49
projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.vm
Normal file
@@ -0,0 +1,49 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.vm
|
||||
|
||||
// Puts the first argument[0] elements of the Fibonacci series
|
||||
// in the memory, starting in the address given in argument[1].
|
||||
// Argument[0] and argument[1] are initialized by the test script
|
||||
// before this code starts running.
|
||||
|
||||
push argument 1
|
||||
pop pointer 1 // that = argument[1]
|
||||
|
||||
push constant 0
|
||||
pop that 0 // first element in the series = 0
|
||||
push constant 1
|
||||
pop that 1 // second element in the series = 1
|
||||
|
||||
push argument 0
|
||||
push constant 2
|
||||
sub
|
||||
pop argument 0 // num_of_elements -= 2 (first 2 elements are set)
|
||||
|
||||
label MAIN_LOOP_START
|
||||
|
||||
push argument 0
|
||||
if-goto COMPUTE_ELEMENT // if num_of_elements > 0, goto COMPUTE_ELEMENT
|
||||
goto END_PROGRAM // otherwise, goto END_PROGRAM
|
||||
|
||||
label COMPUTE_ELEMENT
|
||||
|
||||
push that 0
|
||||
push that 1
|
||||
add
|
||||
pop that 2 // that[2] = that[0] + that[1]
|
||||
|
||||
push pointer 1
|
||||
push constant 1
|
||||
add
|
||||
pop pointer 1 // that += 1
|
||||
|
||||
push argument 0
|
||||
push constant 1
|
||||
sub
|
||||
pop argument 0 // num_of_elements--
|
||||
|
||||
goto MAIN_LOOP_START
|
||||
|
||||
label END_PROGRAM
|
||||
@@ -0,0 +1,22 @@
|
||||
// This file is part of www.nand2tetris.org
|
||||
// and the book "The Elements of Computing Systems"
|
||||
// by Nisan and Schocken, MIT Press.
|
||||
// File name: projects/08/ProgramFlow/FibonacciSeries/FibonacciSeriesVME.tst
|
||||
|
||||
load FibonacciSeries.vm,
|
||||
output-file FibonacciSeries.out,
|
||||
compare-to FibonacciSeries.cmp,
|
||||
output-list RAM[3000]%D1.6.2 RAM[3001]%D1.6.2 RAM[3002]%D1.6.2
|
||||
RAM[3003]%D1.6.2 RAM[3004]%D1.6.2 RAM[3005]%D1.6.2;
|
||||
|
||||
set sp 256,
|
||||
set local 300,
|
||||
set argument 400,
|
||||
set argument[0] 6,
|
||||
set argument[1] 3000,
|
||||
|
||||
repeat 73 {
|
||||
vmstep;
|
||||
}
|
||||
|
||||
output;
|
||||
Reference in New Issue
Block a user