HP OpenVMS Systems Documentation

Content starts here

HP Pascal for OpenVMS
User Manual


Previous Contents Index


Chapter 5
Calling Conventions

This chapter describes how HP Pascal passes parameters and calls routines. It discusses the following topics:

For More Information:

  • On declaring and calling HP Pascal routines (HP Pascal for OpenVMS Language Reference Manual)
  • On procedure-calling and argument-passing mechanisms (HP OpenVMS Calling Standard)

5.1 OpenVMS Calling Standard

Programs compiled by the HP Pascal compiler conform to the OpenVMS calling standard. This standard describes how parameters are passed, how function values are returned, and how routines receive and return control. Because HP Pascal conforms to the calling standard, you can call and pass parameters to routines written in other Hewlett-Packard languages from HP Pascal programs.

For More Information:

  • See the HP OpenVMS Calling Standard

5.1.1 Parameter Lists

Each time a routine is called, the HP Pascal compiler constructs a parameter list.

On OpenVMS I64 systems, the parameters are a sequence of quadword (8-byte) entries. The first 8 integer parameters are located in integer registers designated as R32 to R39; the first 8 floating-point parameters are located in floating-point registers designated as F8 to F15. Information about the parameter list is passed in the argument information register (R25). The first byte of the register specifies the parameter count. Arguments beyond 8 are passed on the stack starting at offset +16.

On OpenVMS Alpha systems, the parameters are a sequence of quadword (8-byte) entries. The first 6 integer parameters are located in integer registers designated as R16 to R21; the first 6 floating-point parameters are located in floating-point registers designated as F16 to F21. Information about the parameter list is passed in the argument information register (R25). The first byte of the register specifies the parameter count. Arguments beyond 6 are passed on the top of the stack.

On OpenVMS VAX systems, the parameters are a sequence of longword (4-byte) entries pointed to by the array pointer (AP). The first byte of the first entry in the list is a parameter count, which indicates how many parameters follow in the list.

The form in which the parameters in the list are represented is determined by the passing mechanisms you specify in the formal parameter list and the values you pass in the actual parameter list. The parameter list contains the actual parameters passed to the routine.

5.1.2 Function Return Values

In HP Pascal, a function returns to the calling block the value that was assigned to its identifier during execution. HP Pascal chooses one of three methods for returning this value. The method chosen depends on the amount of storage required for values of the type returned, as follows:

On OpenVMS I64 Systems:

  • An nonfloating-point scalar type, a schematic subrange, an array, a record, or set with size less than 64 bits, is returned in the first integer register, designated as r8 . If the value is less than 64 bits, r8 is sign-extended or zero-extended depending on the type.
  • A floating-point value that can be represented in 64 bits of storage is returned in the first floating-point register, designated as f8 .
  • If the value is too large to be represented in 64 bits, if its type is a string type (PACKED ARRAY OF CHAR, VARYING OF CHAR, or STRING), or if the type is nonstatic, the calling routine allocates the required storage. An extra parameter (a pointer to the location where the function result will be stored) is added to the beginning of the calling routine's actual parameter list.

On OpenVMS Alpha Systems:

  • An nonfloating-point scalar type, a schematic subrange, an array, a record, or set with size less than 64 bits, is returned in the first integer register, designated as r0 . If the value is less than 64 bits, r0 is sign-extended or zero-extended depending on the type.
  • A floating-point value that can be represented in 64 bits of storage is returned in the first floating-point register, designated as f0 .
  • If the value is too large to be represented in 64 bits, if its type is a string type (PACKED ARRAY OF CHAR, VARYING OF CHAR, or STRING), or if the type is nonstatic, the calling routine allocates the required storage. An extra parameter (a pointer to the location where the function result will be stored) is added to the beginning of the calling routine's actual parameter list.

On OpenVMS VAX Systems:

  • If the value can be represented in 32 bits of storage, it is returned in register R0. If the value is less than 32 bits, the upper bits of R0 are undefined.
  • If the value requires from 33 to 64 bits, the low-order bits of the result are returned in register R0 and the high-order bits are returned in register R1.
  • If the value is too large to be represented in 64 bits, if its type is a string type (PACKED ARRAY OF CHAR, VARYING OF CHAR, or STRING), or if the type is nonstatic, the calling routine allocates the required storage. An extra parameter (a pointer to the location where the function result will be stored) is added to the beginning of the calling routine's actual parameter list.

Note that functions that require the use of an extra parameter can have no more than 254 parameters; functions that store their results in registers can have 255 parameters.

