HP OpenVMS Systems Documentation

Content starts here

OpenVMS Programming Concepts Manual


Previous Contents Index

19.2.2 The RTL Call Entry

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.

In the Alpha and VAX 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.

Optional arguments apply only to the CALL entry points. For example, the call format for a procedure with two optional arguments is as follows:


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.

BASIC


    CALL LIB$MOVTC(SRC, FILL, TABLE, DEST)

    STATUS = LIB$GET_INPUT(STRING, 'NAME:')

BLISS


    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);

C


 #include <lib$routines.h>
 #include <descrip.h>

     $DESCRIPTOR(name, "Name:");
     struct dsc$descriptor_s string:
        .
        .
        .
      status = lib$get_input(&string, &name);

COBOL


    CALL LIB$MOVTC USING BY DESCRIPTOR
        SRC,
        FILL,
        TABLE,
        DEST,
        GIVING RET-STATUS.

FORTRAN


    CALL LIB$MOVTC(SRC, FILL, TABLE, DEST)

    STATUS = LIB$GET_INPUT(STRING, 'NAME:')

Pascal


    RET_STATUS := LIB$MOVTC (SRC, FILL, TABLE, DEST);

PL/I


    CALL LIB$MOVTC(SRC, FILL, TABLE, DEST);

    STATUS = LIB$GET_INPUT(STRING, 'NAME:');

VAX MACRO

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.

19.2.2.1 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 OpenVMS Calling Standard or the description of LIB$SIGNAL in the 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.

19.2.3.1 Facility Return Status and Condition Value Symbols

Library return status and condition value symbols have the following general form:


fac$_abcmnoxyz

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

19.3 Calling a Library Procedure in VAX MACRO (VAX Only)

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:

  • For CALLS, the calling procedure pushes the argument list onto the stack (in reverse order) before performing the call. The list is automatically removed from the stack upon return.
  • For CALLG, the calling program specifies the address of the argument list, which can be anywhere in memory. This list remains in memory upon return.

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$

19.3.4 VAX MACRO JSB Entry Points

A procedure's JSB entry point name indicates the highest numbered register that the procedure modifies. Thus, a procedure with a suffix Rn modifies registers R0 through Rn. (You should always assume that R0 and R1 are modified.) The calling program loads the arguments in the registers before the JSB instruction is executed.

A calling program must use a JSB instruction to invoke a run-time library routine by means of its JSB entry point. You pass arguments to a JSB entry point by placing them in registers in the following manner:


NUM:    .FLOAT      0.7853981           ; Constant P1/4
        MOVF        NUM, R0             ; Set up input argument
        JSB         G^MTH$SIN_R4        ; Call F_floating sine procedure
                                        ; Return with value in R0

In this example, R4 in the entry point name indicates that MTH$SIN_R4 changes the contents of registers R0 through R4. The routine does not reference or change the contents of registers R5 through R11.

The entry mask of a calling procedure should specify all the registers to be saved if the procedure invokes a JSB routine. This step is necessary because a JSB procedure does not have an entry mask and thus has no way to specify registers to be saved or restored.

For example, consider program A calling procedure B by means of a CALL entry point.

  • Procedure B modifies the contents of R2 through R6, so the contents of these registers are preserved at the time of the call.
  • Procedure B then invokes procedure C by means of a JSB entry point.
  • Procedure C modifies registers R0 through R7.
  • When control returns to procedure B, R7 has been modified, but when procedure B passes control back to procedure A, it restores only R2 through R6. Thus, the contents of R7 are unpredictable, and program A does not execute as expected. Procedure B should be rewritten so that R2 through R7 are saved in procedure B's entry mask.

A similar problem occurs if the stack is unwound, because unwinding the stack restores the contents of registers for each stack frame as it removes the previous frame. Because a JSB entry point does not create a stack frame, the contents of the registers before the JSB instruction will not be restored unless they were saved in the entry mask of the calling program. You do this by naming the registers to be saved in the calling program's entry mask, so a stack unwind correctly restores all registers from the stack. In the following example, the function Y=PROC(A,B) returns the value Y, where Y = SIN(A)*SIN(B):


     .ENTRY  PROC, ^M <R2, R3, R4, R5>    ; Save R2:R5
     MOVF    @4(AP), R0                   ; R0 = A
     JSB     G^MTH$SIN_R4                 ; R0 = SIN(A)
     MOVF    R0 , R5                      ; Copy result to register
                                          ; not modified by MTH$SIN
     MOVF    @8(AP) , R0                  ; R0 = B
     JSB     G^MTH$SIN_R4                 ; R0 = SIN(B)
     MULF    R5 , R0                      ; R0 = SIN(A)SIN(B)
     RET                                  ; Return

