HP OpenVMS systems
The OpenVMS Run-Time Library is a set of language-independent routines that establish a common run-time environment for user programs. The procedures ensure correct operation of complex language features and help enforce consistent operations on data across languages.
The HP OpenVMS Calling Standard describes the mechanisms used by OpenVMS languages
for invoking routines and passing data between them. In effect, this
standard describes the interface between your program and the run-time
library routines that your program calls. This chapter describes the
basic methods for coding calls to run-time library routines from an
OpenVMS common language.
When you call a run-time library routine from your program, you must furnish whatever arguments the routine requires. When the routine completes execution, in most cases it returns control to your program. If the routine returns a status code, your program should check the value of the code to determine whether or not the routine completed successfully. If the return status indicates an error, you may want to change the flow of execution of your program to handle the error before returning control to your program.
When you log in, the operating system creates a process that exists until you log out. When you run a program, the system activates an executable image in your process. This image consists of a set of user procedures.
From the run-time library's point of view, user procedures are procedures that exist outside the run-time library and that can call run-time library routines. When you write a program that calls a run-time library routine, the run-time library views your program as a user procedure. User procedures also can call other user procedures that are either supplied by HP or written by you. Because an OpenVMS native-mode language compiler program exists outside the run-time library, compiler-generated programs that call any run-time library routine are also defined as a set of user procedures.
The main program, or main procedure, is the first user procedure that the system calls after calling a number of initialization procedures. A user program consists of the main program and all of the other user procedures that it calls.
Figure 19-1 shows the calling relationships among a main program, other user procedures, library routines, and the operating system. In this figure, Call indicates that the calling procedures requested some information or action; Return indicates that the called procedure returned the information to the calling procedure or performed the action.
Figure 19-1 Calling the Run-Time Library
Each run-time library routine requires a specific calling sequence. This calling sequence indicates the elements that you must include when calling the routine, and the order of those elements. The form of a calling sequence first specifies the type of call being made. A library routine can be invoked either by a CALL instruction or possibly by a JSB instruction (for VAX systems only) as follows:
On VAX systems, the following restrictions apply to the different types of calls:
Each routine is identified by a unique entry point name consisting of the facility prefix (for example, MTH$) and the procedure name (for example, MTH$SIN). Run-time library entry points follow the OpenVMS conventions for naming global symbols. A global entry point takes the following general form:
The elements that make up this format represent the following:
|fac||A 2- or 3-character facility name|
|symbol||A 1- to 27-character symbol|
The facility names are maintained in a systemwide HP registry. A unique, 12-bit facility number is assigned to each facility name for use in (1) condition value symbols, and (2) condition values in procedure return status codes, signaled conditions, and messages. The high-order bit of this number is 0 for facilities assigned by HP and 1 for those assigned by Application Project Services (APS) and customers. For further information, refer to the HP OpenVMS Calling Standard.
The run-time library facility names are as follows:
|PPL$||Parallel processing routines|
|SMG$||Screen management routines|
Arguments passed to a routine must be listed in your call entry in the order shown in the format section of the routine description. Each argument has four characteristics: OpenVMS usage, data type, access type, and passing mechanism. These characteristics are described in Chapter 17.
Some arguments are optional. Optional arguments are indicated by brackets in the routine descriptions. When your program invokes a run-time library routine using a CALL entry point, you can omit optional arguments at the end of the argument list. If the optional argument is not the last argument in the list, you must either pass a zero by value or use a comma to indicate the place of the omitted argument. Some languages, such as C, require that you pass zero by value for trailing optional arguments. See your language processor documentation for further information.
On VAX systems, the calling program passes an argument list of longwords to a called routine; each longword in the argument list specifies a single argument. Note that a 64-bit floating-point argument would count as 2 longword arguments in the list.
On Alpha systems, the calling program passes arguments in an argument item sequence; each quadword in the sequence specifies a single argument item. Note that the argument item sequence is formed using R16--21 or F16--21 (a register for each argument). The argument item sequence can have a mix of integer and floating-point items that use both register types but must not repeat the same number.
For I64, parameters are passed in a combination of general registers, floating-point registers, and memory, as illustrated in Figure 18-9. The first eight parameters are passed in R32 through R39, with the parameter count in R25 and subsequent parameters in quadwords on the stack.
In the Alpha, VAX, and I64 environments, the called routine interprets each argument using one of three standard passing mechanisms: by value, by reference, or by descriptor. For more information on arguments, see Sections 18.4 and 18.5.
LIB$GET_INPUT get-str [,prompt-str] [,out-len]
A FORTRAN program could include any one of the following calls to this procedure:
INTEGER*4 STAT . . . STAT = LIB$GET_INPUT (GET_STR,PROMPT,LENGTH) STAT = LIB$GET_INPUT (GET_STR,PROMPT) STAT = LIB$GET_INPUT (GET_STR,PROMPT,) STAT = LIB$GET_INPUT (GET_STR,,LENGTH) STAT = LIB$GET_INPUT (GET_STR) STAT = LIB$GET_INPUT (GET_STR,) STAT = LIB$GET_INPUT (GET_STR,%VAL(0))
The following examples illustrate the standard mechanism for calling an external procedure, subroutine, or function in most high-level languages.
CALL LIB$MOVTC(SRC, FILL, TABLE, DEST) STATUS = LIB$GET_INPUT(STRING, 'NAME:')
LOCAL MSG_DESC : BLOCK [8,BYTE]; MSG_DESC [DSC$B_CLASS] = DSC$K_CLASS_S; MSG_DESC [DSC$B_DTYPE] = DSC$K_DTYPE_T; MSG_DESC [DSC$W_LENGTH] = 5; MSG_DESC [DSC$A_POINTER] = MSG; STATUS = LIB$PUT_OUTPUT(MSG_DESC);
#include <lib$routines.h> #include <descrip.h> $DESCRIPTOR(name, "Name:"); struct dsc$descriptor_s string: . . . status = lib$get_input(&string, &name);
CALL LIB$MOVTC USING BY DESCRIPTOR SRC, FILL, TABLE, DEST, GIVING RET-STATUS.
CALL LIB$MOVTC(SRC, FILL, TABLE, DEST) STATUS = LIB$GET_INPUT(STRING, 'NAME:')
RET_STATUS := LIB$MOVTC (SRC, FILL, TABLE, DEST);
CALL LIB$MOVTC(SRC, FILL, TABLE, DEST); STATUS = LIB$GET_INPUT(STRING, 'NAME:');
In VAX MACRO, a calling sequence takes one of three forms, as illustrated by the following examples:
CALLS #2,G^LIB$GET_INPUT CALLG ARGLIST, G^LIB$GET_VM JSB G^MTH$SIN_R4
As these examples show, high-level languages use different forms of the
call statement. Each language's user guide gives specific information
about calling the run-time library from that language.
188.8.131.52 JSB Call Entries (VAX Only)
On VAX systems, JSB entry point names follow the naming conventions explained in Section 19.2.1, except that they include a suffix indicating the number of the highest register accessed or modified. This suffix helps ensure that the calling program and the called routine agree on the number of registers that the called routine is going to change.
The following example illustrates the VAX MACRO code that invokes the library routine MTH$SIN_R4 by means of a JSB instruction. As indicated in the JSB entry point name, this routine uses R0 through R4.
JSB G^MTH$SIN_R4 ;F_floating sine uses R0 through R4
JSB entry points are available only to VAX MACRO and VAX BLISS
programs. No VAX high-level language provides a mechanism for accessing
JSB entry points.
19.2.3 Returns from an RTL Routine
On VAX systems, some run-time library routines return a function value. Typically on a VAX system, the return is in the form of a 32-bit value in register R0 or a 64-bit value in registers R0 and R1. In high-level languages, statuses or function return values in R0 appear as the function result. When a routine returns a function value in R0, it cannot also use R1 to return a status code. Therefore, such a procedure signals errors rather than returning a status. For more information, refer to the HP OpenVMS Calling Standard or the description of LIB$SIGNAL in the HP OpenVMS RTL Library (LIB$) Manual.
On Alpha systems, a standard function returns its function value in R0, F0, or F0 and F1. A function value of less than 64 bits returned by immediate value in R0 is zero-extended or sign-extended to a full quadword as required by the data type. Note that a floating function value is returned by immediate value in F0 or in F0 and F1.
For I64, values up to 128 bits are returned directly in the registers (R8, R9 or F8, F9), according to the rules in Table 18-15. Integer, enumeration, record, and set values (bit vectors) smaller than 64 bits must be zero-filled (unsigned integers, enumerations, records, sets) or sign-extended (signed integrals) to a full 64 bits. However, for unsigned 32-bit integers, bit 31 is replicated in bits 32--63.
When floating-point values are returned in floating-point registers,
they are returned in the register format, rounded to the appropriate
precision. When they are returned in the general registers (for
example, as part of a record), they are returned in their memory format.
184.108.40.206 Facility Return Status and Condition Value Symbols
Library return status and condition value symbols have the following general form:
The elements that make up this format represent the following:
|fac||The 2- or 3-letter facility symbol|
|abc||The first 3 letters of the first word of the associated message|
|mno||The first 3 letters of the next word|
|xyz||The first 3 letters of the third word, if any|
Articles and prepositions are not considered significant words in this format. If a significant word is only two letters long, an underscore is used to fill out the third space. Some examples follow. Note that, in most facilities, the normal or success symbol is an exception to the convention described here.
|SS$_NORMAL||Routine successfully completed|
|LIB$_INSVIRMEM||Insufficient virtual memory|
|MTH$_FLOOVEMAT||Floating overflow in mathematics library procedure|
|OTS$_FATINTERR||Fatal internal error in a language-independent support procedure|
|LIB$_SCRBUFOVF||Screen buffer overflow|
This section describes how to code MACRO calls to library routines
using a CALLS, CALLG, or JSB instruction for VAX systems. The routine
descriptions that appear later in this manual describe the entry points
for each routine. You can use either a CALLS or a CALLG instruction to
invoke a procedure with a CALL entry point. You must use a JSB
instruction to invoke a procedure with a JSB entry point. All MACRO
calls are explicitly defined.
19.3.1 VAX MACRO Calling Sequence
All run-time library routines have a CALL entry point. Some routines also have a JSB entry point. In MACRO, you invoke a CALL entry point with a CALLS or CALLG instruction. To access a JSB entry point, use a JSB instruction.
Arguments are passed to CALLS and CALLG entry points by a pointer to the argument list. The only difference between the CALLS and CALLG instructions is as follows:
Both of these instructions have the same effect on the called procedure.
JSB instructions execute faster than CALL instructions. They do not set up a new stack frame, do not change the enabling of hardware traps or faults, and do not preserve the contents of any registers before modifying them. For these reasons, you must be careful when invoking a JSB entry point in order to prevent the loss of information stored by the calling program.
Whichever type of call you use, the actual reference to the procedure entry point should use general-mode addressing (G^). This ensures that the linker and the image activator are able to locate the module within the shareable image.
In most cases, you have to tell a library routine where to find input values and store output values. You must select a data type for each argument when you code your program. Most routines accept and return 32-bit arguments.
For input arguments of byte, word, or longword values, you can supply a constant value, a variable name, or an expression in the run-time library routine call. If you supply a variable name for the argument, the data type of the variable must be as large as or larger than the data types that the called procedure requires. For example, if the called procedure expects a byte in the range 0 to 100, you can use a variable data type of a byte, word, or longword with a value between 0 and 100.
For each output argument, you must declare a variable of exactly the
length required to avoid extraneous data. For example, if the called
procedure returns a byte value to a word-length variable, the leftmost
8 bits of the variable <15:8> are not overwritten on output.
Conversely, if a procedure returns a longword value to a word-length
variable, it modifies variables in the next higher word.
19.3.2 VAX MACRO CALLS Instruction Example
Before executing a CALLS instruction, you must push the necessary arguments on the stack. Arguments are pushed in reverse order; the last argument listed in the calling sequence is pushed first. The following example shows how a MACRO program calls the procedure that allocates virtual memory in the program region for LIB$GET_VM.
.PSECT DATA PIC,USR,CON,REL,GBL,NOSHR,NOEXE,RD,WRT,NOVEC MEM: .LONG 0 ; Longword to hold address of ; allocated memory LEN: .LONG 700 ; Number of bytes to allocate .PSECT CODE PIC,USR,CON,REL,GBL,SHR,EXE,RD,NOWRT,NOVEC .ENTRY PROG, ^M<> PUSHAL MEM ; Push address of longword ; to receive address of block PUSHAL LEN ; Push address of longword ; containing number of bytes ; desired CALLS #2, G^LIB$GET_VM ; Allocate memory BLBC R0, 1$ ; Branch if memory not available RET 1$: PUSHL R0 ; Signal the error CALLS #1, G^LIB$SIGNAL RET .END PROG
Because the stack grows toward location 0, arguments are pushed onto
the stack in reverse order from the order shown in the general format
for the routine. Thus, the base-address argument, here
called START, is pushed first, and then the
number-bytes argument, called LEN. Upon return from
LIB$GET_VM, the calling program tests the return status
(ret-status), which is returned in R0 and branches to
an appropriate error routine if an error occurred.
19.3.3 VAX MACRO CALLG Instruction Example
When you use the CALLG instruction, the arguments are set up in any location, and the call includes a reference to the argument list. The following example of a CALLG instruction is equivalent to the preceding CALLS example.
ARGLST: .LONG 2 ; Argument list count .ADDRESS LEN ; Address of longword containing ; the number of bytes to allocate. .ADDRESS START ; Address of longword to receive ; the starting address of the ; virtual memory allocated. LEN: .LONG 20 ; Number of bytes to allocate START: .BLKL 1 ; Starting address of the virtual ; memory. CALLG ARGLIST, G^LIB$GET_VM ; Get virtual memory BLBC R0, ERROR ; Check for error BRB 10$