5.1.3 Contents of the Call Stack

The OpenVMS I64 and OpenVMS Alpha system conventions define three types of procedures. The calling process does not need to know what type it is calling; the compiler chooses which type to generate based on the requirements of the procedure.

On OpenVMS I64 Systems:

On OpenVMS I64 systems, the types of procedures are:

  • Memory stack procedures
    These procedures allocate a memory stack and may maintain part or all of its caller's context on that stack.
  • Register stack procedures
    These procedures allocate only a register stack and maintains its caller's context in registers.
  • Null frame procedures
    These procedures do not allocate a memory stack or a register stack and therefore preserve no context of its caller. However, unlike an OpenVMS Alpha null frame procedure, these procedures do not execute in the context of its caller.

On OpenVMS I64 systems, the compiler determines the exact contents of the memory stack frame, but all memory stack frames have common characteristics:

  • Scratch area: A 16-byte region is provided as scratch storage for procedures that are called by the current procedure. Leaf procedures need not allocate this area. A procedure can use the 16 bytes pointed to by the stack pointer as scratch memory, but the contents of this area are not preserved by a procedure call.
  • Arguments passed in memory: Parameters beyond those passed in registers are stored in this area of the memory stack frame. A procedure accesses its incoming parameters in the outgoing parameter area of its caller's memory stack frame.
  • Local storage: A procedure can store local variables, temporaries, and spilled registers in this area. There are specific conventions that affect the layout for spilled registers.

On OpenVMS Alpha Systems:

On OpenVMS Alpha systems, the types of procedures are:

  • Stack frame procedures, in which the calling context is placed on the stack
  • Register frame procedures, in which the calling context is in registers
  • No frame procedures, for which the compiler does not establish a context and which, therefore, execute in the context of the caller

If a stack frame is required, it consists of a fixed part (which is known at compile time) and an optional variable part.

The compiler determines the exact contents of the stack frame, but all stack frames have common characteristics:

  • Fixed temporary locations: This is an optional section that contains language-specific locations required by the procedure context of some languages
  • Register save area: This is a set of consecutive quadwords for storing registers saved and restored by the current procedure
  • Argument home area: If allocated, this is a region of memory used by the called process to assemble the arguments passed in registers adjacent to the arguments passed in memory. This allows all arguments to be addressed as a contiguous array. The argument home area is also used to store arguments passed in registers if an address for such an argument is required.
  • Arguments passed in memory

On OpenVMS VAX Systems:

Each time a routine is called by an HP Pascal program on an OpenVMS VAX system, the hardware creates a call frame structure on the call stack. The call frame for each active routine contains the following:

  • A pointer to the call frame of the previous routine call. This pointer is called the saved frame pointer (FP).
  • The saved argument pointer (AP) of the previous routine call.
  • The storage address of the point at which the routine was called; that is, the address of the instruction following the call to the current routine. This address is called the saved program counter (PC).
  • The saved contents of other general registers. Based on a mask specified in the control information, the system restores the saved contents of these registers to the calling routine when control returns to it.

When execution of a routine ceases, the system uses the frame pointer in the call frame of the current routine to locate the frame of the previous routine. The system then removes the call frame of the current routine from the stack.

For More Information:

  • On procedure types and characteristics (HP OpenVMS Calling Standard)

5.1.4 Unbound Routines

The frame pointer of calling routines is stored in an implementation-defined register. If, however, you declare a routine with the UNBOUND attribute, the system does not assume that the frame pointer of the calling routine is stored in a register and there is no link between the calling and the called routines. As a result, an unbound routine has the following restrictions:

  • It cannot access automatic variables declared in enclosing blocks.
  • It cannot call bound routines declared in enclosing blocks.
  • It cannot use a GOTO statement to transfer control to enclosing blocks other than the main program block.

By default, routines declared at program or module level and all other routines declared with the INITIALIZE, GLOBAL, or EXTERNAL attributes have the characteristics of unbound routines. Routines passed by the immediate value mechanism must be UNBOUND.

Asynchronous system trap routines (ASTs) and RMS completion routines must have both the ASYNCHRONOUS and UNBOUND attributes. Because they are asynchronous, such routines can access only volatile variables, predeclared routines, and other asynchronous routines. Note that the HP Pascal run-time system does not permit a program and an asynchronous routine (such as an AST) to access the same file simultaneously.

For More Information:

  • On attributes (HP Pascal for OpenVMS Language Reference Manual)
  • On the immediate value mechanism ( Section 5.3.1)

