Return code or Call code not working, cont.

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Return code or Call code not working, cont.

ShiraJoseph
Mark,
Here is the (Java) code I have for call, function, and return.

...
case "call":
        _ASMcommand = comment
                + "//->push returnAddress\n"
                + "@retAddr"+_count+ "\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n"
                + "//->push LCL\n"
                + "@LCL\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n"
                + "//->push ARG\n"
                + "@ARG\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n"
                + "//->push THIS\n"
                + "@THIS\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n"
                + "//->push THAT\n"
                + "@THAT\nD=M\n@SP\nA=M\nM=D\n@SP\nM=M+1\n"
                + "//->ARG=SP-5-nArgs\n"
                + "@SP\nD=M\n@5\nD=D-A\n@"+_VMcommand.substring(_VMcommand.lastIndexOf(" ")+ 1, _VMcommand.length()) + "\nD=D-M\n@ARG\nM=D\n"
                + "//->LCL=SP\n"
                + "@SP\nD=M\n@LCL\nM=D\n"
                + "//->goto functionName\n"
                + "@"+_VMcommand.substring(_VMcommand.indexOf(" ")+ 1, _VMcommand.lastIndexOf(" ")) + "\n0; JMP\n"
                + "//->(returnAddress)\n"
                + "(retAddr"+_count+ ")\n";
        break;
case "function":
        _ASMcommand = comment
                + "("+_VMcommand.substring(_VMcommand.indexOf(" ")+ 1, _VMcommand.lastIndexOf(" "))+ ")\n"
                + "//->initialize n\n"
                + "@" + _VMcommand.substring(_VMcommand.lastIndexOf(" ")+ 1, _VMcommand.length())
                + "\nD=A\n@n" + _count + "\nM=D\n"
                + "//->while n!=0\n"
                + "(LOOP" + _count + ")\n@n" + _count + "\nD=M\n@END" + _count + "\nD;JEQ\n"
                + "//->push 0\n"
                + "@0\nD=A\n@SP\nA=M\nM=D\n@SP\nM=M+1\n"
                + "//->n--\n"
                + "@n" + _count + "\nM=M-1\n@LOOP" + _count + "\n0;JMP\n(END" + _count + ")\n";
        break;
case "return":
        _ASMcommand = comment
                + "//->endFrame = LCL\n"
                + "@LCL\nD=M\n@endFrame"+_count+"\nM=D\n"
                + "//->retAddr=*(endFrame-5)\n"
                + "@5\nA=D-A\nA=M\nD=M\n@retAddr"+_count +"\nM=D\n"
                + "//->*ARG=pop()\n"
                + "@SP\nM=M-1\nA=M\nD=M\n@ARG\nA=M\nM=D\n"
                + "//->SP=ARG+1\n"
                + "@ARG\nD=M+1\n@SP\nM=D\n"
                + "//->THAT=*(endFrame-1)\n"
                + "@endFrame"+_count+"\nA=M-1\nA=M\nD=M\n@THAT\nM=D\n"
                + "//->THIS=*(endFrame-2)\n"
                + "@endFrame"+_count+"\nD=M\n@2\nA=D-A\nA=M\nD=M\n@THIS\nM=D\n"
                + "//->ARG=*(endFrame-3)\n"
                + "@endFrame"+_count+"\nD=M\n@3\nA=D-A\nA=M\nD=M\n@ARG\nM=D\n"
                + "//->LCL=*(endFrame-4)\n"
                + "@endFrame"+_count+"\nD=M\n@4\nA=D-A\nA=M\nD=M\n@LCL\nM=D\n"
                + "//->goto retAddr\n"
                + "@retAddr"+_count+"\n0;JMP\n";
        break;
...
Reply | Threaded
Open this post in threaded view
|

Re: Return code or Call code not working, cont.

cadet1620
Administrator
I'll take a look at the Java in a bit.  Could you email me the compete NestedCall.asm (or Sys.asm depending on how you generated it) file. It might be easier to step through the return code to see where it went wrong.

--Mark
Reply | Threaded
Open this post in threaded view
|

Re: Return code or Call code not working, cont.

cadet1620
Administrator
In reply to this post by ShiraJoseph
You can save a lot of RAM by using R13 and R14 for FRAME and retAddr in the return code.
//->endFrame = LCL
@LCL
D=M
@R13
M=D
//->retAddr=*(endFrame-5)
@5
A=D-A
A=M
D=M
@R14
M=D
These temporaries are only used during the return code so they don't need to be unique.

The real cool thing about this is that then the return code is identical for all instances of return.  You can put a ($RETURN) label at the start of it the first time you generate it and all other returns only need to jump to that label!

--Mark
Reply | Threaded
Open this post in threaded view
|

Re: Return code or Call code not working, cont.

cadet1620
Administrator
In reply to this post by ShiraJoseph
Look reallly close at all your D=M instructions.  There are at least 2 of them that should be D=A in the call code.

                + "//->push returnAddress\n"
                + "@retAddr"+_count+ "\nD=A\n@SP\nA=M\nM=D\n@SP\nM=M+1\n"
 
                + "//->ARG=SP-5-nArgs\n"
                + "@SP\nD=M\n@5\nD=D-A\n@"+_VMcommand.substring(_VMcommand.lastIndexOf(" ")+ 1, _VMcommand.length())
                + "\nD=D-A\n@ARG\nM=D\n"

I haven't looked closely at the function or return code yet.

--Mark
Reply | Threaded
Open this post in threaded view
|

Re: Return code or Call code not working, cont.

cadet1620
Administrator
In reply to this post by ShiraJoseph
Return has a problem with all of its
    xxx=*(endFrame-n)
implementations.  They are doing double dereferencing, that is **(endFrame-n).

There is also a problem with the jump to the return address.  The correct return address value is in retAddr_n, but you are not using it correctly.

--Mark
Reply | Threaded
Open this post in threaded view
|

Re: Return code or Call code not working, cont.

ShiraJoseph
Ok, ok, I see; I was treating retAddr and endFrame as variables, stored in its own RAM.  But in fact, those variables are virtual machine side only; from the vm's perspective, it is saying "use this address number," not "use this variable for your address number."
Reading through the other things you mentioned now.