9.1.3 Passing arguments

(1)

Registers used for passing arguments

The registers used for passing arguments are AX, BC, and DE.

(2)

Target for argument allocation, argument type, and size change

The targets for allocating arguments, argument types, and how to change the size are shown below.

Changes can be accepted only for those described below.

Argument Class

Target for Argument Allocation

Argument Type and Size Change

When the function prototype can be referenced and the parameter type can be referenced

Register or stack

When allocating a far pointer argument to registers, it is allocated to registers for three bytes.

When the function prototype can be referenced but the parameter type cannot be referenced (= variable argument)

Stack

Argument type conforms to default argument promotions.

When the function prototype cannot be referenced

Register or stack

Argument type conforms to default argument promotions.

When allocating a far pointer argument to registers as the result of default argument promotions, it is allocated to registers for three bytes.

Caution 1.

For the variable size or default argument promotions, see "(7) Default argument promotions".

Caution 2.

The argument immediately before a variable argument is handled as "when the function prototype can be referenced and the parameter type can be referenced".

(3)

Register allocation of arguments

Arguments are allocated to registers as follows.

-

A target to be allocated to registers is an argument whose size is 4 bytes or less.
Note that when an argument of the structure type or union type is to be allocated to registers, the included padding will also be allocated to registers.

-

When the argument is a structure or union, all members are allocated either to registers or in the stack.

-

For a far pointer, the lower three bytes are allocated to registers.
The page number part (= upper four bits of the 20-bit far address) of a far pointer is stored in the lower four bits of a register to which the upper one byte among the three bytes will be allocated.
For example, when allocating a far pointer to registers A-DE, the page number part is stored in the lower four bits of register A.

-

Register allocation is processed in the order from the first argument to the last argument (from left to right in the source program), and allocates each argument to the register with the highest priority among available registers. If there are no available registers, arguments are allocated in the stack. The priorities of the registers are shown below.

Argument Size

Priority of Register to which Argument is Allocated (left side has the highest priority)

1-byte

A, X, C, B, E, D

2-byte

AX, BC, DE

3-byte

C-AX, X-BC, E-BC, X-DE, B-DE

4-byte

far pointer: A-DE, X-DE, C-DE, B-DE,X-BC

Other than far pointer: BC-AX, DE-BC

 

"-" in this table is a symbol to associate 8-bit or 16-bit registers to other 16-bit registers.

Each argument is allocated to registers so that the descending order of addresses (from upper address to lower address) for the bytes composing the argument matches the register specification order (from left to right) shown in the above table.

Example 1.

When calling to a function declared as "void foo (char p1, short p2, char p3)", p1 is allocated to register A, p2 is allocated to register BC, and p3 is allocated to register X.

Example 2.

When structure-type argument S shown below is allocated to registers, c1 is allocated to register X and s2 is allocated to register BC. Padding is allocated to register A.

struct {
        char    c1;
        short   s2;
} S;

Example 3.

When calling to a function declared as "void foo (long x)", the upper 2 bytes of x are allocated to register BC and the lower 2 bytes are allocated to register AX.

Example 4.

When structure-type argument S3 shown below is allocated to registers, the highest byte is allocated to register C, the next one byte is allocated to register A, and the lowest byte is allocated to register X.

struct{
        char    a[3];
} S3;

Caution 1.

8-byte data, such as long long type data or double type data in the program to which option -dbl_size=8 is specified, is allocated in the stack

Caution 2.

A structure or union of five bytes or more is allocated in the stack while a structure or union of 4 bytes or less is a target for being allocated to registers.

(4)

Stack allocation of arguments

Arguments are allocated in the stack as follows.

-

Arguments to be passed by the stack are allocated in little endian mode and aligned at the 2-byte boundary.

-

The order for allocating the arguments to be passed by the stack is that the more the argument is on the left side in the argument sequence, the address is smaller.

-

The arguments to be passed by the stack are sequentially allocated in the stack except for the 1-byte padding which can be inserted between arguments.

-

Each argument is allocated in the stack so that the descending order of addresses (from upper address to lower address) for the bytes composing the argument matches the descending order of addresses (from upper address to lower address) in the stack.

-

For a far pointer, the lower three bytes are allocated to a 4-byte area in the stack. The value of the highest one byte of the 4 bytes is undefined. The page number part (= upper four bits of the 20-bit far address) of a far pointer is stored in the lower four bits of the second upper byte in the 4-byte area.

Caution

For the method of stack allocation, see section "9.1.5 Stack frame".

 

-

The arguments to be allocated to the stack are as follows.

-

Argument whose size is between one byte and 4 bytes and is not allocated to registers

-

Argument whose size is five bytes or more

-

Variable argument

 

Example

When calling to a function declared as "void foo (long long x)" and assuming that sp indicates the value of stack pointer immediately before the call site of the function, the highest one byte of x is allocated to the location indicated by sp + 7, each byte is allocated to sp + 6, sp + 5, sp + 4, sp + 3, sp + 2, and sp + 1 in the descending order of addresses, and the lowest byte is allocated to the location indicated by sp + 0.