Is it alright to store temporary variables FRAME and RET in R13-R15

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

Is it alright to store temporary variables FRAME and RET in R13-R15

kraftwerk1611
Hi all,

This question refers to Figure 8.5, page 163 i.e table that shows psuedo code for VM implementation.

My question is is it alright to use registers R13-R15 to store temporary variables FRAME and RET When implementing 'return' from inside a function?

If I declare variables like @FRAME, then I guess they would go to static segment, which is reserved for class level variables.

Is there any other way to store these variables somewhere else?

What happens if inside a function you need to store more than 3 temporary variables and R13,R14 and R14 are already being used?

I would appreciate a reply.

Thank you.  
Reply | Threaded
Open this post in threaded view
|

Re: Is it alright to store temporary variables FRAME and RET in R13-R15

cadet1620
Administrator
This post was updated on .
Yes, you can use R13-R15 for anything that you want in your generated ASM code.  They are what you should use for RET and FRAME.

You should not use R13-R15 for temporary variables across multiple VM commands. For example "function" VM command must not store something in a temporary variable that the "return" command needs to use. That variable would be overwritten if the function called called another function.

One thing that you can do using R13-R15 is Assembly Language Functions. Pick one of the registers to be your return pointer.
    @$RIP_123
    D=A
    @$DO_XXX
    0;JMP
($RIP_123)
Then $DO_XXX can contain the long ASM implementation for a VM command.
($DO_XXX)
    @R15    // save RIP
    M=D
    // the long asm code for XXX commands goes here
    @R15
    0;JMP   // go back to caller
This way if XXX comands require something like 15 instructions and there are 100 XXX commands in the program, it will only take 4*100 + (15+4) ASM instructions instead of 1500.

This can be especially effective for "call" commands which are quite long. (But get your calls working in-line before adding this commplication. You don't need to do this optimization for the nand2tetris projects.)

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

Re: Is it alright to store temporary variables FRAME and RET in R13-R15

kraftwerk1611
Thank you.

Why @$RIP_123 in your code endsup with value @16 but @$DO_XXX ends up with a value of @4 and not @17?

And so it is okay to use variable names like @x, @y in asm code? I have been trying to avoid them  in my code  order to not  touch the RAM[16]...RAM[255] area.
Reply | Threaded
Open this post in threaded view
|

Re: Is it alright to store temporary variables FRAME and RET in R13-R15

cadet1620
Administrator
kraftwerk1611 wrote
Why @$RIP_123 in your code endsup with value @16 but @$DO_XXX ends up with a value of @4 and not @17?

And so it is okay to use variable names like @x, @y in asm code? I have been trying to avoid them  in my code  order to not  touch the RAM[16]...RAM[255] area.
There was a typo in my code. The code label for ($RIP_123) was missing the "$".

You don't want to use named RAM variables like @x in your generated code because they reduce the amount of RAM available for variables in the "static" segment. A few would be OK, but hundreds would be a problem.  You should be able to write all your ASM using just the R13-R15 variables.

The $DO_XXX and $RIP_123 in my example are ROM addresses.

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

Re: Is it alright to store temporary variables FRAME and RET in R13-R15

kraftwerk1611
Thank you for the reply,

I have finished coding return using only given registers. and passed the SimpleFunction.tst.



I have, however, put retrieving back saved state and going back to caller code in single function. I could not decide if it would be a better option for later coding to split retrieve saved state and actual returning back in separate functions.

The SimpleFunction.tst is in fact not that simple.

By the way could it  create trouble later if we and VM Emulator are using the different registers (R13-R15) for different purposes?

Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Is it alright to store temporary variables FRAME and RET in R13-R15

cadet1620
Administrator
kraftwerk1611 wrote
By the way could it  create trouble later if we and VM Emulator are using the different registers (R13-R15) for different purposes?
Since the VM Emulator only interprets VM code, the ASM your VM Translator generates will not cause any problems.

I have, however, put retrieving back saved state and going back to caller code in single function. I could not decide if it would be a better option for later coding to split retrieve saved state and actual returning back in separate functions.
If you are talking about your translator's code organization, there is no particular advantage or disadvantage. The code might read better with pushState() and popState() functions that are right next to each other so that it is easy to see that they are doing inverse operations.

The "call" command code writer function will call pushState() and return's code writer will call popState. No other code writers will call these functions.

If you are talking about your Generated ASM code and the ASM functions I mentioned, a single block of code will run marginally faster.


Notice the the ASM code that is generated for "return" is always exactly the same.  You can write it for the first "return" command that you process, preceded with a label like ($RETURN). All other "return" command are nothing more than a jump to the first instance of return code.

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

Re: Is it alright to store temporary variables FRAME and RET in R13-R15

A_Random_Person
In reply to this post by kraftwerk1611
Well, that's exactly what I did. 😎