5.2 Parameter-Passing Semantics

Parameter-passing semantics describe how parameters behave when passed between the calling and called routine. HP Pascal passes parameter values by the following methods:

  • Value passing semantics (Standard)
  • Variable passing semantics (Standard)
  • Foreign passing semantics (HP Pascal extension)

By default, HP Pascal passes arguments using value semantics.

For More Information:

  • On value, variable, and foreign semantics (HP Pascal for OpenVMS Language Reference Manual)

5.3 Parameter-Passing Mechanisms

The way in which an argument specifies how the actual data to be passed by the called routine is defined by the parameter-passing mechanism. In compliance with the OpenVMS calling standard, HP Pascal supports the basic parameter-passing mechanisms, shown in Table 5-1.

Table 5-1 Parameter-Passing Descriptions
Mechanism Description
By immediate value The argument contains the value of the data item.
By reference The argument contains the address of the data to be used by the routine.
By descriptor The argument contains the address of a descriptor, which describes type of the data and its location.

By default, HP Pascal uses the by reference mechanism to pass all actual parameters except those that correspond to conformant parameters and undiscriminated schema parameters, in which case the by descriptor mechanism is used. Table 5-2 describes the syntax you use in HP Pascal to obtain the desired parameter-passing mechanism.

Table 5-2 Parameter-Passing Syntax on HP Pascal
Mechanism Syntax Used by HP Pascal
By immediate value %IMMED or [IMMEDIATE]
By reference Default for nonconformant and nonschema parameters or %REF
By descriptor Default for conformant and schema parameters or %DESCR, %STDESCR, [CLASS_S],[CLASS_A], or [CLASS_NCA]

A mechanism specifier usually appears before the name of a formal parameter, or if a passing attribute is used it appears in the attribute list of the formal parameter. However, in HP Pascal, a mechanism specifier can also appear before the name of an actual parameter. In the latter case, the specifier overrides the type, passing semantics, passing mechanism, and the number of formal parameters specified in the formal parameter declaration.

For More Information:

5.3.1 By Immediate Value

The by immediate value passing mechanism passes a copy of a value instead of the address. HP Pascal provides the %IMMED foreign passing mechanism and the IMMEDIATE attribute in order to pass a parameter by immediate value. You cannot use variable semantics with the by immediate value passing mechanism.

On OpenVMS I64 and OpenVMS Alpha systems, values that are less than or equal to 64 bits in size can be passed by immediate value.

On OpenVMS VAX systems, values that are less than or equal to 32 bits in size can be passed by immediate value.

5.3.2 By Reference

The by reference mechanism passes the address of the parameter to the called routine. This is the default parameter-passing mechanism for non-conformant and non-schematic parameters.

When using the by reference mechanism, the type of passing semantics used depends on the use of the VAR keyword. If the formal parameter name is preceded by the reserved word VAR, variable semantics is used; otherwise, value semantics is used.

In addition to using the defaults, the HP Pascal compiler provides the %REF foreign passing mechanism and the REFERENCE attribute, which has more than one interpretation for the passing semantics depending on the data item represented by the actual parameter. This allows you to have the called routine use either variable semantics or true foreign semantics. The mechanism specifier appears before the name of a formal parameter. The parameter passing attribute appears in the attribute list of the formal parameter.

5.3.3 By Descriptor

There are several types of descriptors. Each descriptor contains a value that identifies the descriptor's type. The called routine then uses the information held in the descriptor to identify its type and size. This is the default parameter-passing mechanism for conformant and schematic parameters.

When you use one of the HP Pascal by descriptor mechanisms, the compiler passes the address of a string, array, or scalar descriptor. The HP Pascal compiler generates the descriptor supplying the necessary information.

HP Pascal provides three attributes for the by descriptor passing mechanism: [CLASS_S], [CLASS_A], and [CLASS_NCA]. With these three attributes, the type of passing semantics used for the by descriptor argument depends on the use of the VAR keyword. If the formal parameter name is preceded by the reserved word VAR, variable semantics is used; otherwise, value semantics is used. The parameter-passing attribute appears in the attribute list of the formal parameters.

Sometimes you may want to choose either variable semantics or true foreign semantics. In these cases, the HP Pascal compiler provides two foreign passing mechanism specifiers, %DESCR and %STDESCR. These specifiers have more than one interpretation for the passing semantics depending on the data type of the actual parameter. The mechanism specifier appears before the name of a formal parameter.

