'function f n' clarification

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

'function f n' clarification

Dimenus
Apologies. I'm trying to understand why we specify the number of local elements when declaring the function header and then push them on to the stack when the vm code pushes/initializes them on the stack anyway right below the header.

Ex:

In SimpleFunction, I would expect to have two values immediately pushed onto the stack, but we push four.
function SimpleFunction.test 2

push local 0

push local 1

add

not

push argument 0

add

push argument 1

sub

return
Reply | Threaded
Open this post in threaded view
|

Re: 'function f n' clarification

ybakos
It comes down to the function call protocol.

First, before jumping to a function's body to start its execution, the caller must push its arguments onto the stack, and then jump to the instructions.

Second, when allocating memory for a stack frame, the second argument of the vm "function" command (eg, 2), indicates how much memory must be allocated for local variables.

Third, when the function returns, all of the memory it occupied, including the arguments it was passed, are "gone," and in their place is the single return value.

The SimpleFunction test is simply assuming that there are two arguments and two locals, doing some manipulation, and checking the result.

function SimpleFunction.test 2 // part of the challenge is figuring this out
push local 0 // push the first local var's value onto the stack
push local 1 // push the second local var's value onto the stack
add
not
push argument 0 // push the first argument onto the stack
add
push argument 1 // push the second argument onto the stack
sub
return // this is part of the fun too

Reply | Threaded
Open this post in threaded view
|

Re: 'function f n' clarification

cadet1620
Administrator
In reply to this post by Dimenus
Dimenus wrote
Apologies. I'm trying to understand why we specify the number of local elements when declaring the function header and then push them on to the stack when the vm code pushes/initializes them on the stack anyway right below the header.

Ex:

In SimpleFunction, I would expect to have two values immediately pushed onto the stack, but we push four.
function SimpleFunction.test 2
push local 0
push local 1
add
not
push argument 0
add
push argument 1
sub
The local 1 and local 2 pushes are part of an expression evaluation and will not normally be seen in functions. They are referencing local variables that have not yet been set by let statements.

This code is testing that both local variables were initialized to 0 by the function entry code.

The equivalent Jack code is:
    function int test(int a, int b)
    {
        var int i, j;
        return ((~(i+j))+a)-b;
    }
The expression could be rewritten as (a-b)+(~(i+j)) and it will return the same value. In that case the VM code would be:
function SimpleFunction.test 2
push argument 0
push argument 1
sub
push local 0
push local 1
add
not
add
return
--Mark

Reply | Threaded
Open this post in threaded view
|

Re: 'function f n' clarification

Dimenus
This post was updated on .
In reply to this post by ybakos
ybakos wrote
Second, when allocating memory for a stack frame, the second argument of the vm "function" command (eg, 2), indicates how much memory must be allocated for local variables.
Edit: The lightbulb just went on. I've got it it now. I was just confused because I thought SP was 317 when it's really 319 in the simple example. 317/318 are the local memory segment and the pushed values are required in order to do ops because the local stack actually begins at 319. So what I thought were four 'stack' values are actually two stack values and the local memory segment.
Reply | Threaded
Open this post in threaded view
|

Re: 'function f n' clarification

ybakos
Awesome, keep going, Dimenus!