19.3.5 Return Status

Your VAX MACRO program can test for errors by examining segments of the 32-bit status code returned by a run-time library routine.

To test for errors, check for a zero in bit 0 using a Branch on Low Bit Set (BLBS) or Branch on Low Bit Clear (BLBC) instruction.

To test for a particular condition value, compare the 32 bits of the return status with the appropriate return status symbol using a Compare Long (CMPL) instruction or the run-time library routine LIB$MATCH_COND.

There are three ways to define a symbol for the condition value returned by a run-time library routine so that you can compare the value in R0 with a particular error code:

  • Using the .EXTRN symbol directive. This causes the assembler to generate an external symbol declaration.
  • Using the $facDEF macro call. Calling the $LIBDEF macro, for example, causes the assembler to define all LIB$ condition values.
  • By default. The assembler automatically declares the condition value as an external symbol that is defined as a global symbol in the run-time library.

The following example asks for the user's name. It then calls the run-time library routine LIB$GET_INPUT to read the user's response from the terminal. If the string returned is longer than 30 characters (the space allocated to receive the name), LIB$GET_INPUT returns in R0 the condition value equivalent to the error LIB$_INPSTRTRU, 'input string truncated.' This value is defined as a global symbol by default. The example then checks for the specific error by comparing LIB$_INPSTRTRU with the contents of R0. If LIB$_INPSTRTRU is the error returned, the program considers that the routine executed successfully. If any other error occurs, the program handles it as a true error.


        $SSDEF                                  ; Define SS$ symbols
        $DSCDEF                                 ; Define DSC$ symbols
        .PSECT   $DATA
PROMPT_D:                                       ; Descriptor for prompt
        .WORD    PROMPT_LEN                     ; Length field
        .BYTE    DSC$K_DTYPE_T                  ; Type field is text
        .BYTE    DSC$K_CLASS_S                  ; Class field is string
        .ADDRESS PROMPT                         ; Address

PROMPT: .ASCII   /NAME: /                       ; String descriptor
PROMPT_LEN = . - PROMPT                         ; Calculate length of
                                                ; string

STR_LEN = 30                                    ; Use 30-byte string
STRING_D:                                       ; Input string descriptor
        .WORD    STR_LEN                        ; Length field
        .BYTE    DSC$K_DTYPE_T                  ; Type field in text
        .BYTE    DSC$K_CLASS_S                  ; Class field is string
        .ADDRESS STR_AREA                       ; Address
STR_AREA: .BLKB   STR_LEN                       ; Area to receive string

                 .PSECT $CODE
                 .ENTRY START , ^M<>
                 PUSHAQ PROMPT_D                ; Push address of prompt
                                                ; descriptor
                 PUSHAQ STRING_D                ; Push address of string
                                                ; descriptor

                 CALLS  #2 , G^LIB$GET_INPUT    ; Get input string
                 BLBS   R0 , 10$                ; Check for success
                 CMPL   R0 , #LIB$_INPSTRTRU    ; Error: Was it
                                                ; truncated string?
                 BEQL   10$                     ; No, more serious error
                 PUSHL  R0
                 CALLS  #1 , G^LIB$SIGNAL

10$:             MOVL   #SS$_NORMAL , R0        ; Success, or name too
                                                ; long
                 RET
                .END    START

19.3.6 Function Return Values in VAX MACRO

Function values are generally returned in R0 (32-bit values) or R0 and R1 (64-bit values). A MACRO program can access a function value by referencing R0 or R0 and R1 directly. For functions that return a string, the address of the string or the address of its descriptor is returned in R0. If a function needs to return a value larger than 64 bits, it must return the value by using an output argument.

Note the following exceptions to these rules:

  • JSB entry points in the MTH$ facility return H_floating values in R0 through R3.
  • One routine, MTH$SINCOS, returns two function values: the sine and the cosine of an angle. Depending on the data type of the function values, the function values are returned in the following registers:
    F_floating R0 and R1
    D_floating R0 through R3
    G_floating R0 through R3
    H_floating R0 through R7

As in the case of output arguments, a variable declared to receive the function values must be the same length as the value.


Previous Next Contents Index