The value for x must go into the FRAME, since it is an escaping variable.  Hence the first MOVE  calculates the stack location by taking an offset of –4 from the temporary t1.  t1 in this case is the Frame Pointer – and so the value for x is being stored in the location one location 'above' the Frame Pointer, assuming a word size of 4.

In the function f, you can see that the destination address for the assignment is another calculation.  This time it is at offset –4 from the temporary t2.  What is this temporary?  Well, look at the call to f.  You can see that the temporary t1 is being passed as a parameter.  What is t1?  Well, we said just a moment ago that it was the frame pointer.  So the frame pointer is passed as a parameter to f – and in fact this parameter is the static link.  It is passed implicitly.

Note that there is no static link assigned for the outmost frame – created for tigermain.  So –4 is the location of the first local variable that is a frame variable, then –8 and so on, when these are declared in the outermost scope.  If a local variable must be stored in the frame in a function, then you will find that –4 is the offset reserved for the static link, so then –8 will be the offset for the first, -12 for the second and so on.  Formal parameters will be stored in temporary variables if they are are NOT escaping.  If they escape, you will find them at offsets 0,4,8,12 etc. (I.e. above the frame pointer in memory)

You should experiment with this using a number of different programs, with the variables and parameters all doing different things re: escaping, and with a number of nested functions.