diff --git a/README.md b/README.md index 0020a04..685e30b 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,6 @@ wc -l file.hack ## Function Calling Commands -- [ ] `SimpleFunction.vm` +- [x] `SimpleFunction.vm` (128) - [ ] `FibonacciElement.vm` - [ ] `StaticsTest.vm` diff --git a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm index 5edfdad..232a58d 100644 --- a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm +++ b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.asm @@ -78,21 +78,52 @@ A=A-1 M=M-D @SP M=M-1 // end sub (L8) +@SP +A=M-1 +D=M +@ARG +A=M +M=D @ARG D=M+1 @SP M=D // @SP = ARG+1 @LCL -D=M // D=@LCL -@THAT -MD=D-1 // THAT = LCL-1 -@THIS -MD=D-1 // THIS = LCL-2 -@ARG -MD=D-1 // ARG = LCL-3 -@LCL -MD=D-1 // LCL = LCL-4 -A=D-1 // A = LCL-5 +D=M +@R13 +M=D // Save LCL to R13 +A=D-1 // A=*LCL-1 +D=M // D=*(*LCL-1) +@THAT // A=THAT +M=D // *that = *(*lcl-1) +@R13 +A=M-1 +A=A-1 // A=*LCL-2 +D=M // D=*(*LCL-2) +@THIS // A=THIS +M=D // *THIS = *(*lcl-2) +@R13 +A=M-1 +A=A-1 +A=A-1 // A=*LCL-3 +D=M // D=*(*LCL-3) +@ARG // A=ARG +M=D // *ARG = *(*lcl-3) +@R13 +A=M-1 +A=A-1 +A=A-1 +A=A-1 // A=*LCL-4 +D=M // D=*(*LCL-4) +@LCL // A=LCL +M=D // *LCL = *(*lcl-4) +@R13 +A=M-1 +A=A-1 +A=A-1 +A=A-1 +A=A-1 // A=*LCL-5 +A=M // A=*(*LCL-5) 0;JMP // Jump to *(LCL-5) -@97 +@128 0;JMP diff --git a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.out b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.out index 7b5e4c9..ef72b7a 100644 --- a/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.out +++ b/projects/08/FunctionCalls/SimpleFunction/SimpleFunction.out @@ -1 +1,2 @@ | RAM[0] | RAM[1] | RAM[2] | RAM[3] | RAM[4] |RAM[310]| +| 311 | 305 | 300 | 3010 | 4010 | 1196 | diff --git a/vm/CodeWriter.php b/vm/CodeWriter.php index 1ebe311..8468af1 100644 --- a/vm/CodeWriter.php +++ b/vm/CodeWriter.php @@ -14,26 +14,64 @@ class CodeWriter { public function writeReturn() { $this->write([ + "@SP", + "A=M-1", + "D=M",// Popped value to D + // And then write it to *ARG = pop() + "@ARG", + "A=M", + "M=D", + // SP=ARG+1 "@ARG", "D=M+1", "@SP", "M=D // @SP = ARG+1", - // THAT = LCL-1 "@LCL", - "D=M // D=@LCL", - "@THAT", - "MD=D-1 // THAT = LCL-1", - // THIS = LCL-2 - "@THIS", - "MD=D-1 // THIS = LCL-2", - // ARG = LCL-3 - "@ARG", - "MD=D-1 // ARG = LCL-3", - // LCL = LCL-4 - "@LCL", - "MD=D-1 // LCL = LCL-4", - "A=D-1 // A = LCL-5", + "D=M", + "@R13", + "M=D // Save LCL to R13", + + // now we go restoring THAT, THIS, ARG, LCL + "A=D-1 // A=*LCL-1", + "D=M // D=*(*LCL-1)", + "@THAT // A=THAT", + "M=D // *that = *(*lcl-1)", + // now we restore THIS + "@R13", + "A=M-1", + "A=A-1 // A=*LCL-2", + "D=M // D=*(*LCL-2)", + "@THIS // A=THIS", + "M=D // *THIS = *(*lcl-2)", + + // now we restore ARG + "@R13", + "A=M-1", + "A=A-1", + "A=A-1 // A=*LCL-3", + "D=M // D=*(*LCL-3)", + "@ARG // A=ARG", + "M=D // *ARG = *(*lcl-3)", + + // now we restore LCL + "@R13", + "A=M-1", + "A=A-1", + "A=A-1", + "A=A-1 // A=*LCL-4", + "D=M // D=*(*LCL-4)", + "@LCL // A=LCL", + "M=D // *LCL = *(*lcl-4)", + + // Now we hyperjump + "@R13", + "A=M-1", + "A=A-1", + "A=A-1", + "A=A-1", + "A=A-1 // A=*LCL-5", + "A=M // A=*(*LCL-5)", "0;JMP // Jump to *(LCL-5)", ]); }