parameter passing

When passing parameters before a call, another call may occur, such as:

   f( a, g(b))

=>
  pass 1 a
  pass 1 b  **
  call g
  pass 2 retval
  call f

We are using PV[0..LVMAX-1] to pass parameters for a call.  The line ** will overwrite the first "pass 1 a" causes incorrect parameter passing.  To correct it, parameter passing must be recursivable.  For example, instead of passing to an absolute place, let's pass to a stack.

=> 
  push a
  push b
  call g
  push retval
  call f

The stack segment is already existed.  It is used to save/restore registers when a call occurred.  We can use the space "after" the most recent frame to pass parameters.  A call will adjust fp properly as it knows the arity of the function call.  The SS view from the above sequence is:

   ...y 
     ^ fp

   push a    =>    y a
   push b    =>    y a b
   call g      =>     y a [ frame of g ]  =>  ... a 
   push retval =>  y a x
   call f       =       y [ frame of f ]  =>  y

The call instruction passes its parameters and saves caller's registers as follows:

   fp = fp - arity	       // fp is before 1st param   
   for(i=1; i<=nlocal; i++){
      if( i <= arity ){
        t = SS[fp+i]
        SS[fp+i] = M[i]  	// save register i
        M[i] = t                     // pass parameter i
      }else{
         SS[fp+i] = M[i]            // just save register i
      }
    }
    fp = fp + nlocal + 1	// create new frame
    SS[fp] = retads		// save return address

15 Jan 2006
     