HP OpenVMS Programming Concepts Manual
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
- 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
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
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
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
.ENTRY START , ^M<>
PUSHAQ PROMPT_D ; Push address of prompt
PUSHAQ STRING_D ; Push address of string
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
CALLS #1 , G^LIB$SIGNAL
10$: MOVL #SS$_NORMAL , R0 ; Success, or name too
19.3.6 Function Return Values in VAX MACRO (VAX and Alpha)
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:
R0 and R1
R0 through R3
R0 through R3
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.
19.4 Calling a Library Routine in BLISS
This section describes how to code BLISS calls to library routines. A
called routine can return only one of the following:
- No value.
- A function value (typically, an integer or floating point number).
For example, MTH$SIN returns its result as an F_floating value in R0 on
VAX systems, in F0 on Alpha systems, or in R8 on I64 systems.
Alpha processors, BLISS cannot access floating point registers. Direct
use of the I64 floating-point registers is not supported.
- A return status (typically, a 32-bit condition value) indicating
that the routine has either executed successfully or failed. For
example, LIB$GET_INPUT returns a return status in R0 (R8, R9 for I64).
If the routine executes successfully, it returns SS$_NORMAL; if not, it
returns one of several possible error condition values. BLISS treats
the return status like any other value.
19.4.1 BLISS Calling Sequence
Scalar arguments are usually passed to run-time library routines by
reference. Thus, when a BLISS program passes a variable, the variable
appears with no preceding period in the procedure-call actual argument
list. A constant value can be easily passed by using the %REF built-in
The following example shows how a BLISS program calls LIB$PUT_OUTPUT.
This routine writes a record at the user's terminal.
MODULE SHOWTIME(IDENT='1-1' %TITLE'Print time', MAIN=TIMEOUT)=
LIBRARY 'SYS$LIBRARY:STARLET'; ! Defines system services, etc.
DESC=%CHARCOUNT(%REMAINING), ! VAX string descriptor
UPLIT BYTE(%REMAINING) %; ! definition
FMTDESC=UPLIT( DESC('At the tone, the time will be ',
%CHAR(7), '!%T' ));
TIMEBUF: VECTOR, ! 64-bit system time
MSGBUF: VECTOR[80,BYTE], ! Output message buffer
MSGDESC: BLOCK[8,BYTE], ! Descriptor for message buffer
RSLT: WORD; ! Length of result string
! Initialize the fields of the string descriptor.
$GETTIM(TIMADR=TIMEBUF); ! Get time as 64-bit integer
$FAOL(CTRSTR=FMTDESC, ! Format descriptor
OUTLEN=RSLT, ! Output length (only a word!)
OUTBUF=MSGDESC, ! Output buffer desc.
PRMLST= %REF(TIMEBUF)); ! Address of 64-bit
! time block
MSGDESC [DSC$W_LENGTH] = .RSLT; ! Modify output desc.
RETURN (LIB$PUT_OUTPUT(MSGDESC); ! Return status
19.4.2 Accessing a Return Status in BLISS
BLISS accesses a function return value or condition value returned in
R0 (R8, R9 for I64) as follows:
STATUS = LIB$PUT_OUTPUT(MSG_DESC);
IF NOT .STATUS THEN LIB$STOP(.STATUS);
19.4.3 Calling JSB Entry Points from BLISS
I64 register usage differs from that of Alpha and VAX. If you use
OpenVMS high-level languages, the register and register mapping
differences in the calling standards are handled by the compilers and
are not exposed to your code. However, if your code uses BLISS linkages
to interface with Macro-32 source code, your code might have to take
into account the differences in register mapping.
BLISS added a new qualifier and source level switch to enable register
mapping for register numbers in linkage and register declarations. It
is off by default. BLISS also has additional support for linkages that
See your compiler documentation for additional information.
Many of the library mathematics routines have JSB entry points. You can
invoke these routines efficiently from a BLISS procedure using LINKAGE
and EXTERNAL ROUTINE declarations, as in the following example:
MODULE JSB_LINK (MAIN = MATH_JSB, ! Example of using JSB linkage
IDENT = '1-001',
ADDRESSING_MODE(EXTERNAL = GENERAL)) =
LINK_MATH_R4 = JSB (REGISTER = 0; ! input reg
REGISTER = 0): ! output reg
MTH$SIND_R4 : LINK_MATH_R4;
ROUTINE MATH_JSB = ! Routine
INPUT_VALUE : INITIAL (%E'30.0'),
! Get the sine of single floating 30 degrees. The input, 30 degrees,
! is passed in R0, and the answer, is returned in R0. Registers
! 0 to 4 are modified by MTH$SIND_R4.
MTH$SIND_R4 (.INPUT_VALUE ; SIN_VALUE);
END; ! End of routine
END ! End of module JSB_LINK
Calling System Services
The OpenVMS operating system kernel has many services that are made
available to application and system programs for use at run time. These
system services are procedures that the OpenVMS operating system uses
to control resources available to processes; to provide for
communication among processes; and to perform basic operating system
functions, such as the coordination of input/output operations.
This chapter describes the basic methods and conventions for coding
calls to system services from OpenVMS high-level languages or from an
For more information about using the system services that support
64-bit addressing and to see example programs that demonstrate the use
of these services, refer to Chapter 11.
System services are called by using the conventions of the
HP OpenVMS Calling Standard. The programming languages that generate VAX, Alpha, or
I64 native mode instructions provide mechanisms for specifying the
When you call a system service from your program, you must furnish
whatever arguments the routine requires. When the system service
procedure completes execution, in most cases it returns control to your
program. If the service returns a status code, your program should
check the value of the code to determine whether or not the service
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 write a program that calls a system service in the OpenVMS
operating system, the operating system 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 operating system, compiler
generated programs calling any system service are also defined as a set
of user procedures.
If you program in a high-level language, refer to Chapter 21 for
information about the SYS$LIBRARY:SYS$LIB_C.TLB file, which is an
OpenVMS Alpha and OpenVMS I64 library of C header files.
For VAX MACRO, system service macros generate argument lists and CALL
instructions to call system services. These macros are located in the
system library (see SYS$LIBRARY:STARLET.MLB). When you assemble a
source program, this library is searched automatically for unresolved
references. (See Appendix D for further details.) Similar macros are
available for BLISS and are located in SYS$LIBRARY:STARLET.REQ.
20.2 Preserving System Integrity
As described in this document and the HP OpenVMS System Services Reference Manual, many system
services are available and suitable for application programs, but the
use of some of these powerful services must be restricted to protect
the performance of the system and the integrity of user processes.
For example, because the creation of permanent mailboxes uses system
dynamic memory, the unrestricted use of permanent mailboxes could
decrease the amount of memory available to other users. Therefore, the
ability to create permanent mailboxes is controlled: a user must be
specifically assigned the privilege to use the Create Mailbox
(SYS$CREMBX) system service to create a permanent mailbox.
The various controls and restrictions applied to system service usage
are described in this chapter. The Description section of each system
service in the HP OpenVMS System Services Reference Manual lists any privileges and quotas necessary
to use the service.
20.2.1 User Privileges
The system manager, who maintains the user authorization file for the
system, grants privileges for access to the protected system services.
The user authorization file contains, in addition to profile
information about each user, a list of specific user privileges and
When you log in to the system, the privileges and quotas assigned to
you are associated with the process created on your behalf. These
privileges and quotas are applied to every image the process executes.
When an image issues a call to a system service that is protected by
privilege, the privilege list is checked. If you have the specific
privilege required, the image is allowed to execute the system service;
otherwise, a condition value indicating an error is returned.
For a list of privileges, see the description of the Create Process
($CREPRC) system service in the HP OpenVMS System Services Reference Manual.
20.2.2 Resource Quotas
Many system services require certain system resources for execution.
These resources include system dynamic memory and process quotas for
I/O operations. When a system service that uses a resource controlled
by a quota is called, the process's quota for that resource is checked.
If the process has exceeded its quota, or if it has no quota allotment,
an error condition value may be returned.
20.2.3 Access Modes
A process can execute at any one of four access modes: user,
supervisor, executive, or kernel. The access modes determine a
process's ability to access pages of virtual memory. Each page has a
protection code associated with it, specifying the type of
access---read, write, or no access---allowed for each mode.
For the most part, user-written programs execute in user mode; system
programs executing at the user's request (system services, for example)
may execute at one of the other three, more privileged access modes.
In some system service calls, the access mode of the caller is checked.
For example, when a process tries to cancel timer requests, it can
cancel only those requests that were issued from the same or less
privileged access modes. For example, a process executing in user mode
cannot cancel a timer request made from supervisor, executive, or
Note that many system services use access modes to protect system
resources, and thus employ a special convention for interpreting access
mode arguments. You can specify an access mode using a numeric value or
a symbolic name. Table 20-1 shows the access modes and their numeric
values, symbolic names, and privilege ranks.
Table 20-1 OpenVMS System Access Modes
The symbolic names are defined by the symbolic definition macro
System services that permit an access mode argument allow callers to
specify only an access mode of equal or lesser privilege than the
access mode from which the service was called. If the specified access
mode is more privileged than the access mode from which the service was
called, the less privileged access mode is always used.
To determine the mode to use, the operating system compares the
specified access mode with the access mode from which the service was
called. Because this operation results in an access mode with a higher
numeric value (when the access mode of the caller is different from the
specified access mode), the access mode is said to be
Because much of the code you write executes in user mode, you can omit
the access mode argument. The argument value defaults to 0 (kernel
mode), and when this value is compared with the value of the current
execution mode (3, user mode), the higher value (3) is used.
20.3 System Service Call Entry
The Format section of each system service description in the
HP OpenVMS System Services Reference Manual indicates the positional dependencies and keyword names
of each argument, as shown in the following format:
$SERVICE arga ,argb ,argc ,argd
This format indicates that the macro name of the service is $SERVICE
and that it requires four arguments, ordered as shown and with keyword
names arga, argb,
argc, and argd.
Arguments passed to a service must be listed in your call entry in the
order shown in the Format section of the service description. Each
argument has four characteristics: OpenVMS usage, data type, access
type, and passing mechanism. These characteristics are described in
The OpenVMS Alpha and OpenVMS I64 SYS$LIBRARY:SYS$LIB_C.TLB file
contains C function prototypes for system services. These prototypes
are documented in HP OpenVMS System Services Reference Manual: A--GETUAI and and HP OpenVMS System Services Reference Manual: GETUTC--Z. For each
prototype, the manuals provide the correct syntax (which shows the
arguments the function accepts in the order in which it expects them),
a description of each argument, and the type of data returned by the
Some arguments are optional. Optional arguments are indicated by
brackets in the service descriptions. When your program invokes a
system service by 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 a zero by value for all
trailing optional arguments. See your language processor documentation
for further information.
In the call statement of a high-level language program, you must prefix
the macro function service name with SYS (the system service facility
prefix). For example, the call statement in a C program procedure that
calls the SYS$GETDVI system service with four arguments is as follows:
return_status = sys$getdvi( event_flagnum, channel, &devnam, &item_list,0,0,0);
Note that in C, you must not omit the optional trailing arguments and
should pass a zero by value for these unused parameters. See your
language processor documentation for further information.
The HP OpenVMS System Services Reference Manual provides a description of each service that indicates
how each argument is to be passed. Phrases such as "an
address" and "address of a character string descriptor"
identify reference and descriptor arguments, respectively. Terms like
"Boolean value," "number," "value," or
"mask" indicate an argument that is passed by value.
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.
On VAX systems, the calling program passes an argument list of
longwords to a called service; each longword in the argument list
specifies a single argument.
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--R21 or F16--F21 (a register for each argument).
On I64 systems, the first eight parameters are passed in R32 through
R39, with the parameter count in R25 and subsequent parameters in
quadwords on the stack.
For more detailed information on arguments lists and passing
mechanisms, see Sections 18.4 and 18.5.
Some services also require service-specific data structures that either
indicate functions to be performed or hold information to be returned.
The HP OpenVMS System Services Reference Manual includes descriptions of these service-specific data
structures. You can use this information and information from your
programming language manuals to define such service-specific item lists.