Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Watcom C/C++ User's Guide - the following form of the auxiliary pragma can be used to specify the http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
The following form of the auxiliary pragma can be used to specify the
registers that are to be used to pass arguments to a particular function.

+--------------------------------------------------------------------------+
|      #pragma aux sym parm {reg_set} [;]                                  |
|                                                                          |
+--------------------------------------------------------------------------+

where
    description

sym
    is a function name.

reg_set
    is called a register set.  The register sets specify the registers that
    are to be used for argument passing.  A register set is a list of
    registers separated by spaces and enclosed in square brackets.

Register sets establish a priority for register allocation during argument
list processing.  Register sets are processed from left to right.  However,
within a register set, registers are chosen in any order.  Once all register
sets have been processed, any remaining arguments are pushed on the stack.

Note that regardless of the register sets specified, only certain
combinations of registers will be selected for arguments of a particular
type.

Note that arguments of type float and double are always pushed on the stack
when the "fpi" or "fpi87" option is used.

double
    Arguments of type double can only be passed in the following register
    combination:  AX:BX:CX:DX.  For example, if the following register set
    was specified for a routine having an argument of type double,


         [AX BX SI DI]

    the argument would be pushed on the stack since a valid register
    combination for 8-byte arguments is not contained in the register set.
     Note that this method for passing arguments of type double is supported
    only when the "fpc" option is used.  Note that this argument passing
    method does not include the passing of 8-byte structures.

far pointer
    A far pointer can only be passed in one of the following register pairs:
     DX:AX, CX:BX, CX:AX, CX:SI, DX:BX, DI:AX, CX:DI, DX:SI, DI:BX, SI:AX,
    CX:DX, DX:DI, DI:SI, SI:BX, BX:AX, DS:CX, DS:DX, DS:DI, DS:SI, DS:BX,
    DS:AX, ES:CX, ES:DX, ES:DI, ES:SI, ES:BX or ES:AX.  For example, if a
    far pointer is passed to a function with the following register set,


         [ES BP]

    the argument would be pushed on the stack since a valid register
    combination for a far pointer is not contained in the register set.

long int, float
    The only registers that will be assigned to 4-byte arguments (e.g.,
    arguments of type long int,) are:  DX:AX, CX:BX, CX:AX, CX:SI, DX:BX,
    DI:AX, CX:DI, DX:SI, DI:BX, SI:AX, CX:DX, DX:DI, DI:SI, SI:BX and BX:AX.
     For example, if the following register set was specified for a routine
    with one argument of type long int,


         [ES DI]

    the argument would be pushed on the stack since a valid register
    combination for 4-byte arguments is not contained in the register set.
     Note that this argument passing method includes 4-byte structures.
     Note that this argument passing method includes arguments of type float
    but only when the "fpc" option is used.

int
    The only registers that will be assigned to 2-byte arguments (e.g.,
    arguments of type int) are:  AX, BX, CX, DX, SI and DI.  For example, if
    the following register set was specified for a routine with one argument
    of type int,


         [BP]

    the argument would be pushed on the stack since a valid register
    combination for 2-byte arguments is not contained in the register set.

char
    Arguments whose size is 1 byte (e.g., arguments of type char) are
    promoted to 2 bytes and are then assigned registers as if they were
    2-byte arguments.

others
    Arguments that do not fall into one of the above categories cannot be
    passed in registers and are pushed on the stack.  Once an argument has
    been assigned a position on the stack, all remaining arguments will be
    assigned a position on the stack even if all register sets have not yet
    been exhausted.

Notes:

 1. The default register set is [AX BX CX DX].

 2. Specifying registers AH and AL is equivalent to specifying register AX.
    Specifying registers DH and DL is equivalent to specifying register DX.
     Specifying registers CH and CL is equivalent to specifying register CX.
     Specifying registers BH and BL is equivalent to specifying register BX.

 3. If you are compiling for a memory model with a small data model, or the
    "zdp" compiler option is specified, any register combination containing
    register DS becomes illegal.  In a small data model, segment register DS
    must remain unchanged as it points to the program's data segment.  Note
    that the "zdf" compiler option can be used to specify that register DS
    does not contain that segment address of the program's data segment.  In
    this case, register combinations containing register DS are legal.

Consider the following example.


     #pragma aux myrtn parm [ax bx cx dx] [bp si];

Suppose myrtn is a routine with 3 arguments each of type long int.

 1. The first argument will be passed in the register pair DX:AX.

 2. The second argument will be passed in the register pair CX:BX.

 3. The third argument will be pushed on the stack since BP:SI is not a
    valid register pair for arguments of type long int.

It is possible for registers from the second register set to be used before
registers from the first register set are used.  Consider the following
example.


     #pragma aux myrtn parm [ax bx cx dx] [si di];

Suppose myrtn is a routine with 3 arguments, the first of type int and the
second and third of type long int.

 1. The first argument will be passed in the register AX.

 2. The second argument will be passed in the register pair CX:BX.

 3. The third argument will be passed in the register set DI:SI.

Note that registers are no longer selected from a register set after
registers are selected from subsequent register sets, even if all registers
from the original register set have not been exhausted.

An empty register set is permitted.  All subsequent register sets appearing
after an empty register set are ignored; all remaining arguments are pushed
on the stack.

Notes:

 1. If a single empty register set is specified, all arguments are passed on
    the stack.

 2. If no register set is specified, the default register set [AX BX CX DX]
    is used.

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson