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.