When testing my generated ASM code for NestedCall, it has the correct output right up until "call Sys.main 0" is executed. Specifically the output is all correct (everything is pushed onto the stack correctly and ARG/LCL are correctly repositioned) until writeCall jumps to Sys.main. When it jumps to Sys.main the SP value becomes 271 when it should be 266, by stepping through this I can see it happens when the SP is incremented each time 0 is pushed onto the stack nVars times (which in this particular instance it is 5).
The RAM segments in the stack are correct as well:
Becuase it is 5 more than 266 I am assuming this has something to do with pointer skew. What I am finding really confusing is my ASM code is correct for writeCall as well as writeFunction. For instance my code for "function Sys.main 5" is this:
// ------------------------- writeFunction ---------------------
(Sys.Sys.main)
@SP
A=M
M=0
@SP
M=M+1
@SP
A=M
M=0
@SP
M=M+1
@SP
A=M
M=0
@SP
M=M+1
@SP
A=M
M=0
@SP
M=M+1
@SP
A=M
M=0
@SP
M=M+1
// ------------------------- writeFunction ---------------------
As you can see, it has correctly pushed 5 onto the stack 5 times. My code for write call as mentioned before appears to be correct, as SP is 266 (the correct value) right up until the
goto f:
// -------------------- writeCall -------------------
@Sys.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
@5
D=D-A
@ARG
M=D
@SP
D=M
@LCL
M=D
@Sys.Sys.main
// -------------------- writeCall -------------------
0;JMP
(Sys.Sys.main$ret.0)
I am really not sure what to do at this point, but my assumption is that writeCall is most likely incorrect. If it would be possible, could I email someone my code, or could someone take a look at the
repository so they can see if I have realised the methods correctly? This is my code for writeCall (C++):
void CodeWriter::writeCall(const std::string &functionName, const int &nVars) {
// writeDebugMarker();
static int runningInt = 0;
std::string returnLabel = currentFileName + "." + functionName + "$ret." + std::to_string(runningInt);
std::string push =
"@SP\n"
"A=M\n"
"M=D\n"
"@SP\n"
"M=M+1\n";
std::string writeCallASM =
"// -------------------- writeCall -------------------\n"
"@" + returnLabel + "\n"
"D=A\n" + push +
"@LCL\n"
"D=M\n" + push +
"@ARG\n"
"D=M\n" + push +
"@THIS\n"
"D=M\n" + push +
"@THAT\n"
"D=M\n" + push +
// ARG = SP - 5 - nArgs
"@SP\n"
"D=M\n"
"@" + std::to_string(nVars + 5) + "\n"
"D=D-A\n"
"@ARG\n"
"M=D\n"
// LCL = SP
"@SP\n"
"D=M\n"
"@LCL\n"
"M=D\n"
// goto f
"@" + currentFileName + "." + functionName + "\n"
"// -------------------- writeCall -------------------\n"
"0;JMP\n"
"(" + returnLabel + ")\n";
asmFile << writeCallASM << std::endl;
runningInt++;
}
And this is my code for writeFunction:
void CodeWriter::writeFunction(const std::string &functionName, const int &nVars) {
// writeDebugMarker();
currentFuncName = functionName;
std::string writeFunctionASM =
" // ------------------------- writeFunction ---------------------\n"
"(" + currentFileName + "." + functionName + ")\n";
for (int i = 0; i < nVars; i++) {
writeFunctionASM +=
"@SP\n"
"A=M\n"
"M=0\n"
"@SP\n"
"M=M+1\n";
}
writeFunctionASM +=
" // ------------------------- writeFunction ---------------------\n";
asmFile << writeFunctionASM << std::endl;
}
For reference, this is the .out file with comp failure on line 2:
| RAM[0] | RAM[1] | RAM[2] | RAM[3] | RAM[4] | RAM[5] | RAM[6] |
| 261 | 261 | 256 | 4000 | 5000 | 246 | -1 |