Need some clarification on how the static vm should function I understand that it should be mapped from ram 16 in the order it appears in the code e.g.
Pop static 4-value goes to ram 16 (instead of ram 20)
Pop static 8-value goes to ram 17(instead of ram 24)
Do I apply the same principle to push?
Push static 6 - pushes value @ram 22? For some reason this has really confused me.
I need some guidance implementing this in assemebly code, my first idea was to just store a index in a temp variable which increments by 1 each time there is a static function and thenjust add the base address 16 to it?
There is an interesting feature in HACK assembly called "Free Variables". Basically, if a name is used without it being a label, it will be treated as a free variable and assigned an address in the range of 16-255 inclusive. That is, if you write in HACK assembly
Assuming freevar isn't a label, it will be assigned an address (let's say 16) and every time it's used it will have the same address. The next free var will be assigned address 17 and so on.
This feature is very useful for implementing the static segment. Basically, if you have a file Named Xxx.vm and you have a static variable in it named var, you should generate a HACK assembly symbol in the format "Xxx.var". That is, this static variable will be assigned to a RAM cell in the 16-255 range.
Pushing static variable to the stack would mean to push the value stored in that cell. Popping from the stack to the static variable means copying the value from the top of the stack to that address (and adjusting the stack pointer accordingly of course).
Let's say you have a class Ball with one static variable named count. This static variable will be represented in the virtual machine as "static 0". E.g.:
push static 0 // push Ball.count on the stack
pop static 0 // pop the top of the stack into Ball.count
Suppose you have another class, Paddle, which also has one static variable named position. This will also be represented as "static 0". The difference is, that the first variable is accessible only from Ball.vm and the second one only from Paddle.vm.
When we translate these variables to HACK assembly we need to ensure that they are 2 different places in the memory. We can use the free variable feature as I described before, but instead of naming them Ball.count and Paddle.position, we'll name them Ball.0 and Paddle.0. The assembler will assign them unique addresses in the range 16-255 and all is good.
I think the crux of your confusion is that you have it in your mind that the code you generate in going from the VM code to ASM code has to explicitly map each static variable to a specific address in memory.
You don't. When you wrote the assembler, part of the contract is that the assembler performs this mapping by placing each unique variable name (a name that is not a label) it encounters into a unique memory location, starting at address 16. So all your VM translator has to do is ensure that every static variable in every file somehow gets a unique name in the resulting assembly language program. The assembler takes it form there.
When a new symbol that is not a label or a predefined symbol, the symbol is assigned to a new RAM address in the RAM, starting from RAM and ending at RAM (Before where the stack starts) If you invoke the symbol again, it is replaced by its assigned RAM address, like how SP is assigned to 0. So in your translated code pop static 4 probably appeared somewhere before pop static 8 All you need to do in your push is to use ProgramName.StaticIndex to indicate a certain static variable. I hope this clairifies your confusion.