Table 5-3 lists the class and type of descriptor generated for parameters that can be passed using the by descriptor mechanism.

Table 5-3 Parameter Descriptors
Parameter Type Descriptor Class and Type
  %DESCR %STDESCR Value or VAR Semantics
Ordinal DSC$K_CLASS_S 1 --- ---
SINGLE DSC$K_CLASS_S,
DSC$K_DTYPE_F,
DSC$K_DTYPE_FS
--- ---
DOUBLE DSC$K_CLASS_S,
DSC$K_DTYPE_D,
DSC$K_DTYPE_G,
DSC$K_DTYPE_FT
--- ---
QUADRUPLE DSC$K_CLASS_S
DSC$K_DTYPE_H/_FX 6
--- ---
RECORD --- --- ---
ARRAY DSC$K_CLASS_A/_NCA 2,5 DSC$K_CLASS_S
DSC$K_DTYPE_T 3
---
ARRAY OF
VARYING OF
CHAR
DSC$K_CLASS_VSA
DSC$K_DTYPE_VT
--- ---
Conformant
ARRAY
DSC$K_CLASS_A/_NCA 2,5 DSC$K_CLASS_S
DSC$K_DTYPE_T 3
DSC$K_CLASS_A/_NCA 2,5
Conformant
ARRAY OF
VARYING OF
CHAR 4
DSC$K_CLASS_VSA
DSC$K_DTYPE_VT
--- DSC$K_CLASS_VSA
DSC$K_DTYPE_VT
VARYING OF
CHAR
DSC$K_CLASS_VS
DSC$K_DTYPE_VT
--- ---
Conformant
VARYING OF
CHAR
DSC$K_CLASS_VS
DSC$K_DTYPE_VT
--- DSC$K_CLASS_VS
DSC$K_DTYPE_VT
STRING --- --- DSC$K_CLASS_VS
DSC$K_DTYPE_VT
Schema
name
--- --- Internal HP Pascal descriptor
Discriminated
schema
--- --- ---
SET DSC$K_CLASS_S
DSC$K_DTYPE_Z
--- ---
FILE DSC$K_CLASS_S
DSC$K_DTYPE_Z
---  
Pointer DSC$K_CLASS_S
DSC$K_DTYPE_LU
--- ---
PROCEDURE or
FUNCTION
DSC$K_CLASS_S
DSC$K_DTYPE_BPV
--- Bound procedure
value by reference
  CLASS_A CLASS_NCA CLASS_S
Ordinal --- --- DSC$K_CLASS_S 1
SINGLE --- --- DSC$K_CLASS_S,
DSC$K_DTYPE_F,
DSC$K_DTYPE_FS
DOUBLE --- --- DSC$K_CLASS_S,
DSC$K_DTYPE_D,
DSC$K_DTYPE_G,
DSC$K_DTYPE_FT
QUADRUPLE --- --- DSC$K_CLASS_S
DSC$K_DTYPE_H/_FX 6
RECORD --- --- ---
ARRAY DSC$K_CLASS_A 2 DSC$K_CLASS_NCA 2 DSC$K_CLASS_S
DSC$K_DTYPE_T 3
ARRAY OF
VARYING OF
CHAR
--- --- ---
Conformant
ARRAY
DSC$K_CLASS_A 2 DSC$K_CLASS_NCA 2 DSC$K_CLASS_S
DSC$K_DTYPE_T 3
Conformant
ARRAY OF
VARYING OF
CHAR 4
--- --- ---
VARYING OF
CHAR
--- --- ---
Conformant
VARYING OF
CHAR
--- --- ---
STRING --- --- ---
Schema
name
--- --- ---
Discriminated
schema
--- --- ---
SET --- --- DSC$K_CLASS_S
DSC$K_DTYPE_Z
FILE --- --- DSC$K_CLASS_S
DSC$K_DTYPE_Z
Pointer --- --- DSC$K_CLASS_S
DSC$K_DTYPE_LU
PROCEDURE or
FUNCTION
--- --- ---

1Descriptor's D_type depends on size of type.
2Descriptor's D_type depends on component type.
3Only if PACKED ARRAY OF CHAR.
4Component type can be a conformant VARYING OF CHAR.
5 CLASS_NCA is used on OpenVMS I64 and OpenVMS Alpha systems. CLASS_A is used on OpenVMS VAX systems.
6 DTYPE_FX is used on OpenVMS I64 and OpenVMS Alpha systems. DTYPE_H is used on OpenVMS VAX systems.


Previous Next Contents Index