11.2 Stack call functions

  --------------------------

 

      Stack functions are by default declared using an identifier which

  contains at least one lower-case letter. Stack functions can thus easily be

  distinguished from register functions, since lower-case letters are not

  allowed in the names of register functions.

 

      Parameters for stack functions, if there are any, can be of any type -

  byte, char, word, int, dword, long or float.

 

      Parameters are transferred according to the rules for each type of

  function. If the function has no declaration, the compiler will not keep

  track of the number and type of parameters being transferred. In this case

  there is more freedom in how they are used, but be sure to avoid

  incorrectly using them.

 

      The list of parameters indicates the type for each parameter.

  Parameters of the same type listed in a row are separated by commas. Formal

  parameters of different types in a function declaration are separated by a

  semicolon.

 

      In the following example a stack function returns the sum of all of its

  parameters (of different types) as a value of type word:

 

      word add_them_all (int a,b,c; byte d,e; word x,y)

      {

      return( a+b+c+d+e+x+y );

      }

 

      C-- originally used only Pascal type calls to stack functions. This has

  the advantage of greater compactness and a simpler method of code

  generation. Drawbacks of this call type, which are conversely advantages of

  the C call type, are rigid adherence to the number and type of transferred

  parameters (if you call a function using the pascal method but use the

  wrong number of parameters the stack will be corrupted.) I list below some

  technical details of both types of function call.

 

      Frame of C-- stack for close stack functions in pascal style:

 

       ADDRESS

        ...

      BP + FFFE second to last byte of local variables

      BP + FFFF last byte of local variable

      BP + 0000 Saved BP

      BP + 0002 RET address

      BP + 0004 last word of parameters transferred to functions

            (if they exist)

      BP + 0006 second to last word of parameters transferred to functions

      ...

      BP + nnnn first word of parameters transferred to functions

 

      The stack is freed of transferred functions directly in the function by

  the command 'RET nnnn', where nnnn is the size of the functions transferred

  to the stack.

 

      Frame of a C-- stack for close stack functions in C style:

 

       ADDRESS

        ...

      BP + FFFE second to last byte of local variables

      BP + FFFF last byte of local variables

      BP + 0000 Saved BP

      BP + 0002 RET address

      BP + 0004 first word of parameters transferred to functions (if they

            exist)

      BP + 0006 second word of parameters transferred to functions

       ...

      BP + nnnn last word of parameters transferred to functions

 

      Functions in C style end with the command 'RET'. The stack is freed of

  parameters at the same place where the function was called. Usually this is

  done using the command 'ADD SP,nnnn', i. e., the compiler can know

  precisely how many and what types of parameters are being transferred to

  the function in this case, and correspondingly it frees the stack after

  completing the function. This is very convenient for functions which can

  process a variable number of parameters (for instance printf functions).

 

      A function is declared as follows:

 

    rettype modif procname();

 

      First comes the obligatory type of return from the function. By

  default, for 16-bit programs this is equal to word, and for 32-bit programs

  dword. Then comes the equally obligatory modifier. By default all stack

  functions in C-- are in pascal style (except when compiling a Windows

  program, where by default the style of calling functions is stdcall). Next

  comes the name of the function with parentheses which indicate that a

  function and not a variable is being declared. The declaration ends with a

  semicolon.

 

      When declaring functions in C-- the function parameters need not be

  registered (in which case the compiler does not control the number of type

  of transferred parameters) but if they are included, this switches on the

  mechanism for monitoring the number and type of parameters.