From a000308104aab27c2dde9a306f1bc654b2db4806 Mon Sep 17 00:00:00 2001 From: Yuchen Pei <me@ypei.me> Date: Wed, 29 Nov 2017 12:30:41 +0100 Subject: first commit --- .../FibonacciElement/FibonacciElement.cmp | 2 + .../FibonacciElement/FibonacciElement.tst | 18 ++ .../FibonacciElement/FibonacciElementVME.tst | 17 ++ projects/08/FunctionCalls/FibonacciElement/Main.vm | 30 ++ projects/08/FunctionCalls/FibonacciElement/Sys.vm | 15 + .../08/FunctionCalls/NestedCall/NestedCall.cmp | 2 + .../08/FunctionCalls/NestedCall/NestedCall.html | 196 +++++++++++++ .../08/FunctionCalls/NestedCall/NestedCall.tst | 65 +++++ .../FunctionCalls/NestedCall/NestedCallStack.html | 306 +++++++++++++++++++++ .../08/FunctionCalls/NestedCall/NestedCallVME.tst | 70 +++++ projects/08/FunctionCalls/NestedCall/Sys.vm | 63 +++++ .../SimpleFunction/SimpleFunction.cmp | 2 + .../SimpleFunction/SimpleFunction.tst | 29 ++ .../FunctionCalls/SimpleFunction/SimpleFunction.vm | 16 ++ .../SimpleFunction/SimpleFunctionVME.tst | 29 ++ projects/08/FunctionCalls/StaticsTest/Class1.vm | 20 ++ projects/08/FunctionCalls/StaticsTest/Class2.vm | 20 ++ .../08/FunctionCalls/StaticsTest/StaticsTest.cmp | 2 + .../08/FunctionCalls/StaticsTest/StaticsTest.tst | 17 ++ .../FunctionCalls/StaticsTest/StaticsTestVME.tst | 17 ++ projects/08/FunctionCalls/StaticsTest/Sys.vm | 20 ++ projects/08/ProgramFlow/BasicLoop/BasicLoop.cmp | 2 + projects/08/ProgramFlow/BasicLoop/BasicLoop.tst | 20 ++ projects/08/ProgramFlow/BasicLoop/BasicLoop.vm | 22 ++ projects/08/ProgramFlow/BasicLoop/BasicLoopVME.tst | 20 ++ .../FibonacciSeries/FibonacciSeries.cmp | 2 + .../FibonacciSeries/FibonacciSeries.tst | 22 ++ .../ProgramFlow/FibonacciSeries/FibonacciSeries.vm | 49 ++++ .../FibonacciSeries/FibonacciSeriesVME.tst | 22 ++ 29 files changed, 1115 insertions(+) create mode 100644 projects/08/FunctionCalls/FibonacciElement/FibonacciElement.cmp create mode 100644 projects/08/FunctionCalls/FibonacciElement/FibonacciElement.tst create mode 100644 projects/08/FunctionCalls/FibonacciElement/FibonacciElementVME.tst create mode 100644 projects/08/FunctionCalls/FibonacciElement/Main.vm create mode 100644 projects/08/FunctionCalls/FibonacciElement/Sys.vm create mode 100644 projects/08/FunctionCalls/NestedCall/NestedCall.cmp create mode 100644 projects/08/FunctionCalls/NestedCall/NestedCall.html create mode 100644 projects/08/FunctionCalls/NestedCall/NestedCall.tst create mode 100644 projects/08/FunctionCalls/NestedCall/NestedCallStack.html create mode 100644 projects/08/FunctionCalls/NestedCall/NestedCallVME.tst create mode 100644 projects/08/FunctionCalls/NestedCall/Sys.vm create mode 100644 projects/08/FunctionCalls/SimpleFunction/SimpleFunction.cmp create mode 100644 projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst create mode 100644 projects/08/FunctionCalls/SimpleFunction/SimpleFunction.vm create mode 100644 projects/08/FunctionCalls/SimpleFunction/SimpleFunctionVME.tst create mode 100644 projects/08/FunctionCalls/StaticsTest/Class1.vm create mode 100644 projects/08/FunctionCalls/StaticsTest/Class2.vm create mode 100644 projects/08/FunctionCalls/StaticsTest/StaticsTest.cmp create mode 100644 projects/08/FunctionCalls/StaticsTest/StaticsTest.tst create mode 100644 projects/08/FunctionCalls/StaticsTest/StaticsTestVME.tst create mode 100644 projects/08/FunctionCalls/StaticsTest/Sys.vm create mode 100644 projects/08/ProgramFlow/BasicLoop/BasicLoop.cmp create mode 100644 projects/08/ProgramFlow/BasicLoop/BasicLoop.tst create mode 100644 projects/08/ProgramFlow/BasicLoop/BasicLoop.vm create mode 100644 projects/08/ProgramFlow/BasicLoop/BasicLoopVME.tst create mode 100644 projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.cmp create mode 100644 projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.tst create mode 100644 projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.vm create mode 100644 projects/08/ProgramFlow/FibonacciSeries/FibonacciSeriesVME.tst (limited to 'projects/08') diff --git a/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.cmp b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.cmp new file mode 100644 index 0000000..d667834 --- /dev/null +++ b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.cmp @@ -0,0 +1,2 @@ +| RAM[0] |RAM[261]| +| 262 | 3 | diff --git a/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.tst b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.tst new file mode 100644 index 0000000..1f907b1 --- /dev/null +++ b/projects/08/FunctionCalls/FibonacciElement/FibonacciElement.tst @@ -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 6000 { + ticktock; +} + +output; diff --git a/projects/08/FunctionCalls/FibonacciElement/FibonacciElementVME.tst b/projects/08/FunctionCalls/FibonacciElement/FibonacciElementVME.tst new file mode 100644 index 0000000..87c0920 --- /dev/null +++ b/projects/08/FunctionCalls/FibonacciElement/FibonacciElementVME.tst @@ -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; diff --git a/projects/08/FunctionCalls/FibonacciElement/Main.vm b/projects/08/FunctionCalls/FibonacciElement/Main.vm new file mode 100644 index 0000000..55e5ad2 --- /dev/null +++ b/projects/08/FunctionCalls/FibonacciElement/Main.vm @@ -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 diff --git a/projects/08/FunctionCalls/FibonacciElement/Sys.vm b/projects/08/FunctionCalls/FibonacciElement/Sys.vm new file mode 100644 index 0000000..f3965c9 --- /dev/null +++ b/projects/08/FunctionCalls/FibonacciElement/Sys.vm @@ -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 diff --git a/projects/08/FunctionCalls/NestedCall/NestedCall.cmp b/projects/08/FunctionCalls/NestedCall/NestedCall.cmp new file mode 100644 index 0000000..9200202 --- /dev/null +++ b/projects/08/FunctionCalls/NestedCall/NestedCall.cmp @@ -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 | diff --git a/projects/08/FunctionCalls/NestedCall/NestedCall.html b/projects/08/FunctionCalls/NestedCall/NestedCall.html new file mode 100644 index 0000000..0821f9c --- /dev/null +++ b/projects/08/FunctionCalls/NestedCall/NestedCall.html @@ -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> \ No newline at end of file diff --git a/projects/08/FunctionCalls/NestedCall/NestedCall.tst b/projects/08/FunctionCalls/NestedCall/NestedCall.tst new file mode 100644 index 0000000..70e5523 --- /dev/null +++ b/projects/08/FunctionCalls/NestedCall/NestedCall.tst @@ -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; diff --git a/projects/08/FunctionCalls/NestedCall/NestedCallStack.html b/projects/08/FunctionCalls/NestedCall/NestedCallStack.html new file mode 100644 index 0000000..70582b6 --- /dev/null +++ b/projects/08/FunctionCalls/NestedCall/NestedCallStack.html @@ -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> \ No newline at end of file diff --git a/projects/08/FunctionCalls/NestedCall/NestedCallVME.tst b/projects/08/FunctionCalls/NestedCall/NestedCallVME.tst new file mode 100644 index 0000000..2c689b8 --- /dev/null +++ b/projects/08/FunctionCalls/NestedCall/NestedCallVME.tst @@ -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; diff --git a/projects/08/FunctionCalls/NestedCall/Sys.vm b/projects/08/FunctionCalls/NestedCall/Sys.vm new file mode 100644 index 0000000..8b0b003 --- /dev/null +++ b/projects/08/FunctionCalls/NestedCall/Sys.vm @@ -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 diff --git a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.cmp b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.cmp new file mode 100644 index 0000000..c3ea911 --- /dev/null +++ b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.cmp @@ -0,0 +1,2 @@ +| RAM[0] | RAM[1] | RAM[2] | RAM[3] | RAM[4] |RAM[310]| +| 311 | 305 | 300 | 3010 | 4010 | 1196 | diff --git a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst new file mode 100644 index 0000000..c7b5905 --- /dev/null +++ b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.tst @@ -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; diff --git a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.vm b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.vm new file mode 100644 index 0000000..d64a34f --- /dev/null +++ b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.vm @@ -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 diff --git a/projects/08/FunctionCalls/SimpleFunction/SimpleFunctionVME.tst b/projects/08/FunctionCalls/SimpleFunction/SimpleFunctionVME.tst new file mode 100644 index 0000000..c9267ee --- /dev/null +++ b/projects/08/FunctionCalls/SimpleFunction/SimpleFunctionVME.tst @@ -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; diff --git a/projects/08/FunctionCalls/StaticsTest/Class1.vm b/projects/08/FunctionCalls/StaticsTest/Class1.vm new file mode 100644 index 0000000..c463537 --- /dev/null +++ b/projects/08/FunctionCalls/StaticsTest/Class1.vm @@ -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 diff --git a/projects/08/FunctionCalls/StaticsTest/Class2.vm b/projects/08/FunctionCalls/StaticsTest/Class2.vm new file mode 100644 index 0000000..94f2946 --- /dev/null +++ b/projects/08/FunctionCalls/StaticsTest/Class2.vm @@ -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 diff --git a/projects/08/FunctionCalls/StaticsTest/StaticsTest.cmp b/projects/08/FunctionCalls/StaticsTest/StaticsTest.cmp new file mode 100644 index 0000000..5589f1e --- /dev/null +++ b/projects/08/FunctionCalls/StaticsTest/StaticsTest.cmp @@ -0,0 +1,2 @@ +| RAM[0] |RAM[261]|RAM[262]| +| 263 | -2 | 8 | diff --git a/projects/08/FunctionCalls/StaticsTest/StaticsTest.tst b/projects/08/FunctionCalls/StaticsTest/StaticsTest.tst new file mode 100644 index 0000000..1b9194e --- /dev/null +++ b/projects/08/FunctionCalls/StaticsTest/StaticsTest.tst @@ -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; diff --git a/projects/08/FunctionCalls/StaticsTest/StaticsTestVME.tst b/projects/08/FunctionCalls/StaticsTest/StaticsTestVME.tst new file mode 100644 index 0000000..130ba66 --- /dev/null +++ b/projects/08/FunctionCalls/StaticsTest/StaticsTestVME.tst @@ -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; diff --git a/projects/08/FunctionCalls/StaticsTest/Sys.vm b/projects/08/FunctionCalls/StaticsTest/Sys.vm new file mode 100644 index 0000000..3708322 --- /dev/null +++ b/projects/08/FunctionCalls/StaticsTest/Sys.vm @@ -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 diff --git a/projects/08/ProgramFlow/BasicLoop/BasicLoop.cmp b/projects/08/ProgramFlow/BasicLoop/BasicLoop.cmp new file mode 100644 index 0000000..00d35d2 --- /dev/null +++ b/projects/08/ProgramFlow/BasicLoop/BasicLoop.cmp @@ -0,0 +1,2 @@ +| RAM[0] |RAM[256]| +| 257 | 6 | diff --git a/projects/08/ProgramFlow/BasicLoop/BasicLoop.tst b/projects/08/ProgramFlow/BasicLoop/BasicLoop.tst new file mode 100644 index 0000000..50ca118 --- /dev/null +++ b/projects/08/ProgramFlow/BasicLoop/BasicLoop.tst @@ -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; diff --git a/projects/08/ProgramFlow/BasicLoop/BasicLoop.vm b/projects/08/ProgramFlow/BasicLoop/BasicLoop.vm new file mode 100644 index 0000000..2d63f13 --- /dev/null +++ b/projects/08/ProgramFlow/BasicLoop/BasicLoop.vm @@ -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 diff --git a/projects/08/ProgramFlow/BasicLoop/BasicLoopVME.tst b/projects/08/ProgramFlow/BasicLoop/BasicLoopVME.tst new file mode 100644 index 0000000..237fdff --- /dev/null +++ b/projects/08/ProgramFlow/BasicLoop/BasicLoopVME.tst @@ -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; diff --git a/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.cmp b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.cmp new file mode 100644 index 0000000..c262a4b --- /dev/null +++ b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.cmp @@ -0,0 +1,2 @@ +|RAM[3000]|RAM[3001]|RAM[3002]|RAM[3003]|RAM[3004]|RAM[3005]| +| 0 | 1 | 1 | 2 | 3 | 5 | diff --git a/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.tst b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.tst new file mode 100644 index 0000000..07df2b9 --- /dev/null +++ b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.tst @@ -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; diff --git a/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.vm b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.vm new file mode 100644 index 0000000..6a643b6 --- /dev/null +++ b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeries.vm @@ -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 diff --git a/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeriesVME.tst b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeriesVME.tst new file mode 100644 index 0000000..243f31b --- /dev/null +++ b/projects/08/ProgramFlow/FibonacciSeries/FibonacciSeriesVME.tst @@ -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; -- cgit v1.2.3