Parameter passing convention

Language reference ›› Procedures and functions ››
Parent Previous Next

See also: Open array parameters.



Standard Pascal convention:

By default, parameters are passed by value, even arrays or records.

An argument may be optionally CONST, VAR or OUT.


Special PMP behavior:

As boolean are implemented as single bits, there's no pointers to booleans, so a VAR BOOLEAN argument is implemented by the compiler as a copy before and after the procedure or function call.

Warning: If the boolean is an I/O or any SFR bit, it will be updated at procedure/function return only.


CONST <simple-type> is always passed by value in the current implementation.

Other CONST, VAR or OUT arguments are passed by address in the procedure or function arguments pseudo variables.

Addresses are generated as BYTE or WORD, as pointers, depending on the processor's memory configuration and the $POINTERS directive state.


Argument types must match exactly if they are by-address CONST, VAR or OUT, or must be compatible otherwise.


An OUT argument is a special VAR form; PMP may optimize the code, or emit a warning if used in an expression since it knows that the variable is not initialized at entry (future implementation).


Parameters can be of type SFR. An SFR is always passed by address, even if declared as CONST. An SFR parameter is always treated as volatile and so never optimized.

Parameters can be of type “open array”; this type of parameter is always passed by address, along with a stealth upper bound parameter.


A CONST parameter may be qualified as ROMABLE (not standard Pascal). In this case, PMP generates a special code that may deal either with a RAM or ROM pointer. This code will be a bit less efficient but may be useful in some cases (a good example is to pass ROM strings or arrays by value without copying them into a RAM buffer first).


A CONST parameter may also be restricted by using the ROM qualifier (not standard Pascal). In this case, PMP generates a special code that deals only with a ROM pointer. This code may be useful in some cases (a good example is to pass only ROM strings or arrays by value without copying them into a RAM buffer first).



PROCEDURE Test(X: BYTE; VAR Y: BYTE; VAR Z: BOOLEAN; S: SFR);
 BEGIN
   …
 END;

PROCEDURE Init(CONST ROMABLE T: ARRAY OF BYTE; VAR Dest: STRING);
 VAR I: BYTE;
 BEGIN
   FOR I := low(T) TO high(T) DO SomeProc(T[I], Dest);
 END;

VAR A: BYTE; B: BYTE; C: BOOLEAN;
   S: ^SFR;

 Test(A + 1, B, C, S^);

The call to Test(A + 1, B, C, S^) will generate the following sequence:

    1. Compute A+1.
    2. Move result to Test.X,
    3. Move B address to Test.Y,
    4. Move C value to Test.Z,
    5. Move S content to Test.S,
    6. Call Test,
    7. Move Test.Z value to C.