The MACRO-64 assembler provides a library of macros that help you to program in conformance with the OpenVMS Calling Standard. This library also allows you to define your own opcodes and packed decimal data. The library, called MACRO64.MLB, is installed on your system with the MACRO-64 assembler. The MACRO-64 assembler automatically adds the MACRO64.MLB library to the library list before it begins processing your source program. Consequently, you do not need to add it manually using the .LIBRARY directive. The following macros are supplied by the MACRO-64 Assembler: $BEGIN_EPILOGUE $CALL $CODE_SECTION $DATA_SECTION $END_EPILOGUE $END_PROLOGUE $END_ROUTINE $LINKAGE_PAIR $LINKAGE_SECTION $OPDEF .PACKED $PROCEDURE_DESCRIPTOR $RESET_LP_LIST $RETURN $ROUTINE
1 – Routines and Lexical Scope
The calling-standard macros use the concept of a single, current, active routine. A routine is a programming entity that is associated with a procedure descriptor that may be called, or is a main routine specified as the transfer address of a linked image. Only one routine can be active or current at any given time during assembly. If more than one routine is defined in a single assembler source file, all items associated with the current routine, that is, within the lexical scope of the routine, must be completed before making a different routine current. The lexical scope of one routine cannot overlap the lexical scope of another routine. A routine becomes current or comes into scope by invoking the $ROUTINE macro with the appropriate arguments. $ROUTINE marks the beginning of the lexical scope of a routine. The complementary macro, $END_ROUTINE, marks the end of the current routine's lexical scope.
1.1 – Routines and Program Sections
Routines have three types of associated program sections: o Code section-Contains the executable instructions of the routine. This section is typically read-only and executable. o Data section-Contains data accessed by a routine. Typically, this is where variable data is stored. This section is typically nonexecutable, readable, and writeable. o Linkage section-Contains a routine's procedure descriptor and the necessary linkage information for calling other routines, and for linkage to data not in the linkage section, if any. Also, constant data may be placed here. Typically, this section is read-only and not executable. The linkage section is considered a type of data section with the following function: - Provides linkage information for calls made from a routine associated with the linkage section. - Provides linkage information for data outside of the linkage section. - Defines the associated routine's procedure descriptor so that calls can be made to the routine. - Defines constant or static data.
2 – Using Macros to Control Program Sections
The following section explains how to use the MACRO-64 supplied macros to define and control the various program sections during assembly.
2.1 – Defining Program Sections
Each of the three program section types can be referenced by a corresponding macro. The following three macros are used to refer to and define these three psects associated within a routine: o $CODE_SECTION-makes the routine's code psect current. o $DATA_SECTION-makes the routine's data psect current. o $LINKAGE_SECTION-makes the routine's linkage psect current. To switch to one of the current routine's sections, you invoke the corresponding macro. For example, after invoking $ROUTINE, to place instructions into the current routine's code psect, you invoke the $CODE_SECTION macro. This makes the code psect associated with the current routine the current psect. Similarly, invoking $LINKAGE_SECTION makes the linkage psect associated with the current routine the current psect. You can also control the psect name and attributes for each of the program sections by defining arguments to the $ROUTINE macro.
2.2 – Using Macro Defined Symbols
When you use any of the supplied macros described in this chapter, with the exception of $OPDEF, the following register symbols are defined for you: .DEFINE_IREG $IA0 R16 ; Integer argument 0 .DEFINE_IREG $IA1 R17 ; Integer argument 1 .DEFINE_IREG $IA2 R18 ; Integer argument 2 .DEFINE_IREG $IA3 R19 ; Integer argument 3 .DEFINE_IREG $IA4 R20 ; Integer argument 4 .DEFINE_IREG $IA5 R21 ; Integer argument 5 .DEFINE_FREG $FA0 F16 ; Floating-point argument 0 .DEFINE_FREG $FA1 F17 ; Floating-point argument 1 .DEFINE_FREG $FA2 F18 ; Floating-point argument 2 .DEFINE_FREG $FA3 F19 ; Floating-point argument 3 .DEFINE_FREG $FA4 F20 ; Floating-point argument 4 .DEFINE_FREG $FA5 F21 ; Floating-point argument 5 .DEFINE_IREG $AI R25 ; Argument-information register .DEFINE_IREG $RA R26 ; Return-address register .DEFINE_IREG $PV R27 ; Procedure-value register .DEFINE_IREG $FP R29 ; Frame pointer .DEFINE_IREG $SP R30 ; Stack pointer NOTE SP and FP remain predefined by MACRO-64 whether or not you use the OpenVMS Calling Standard macros. $SP and $FP are defined by the OpenVMS Calling Standard macros for consistency with the other register definitions that correspond to OpenVMS Calling Standard register conventions. The following symbols are defined by the $ROUTINE macro. These symbols are useful while programming with the calling-standard macros to refer to particular data and linkage section items. o $CS-The address of the beginning of the current routine's code section. o $LS-The address of the beginning of the current routine's linkage section. o $DS-The address of the beginning of the current routine's data section. o $DP-The linkage section address where the $ROUTINE macro places the .ADDRESS $DS to enable access to the data section from the linkage section (this variable is optional). o $SIZE-The size of the fixed-stack area in bytes. $SIZE is defined using the value specified with the SIZE argument. o $RSA_OFFSET-The offset within the fixed-stack area to the register save area. $RSA_OFFSET is defined using the value specified with the RSA_OFFSET argument. o $RSA_END-The offset within the fixed-stack area to the first byte beyond the end of the register save area. For more information, see the description for the $ROUTINE macro in this chapter. The $CALL macro also defines the $STACK_ARG_SIZE symbol. This symbol specifies the number of bytes used to store arguments on the stack. This value is useful after calling a routine that returns a value on the stack. In this case, $CALL cannot remove the arguments from the stack because you must first retrieve the returned value from the stack. Subsequently, you can remove the arguments from the stack using the $STACK_ARG_SIZE symbol. For more information, see the description of $CALL in this chapter.
2.3 – Defining Procedure Type
The OpenVMS Calling Standard defines four types of routines; stack, register, null, and bound. You can define the routine type by using the KIND keyword argument with $ROUTINE or $PROCEDURE_DESCRIPTOR macros. The validity and values of other $ROUTINE and $PROCEDURE_DESCRIPTOR macro parameters are determined by the type of routine being declared. For example, a null procedure type has no stack size; therefore, the SIZE parameter is invalid and cannot be specified for a null procedure type. When using the KIND keyword with the $ROUTINE or $PROCEDURE_DESCRIPTOR macros, note the following exceptions: o The $SIZE symbol defined by $ROUTINE is only valid for stack and register routines. o The $RSA_OFFSET symbol defined by $ROUTINE is only valid for a stack routine.
2.4 – Using Macros in Prologue Sections
With stack and register routines, $ROUTINE generates a standard prologue sequence if you specify the STANDARD_PROLOGUE=TRUE keyword argument. STANDARD_PROLOGUE=TRUE is the default for register and stack routines. Alternatively, you can code your own prologue sequence by specifying the STANDARD_PROLOGUE argument as FALSE and using the $END_PROLOGUE macro to mark the end of your prologue sequence. In this case, you may wish to use the $SIZE and $RSA_OFFSET symbols to symbolically specify the fixed-stack size and register save area offset, respectively. For more information on the prologue sequence of instructions that must occur at the beginning of all stack and register routines, see the OpenVMS Calling Standard.
2.5 – Using Macros in Epilogue Sections
With stack and register routines, you can use the $RETURN macro to generate an epilogue sequence. Alternatively, you can code your own epilogue sequence using the $BEGIN_EPILOGUE and $END_EPILOGUE macros to mark the beginning and end of your epilogue sequences. The OpenVMS Calling Standard also describes the epilogue sequence of instructions that must be executed every time a stack or register routine returns to its caller.
3 – Programming Examples Using Supplied Macros
Examples Program Using Supplied Macros and Program Using $CALL show how to use the calling-standard macros to define a routine, switch control between psects, generate an epilogue sequence, and end the routine. Example 3 Program Using Supplied Macros $ROUTINE MAIN, KIND=STACK, - ; Stack routine kind 1 SAVED_REGS=<FP>, - ; Saves FP 2 SIZE=48 ; Stack size is 48 3 $LINKAGE_SECTION ; Switch to the linkage psect. 4 X: .long 6 ; X is a constant FP1_ADDR: ; FP1_ADDR -> FP1 .address FP1 $DATA_SECTION ; Switch to the data section 5 A:: .blkw 5 ; $DS points here B:: .blkw $CODE_SECTION ; Switch to the code section 6 ; ($CS points here) . . . $RETURN ; Perform epilogue and return 7 $END_ROUTINE MAIN ; Mark the end of the routine 8 1 $ROUTINE defines the routine MAIN. The routine type is defined as a stack routine using the KIND=STACK keyword argument. 2 The keyword argument SAVED_REGS=<FP> adds the frame pointer register to the list of registers saved on the stack by the prologue code. The SAVED_REGS keyword is valid only for stack procedures. If you do not specify the FP register (R29) with this argument, it is assumed. 3 The keyword argument SIZE=48 defines the stack area in bytes. This argument is valid only for register and stack routines. If you do not specify a stack size for a stack or register routine, $ROUTINE computes the minimum stack size required to accommodate the other arguments you specify or leave as the default. 4 The $LINKAGE_SECTION macro switches to the linkage section. You can use the $LS symbol created by the $ROUTINE macro to point to the address of the current routine's linkage section. $ROUTINE creates the procedure descriptor and leaves the current location counter within the linkage section just beyond the procedure descriptor. 5 The $DATA_SECTION macro switches to the data section. You can use the $DS symbol created by the $ROUTINE macro to point to the address of the current routine's data section. 6 The $CODE_SECTION macro switches to the code section. The $CS symbol created by the $ROUTINE macro is used to point to the address of the current routine's code section. 7 The $RETURN macro generates a standard epilogue instruction sequence. You can use this macro only with stack or register routine defined with the $ROUTINE macro. 8 The $END_ROUTINE macro marks the end of the routine.
4 – Using the $CALL Macro
$CALL calls local or external routines previously defined by the $ROUTINE macro or defined in another language. To call a routine using standard linkage, use the $CALL macro. You invoke this macro from within the routine's code section. $CALL performs the following actions: o Searches a list of linkage pairs referenced in previous invocations of the $CALL and $LINKAGE_PAIR macros within the calling routine. If a linkage pair is already found to exist on the list, $CALL uses the linkage pair stored from the previous invocation. Otherwise, $CALL stores the linkage pair of the called routine in the caller's linkage section and adds the linkage pair to the caller's list. o Allocates stack space for arguments, if necessary. o Loads arguments specified with the ARGS argument into argument registers and onto the stack, as appropriate. o Sets the arguments information register, R25, according to the arguments specified with ARGS argument. o Generates the following instruction sequence to perform the actual call based on the location of the linkage pair generated from above, and the value of Rls, linkage register, which is assumed to point to the base of the linkage section: LDQ R26, code_addr_offset(Rls) ; load code address LDQ R27, proc_desc_addr_offset(Rls) ; load procedure ; descriptor address ; JSR R26, R26 ; Jump to the routine ; saving the return ; address in R26 o Frees argument stack space, if any, and if the called routine does not return a value on the stack. Like $ROUTINE, the $CALL macro invokes other macros to perform the previous tasks. If you do not specify the Rls argument in your invocation of $CALL, $CALL assumes that you have used the .BASE directive to define a register that points to the base address of your linkage section. That is, it assumes that you have included a statement similar to the following: .BASE R27, $LS This source statement defines the base address of the linkage section to be R27, and to be associated with the macro symbol $LS. This source statement should be placed in your source code before the $CALL macro call.
4.1 – Using $CALL in Source Code
This example uses the same source code from the previous example, except it uses the $CALL macro to show how to call a local and external routine. Example 4 Program Using $CALL . . . $CODE_SECTION ; Switch to the code section ; ($CS points here) . . . MOV R27,R2 1 .base R2, $LS 2 . . . $CALL SUB1 ; Call external routine SUB1 3 $CALL SUB2, LOCAL=TRUE ; Call local routine SUB2 4 . . . $RETURN ; Perform epilogue and return $END_ROUTINE MAIN ; Mark the end of the routine 1 The $LS symbol is defined to be the address of the procedure that is defined within the linkage section. The calling routine places the address of the procedure descriptor in R27 before making the call. This guarantees that the address associated with the symbol $LS is stored in R27 upon routine entry. Since the information in R27 is erased during a standard call, a copy is preserved in register R2. 2 Register R2 now contains the address of our procedure descriptor, which is the base address of our linkage section. Since $LS is defined to point to the base address of the linkage section, the assembler computes the offsets within the linkage section using the .BASE directive. 3 The $CALL macro calls the external routine SUB1. 4 The $CALL macro calls the local routine SUB2. This call uses the LOCAL=TRUE keyword argument to indicate that routine SUB2 is defined within the module.
5 – Programming Considerations
This section discusses some programming considerations you need to be aware of when using the calling-standard macros.
5.1 – Making Multiple Calls From the Same Routine
The $CALL macro generates the following instruction sequence: LDQ R26, code_address_offset(Rls) ; load code address LDQ R27, procedure_descriptor_address_offset(Rls) ; load procedure ; descriptor ; address JSR R26, R26 ; The contents of R26 and R27 are erased as a result of using the $CALL macro. This is important since Rls in the previous sequence is typically R27. Thus, if you require subsequent access to your linkage section, such as when making subsequent calls, you need to make a working copy of R27 to use after the first call. Note that $CALL also overwrites the values in the argument registers, and the scratch registers specified or the default set by the SCRATCH_REGS argument, when you pass arguments to the called routine.
5.2 – Nonstandard Linkage
Under certain circumstances, there may be advantages in using a nonstandard routine linkage.
5.3 – Routine Restrictions
Different routine types have different capabilities and restrictions. For example, only a stack routine that specifies BASE_REG_IS_FP=TRUE can make standard calls.
5.4 – Syntax Rules
You can use either positional or keyword argument association or a combination of the two with these macros. For positional association, the order of formal arguments is shown with the format of each macro. The following syntax rules apply when invoking the assembler using the command-line qualifier /NAMES=AS_IS: o When specifying macro names, you must use all uppercase or all lowercase characters. You cannot mix uppercase and lowercase characters. o When specifying keyword arguments, you must use the same alphabetic case as the macro name it is associated with. If you use lowercase characters with the macro name, you must use lowercase characters with the keyword argument. If you use uppercase characters with the macro name, you must use uppercase characters with the keyword argument.
6 – $BEGIN EPILOGUE
Marks the beginning of an epilogue instruction sequence. Format $BEGIN_EPILOGUE
6.1 – Description
$BEGIN_EPILOGUE marks the beginning of an epilogue instruction sequence that you code within a stack or register routine defined with the $ROUTINE macro. At each point where a stack or register routine returns to its caller, the routine must perform a sequence of operations to restore any saved registers and to perform stack frame management. This sequence is called the epilogue and is described in detail in the OpenVMS Calling Standard. You can use the $RETURN macro to generate a standard epilogue instruction sequence for you, or you can code your own sequence. If you code your own epilogue sequence, you must mark the beginning and end of the epilogue sequence with the $BEGIN_ EPILOGUE and $END_EPILOGUE macros.
6.2 – Notes
o You must not use $BEGIN_EPILOGUE for an epilogue instruction sequence generated by $RETURN. $RETURN automatically invokes $BEGIN_EPILOGUE and $END_EPILOGUE.
6.3 – Example
$ROUTINE MUMBLE, KIND=REGISTER, SAVE_FP=R1 : : : $BEGIN_EPILOGUE MOV R1,FP ; Restore caller's frame RET (R26) ; Return to caller $END_EPILOGUE : : : $END_ROUTINE MUMBLE
7 – $CALL
Issues a call to another routine. Format $CALL NAME=routine-being-called - [Rls=linkage-section-register] - [LS=linkage-section-address] - [LOCAL=boolean] - [ARGS=argument-list] - [SET_ARG_INFO=boolean-value] - [STACK_RETURN_VALUE=boolean-value] - [SCRATCH_REGS=scratch_reg-list] - [TIE=boolean-value] - [FUNC_RETURN= {I64,D64,I32,U32,FF,FD,FG,FS,FT,FDC,FGC,FSC,FTC}] - [USES_VAX_ARGLIST=boolean-value] - [SIGNATURE_BLOCK=signature_address] - [NONSTANDARD=boolean-value] -
7.1 – Parameters
NAME The name of the routine to call. This argument is required. Rls Linkage section register to use when generating the LDQ, LDQ, JSR instruction sequence. This argument is optional. If Rls is omitted, $CALL assumes that you entered a .BASE directive before invoking $CALL that establishes the value of a base register pointing into the linkage section. If you omit the Rls argument and you do not enter such a .BASE directive before invoking $CALL, the assembler issues the following error message during the $CALL macro expansion: "Argument 2 invalid" The assembler failed to find a base register specified with a previous .BASE directive to form a register expression of the form offset(Rn)" LS LS is the address of the linkage section. If you use $CALL within a routine defined by the $ROUTINE macro, the LS argument defaults to the $LS symbol defined by $ROUTINE. If you use $CALL outside of a routine defined by the $ROUTINE macro, there are two ways that you can indicate the location of the linkage section to $CALL. First, you can specify the LS argument to $CALL as a relocatable address expression that indicates the base of the linkage section. In this case you must also specify the Rls argument. Second, you can specify both the linkage-section base register and the linkage-section address in a .BASE directive before invoking $CALL. In this case, you must omit both the Rls and LS arguments to $CALL. Digital recommends that you omit this argument if you use $CALL within a routine defined by the $ROUTINE macro. LOCAL A Boolean value (TRUE or FALSE) that specifies whether the routine to be called is local to the module or globally visible. By default, $CALL generates a call to a globally visible routine. To generate a call to a routine that is not globally visible, you must specify LOCAL=TRUE. ARGS An optional list of arguments to pass to the called routine. Enclose the argument list within angle brackets (<>) and separate the arguments with commas (,). You can use the following qualifiers with each argument you specify with the ARGS argument. These qualifiers are described in the following table. Each argument is an address expression (which may include a register) followed by a qualifier. The table also contains the argument type, the instruction used to load the argument into a register, the instruction used to store the argument on the stack, and the encodings used in the Argument Information Register (R25) in the call signature block when you specify TIE=TRUE. See the OpenVMS Calling Standard for more information on these encodings. Note that arguments are only stored on the stack if there are more than six arguments provided to the routine. ARGS Arguments _________________________________________________________________________ Argument Argument LOAD STORE AI Reg Arg Mem Arg Qualifier Type Instruction Instruction Encoding Signature Signature _________________________________________________________________________
7.1.1 /A Address LDA STQ I64 I32 I32
7.1.2 /D D-floating LDG STG FD FD Q
7.1.3 /F F-floating LDF STF FF FF I32
7.1.4 /G G-floating LDG STG FG FG Q
7.1.5 /L Longword LDL STQ I64 I32 I32
7.1.6 /Q Quadword LDQ STQ I64 Q Q
7.1.7 /S S-floating LDS STS FS FS I32
7.1.8 /T T-floating LDT STT FT FT Q
7.1.9 /UL(1) Unsigned LDL STQ I64 U32 I32
Longword /ZAP #^xF0 _______________________________________________________________________ (1)--Unsigned 32-bit integers are normally passed using the /L argument qualifier. Therefore, Digital does not recommend that you use the /UL argument qualifier. _______________________________________________________________________ SET_ARG_INFO An optional argument to indicate whether $CALL should set the Argument Information (AI) register (R25) with the appropriate argument information or not. By default, or if you specify SET_ARG_INFO=TRUE, $CALL stores the appropriate argument information in R25. If you specify SET_ARG_INFO=FALSE, $CALL does not affect R25. If you want to conform to the OpenVMS Calling Standard, you must store the appropriate information in R25 yourself before invoking $CALL. If you do not need to conform to the OpenVMS Calling Standard, and if the called routine does not need argument information in R25, you can specify SET_ARG_INFO=FALSE and make no change in R25. By making no change in R25, you avoid the overhead involved when either you or $CALL load argument information into R25 at the expense of calling standard conformance. STACK_RETURN_VALUE An optional argument to indicate that the called routine returns a value on the stack. By default, $CALL assumes that the called routine does not return a value on the stack. In this case, $CALL removes any arguments passed to the called routine from the stack when the called routine returns. If the called routine returns a value on the stack, the returned value is placed at a lower address than the arguments on the stack. In this case, you must specify STACK_RETURN_VALUE=TRUE to prevent $CALL from removing the arguments to the called routine from the stack and erasing the value returned by the called routine. You must retrieve the return value and remove it from the stack. Then you can remove the arguments to the called routine using the $STACK_ARG_SIZE symbol defined by $CALL. SCRATCH_REGS An optional list of scratch registers for $CALL to use when processing arguments passed to the called routine with the ARGS argument. If you pass more than six arguments to the called routine, $CALL may need to use scratch registers to process the call. By default, $CALL uses R0, R1, F0, and F1. You can cause $CALL to use different scratch registers with the SCRATCH_REGS argument. If you are passing integer arguments, you should specify at least one integer register. If you are passing floating-point arguments, you should specify at least one floating-point register. $CALL can process arguments to the called routine more efficiently if you specify two or more scratch registers of the type or types appropriate to the arguments you are passsing. TIE A Boolean value (TRUE or FALSE) that specifies whether $CALL should generate a call sequence that is compatible with both native routines and the Translated Image Environment (TIE). By default, $CALL generates a faster call sequence that is only compatible with native routines. If you specify TIE=TRUE, $CALL generates a call sequence that works with both native routines and translated routines. If you are calling a VAX routine in a shareable image that has been translated with the DECmigrate image translator, specify TIE=TRUE. If you are calling a native routine, Digital recommends you default the TIE argument or specify TIE=FALSE. While $CALL generates a call sequence that is compatible with native routines when you specify TIE=TRUE, that call sequence is slower than when you specify or default TIE=FALSE. FUNC_RETURN An optional argument used to indicate the type of function return when you also specify TIE=TRUE. This argument is ignored unless you also specify TIE=TRUE. Specify one of I64, D64, I32, U32, FF, FD, FG, FS, FT, FFC, FDC, FGC, FSC, or FTC. These values correspond to the RASE$K_FR_* signature encodings described in Table 3-7 in the OpenVMS Calling Standard. If you specify TIE=TRUE and do not specify a function return type with FUNC_ RETURN, the default function return type is I64. NOTE Specification of the FUNC_RETURN argument does not in itself cause $ROUTINE to generate a procedure signature block. However, if you specify either or both the ARGLIST or USES_ VAX_ARGLIST arguments, any value you specify with the FUNC_ RETURN argument is recorded in both the procedure descriptor and the procedure signature block. USES_VAX_ARGLIST An optional argument to indicate whether the called routine uses a VAX argument list. This argument is ignored unless you also specify TIE=TRUE. By default, $CALL assumes the called routine does not use a VAX argument list. Specify USES_VAX_ARGLIST=TRUE to indicate that the called routine uses a VAX argument list. SIGNATURE_BLOCK An optional argument that you can use to supply the address of the call signature block. This argument is ignored unless you also specify TIE=TRUE. Note that you cannot specify a SIGNATURE_ BLOCK argument in combination with either of the FUNC_RETURN or USES_VAX_ARGLIST arguments. By default, $CALL generates a call signature block for you when you specify TIE=TRUE, and you can in part control the contents of that signature block with the FUNC_RETURN and USES_VAX_ARGLIST arguments. If you wish to define your own call signature block, do not specify either of the FUNC_RETURN or USES_VAX_ARGLIST arguments and supply the address of your call signature block with the SIGNATURE_BLOCK argument. NONSTANDARD A Boolean value (TRUE or FALSE) that specifies whether $CALL should suppress warning and informational messages concerning nonstandard usage. By default, $CALL issues warning and informational messages to indicate you are using $CALL in a way that violates the OpenVMS Calling Standard or in a way that requires special programming considerations. Specify NONSTANDARD=TRUE if you wish to suppress these messages.
7.2 – Description
$CALL issues a call to another routine and performs the following actions: 1. Searches a list of linkage pairs referenced in previous invocations of the $CALL and $LINKAGE_PAIR macros. If a linkage pair is already in the list, $CALL uses the linkage pair from the previous invocation. Otherwise, $CALL stores the linkage pair of the called routine in the caller's linkage section and adds the linkage pair to the caller's list. If you use $CALL within a routine defined with the $ROUTINE macro, $CALL and $LINKAGE_PAIR reset the list of linkage pairs for each routine. 2. Allocates stack space for arguments if necessary. 3. Generates instructions to load the arguments to the called routine. 4. Sets the value in the argument information register, R25. 5. Generates the following instruction sequence to perform the actual call based on the location of the linkage pair generated from step 1 and the address specified or defaulted with the LS argument. The register specified with the Rls argument is assumed to point to the base of the linkage section as shown in the following example: LDQ R26, code_address_offset(Rls) ; load code address LDQ R27, procedure_descriptor_address_offset(Rls) ; load ; procedure ; descriptor ; address JSR R26, R26 6. Frees argument stack space, if any, and if the called routine does not return a value on the stack.
7.3 – Examples
Example 1 $CALL SUB1, Rls=R13, LS=MY_LINKAGE_SECTION .BASE R13, MY_LINKAGE_SECTION $CALL SUB2 $ROUTINE SUB3, KIND=STACK, SAVED_REGS=<R2,FP> $LINKAGE_SECTION .QUAD 1 XX: $CODE_SECTION MOV R27, R2 $CALL SUB4, R2 .BASE R2, $LS $CALL SUB5 $CALL SUB6, - ARGS=<XX/A, R0/Q>, - SCRATCH_REGS=<R22,R23> $CALL SUB7, - ARGS=<1/A,2/A,3/A> $RETURN $END_ROUTINE SUB3 Example 2 $CALL FOO, ARGS=<A,B,C,D,E,F,G,H>, STACK_RETURN_VALUE=TRUE ; Fetch octaword return value from stack LDQ R4, 0(SP) ; low quadword LDQ R5, 8(SP) ; high quadword LDA SP, $STACK_ARG_SIZE+16(SP) ; RESET STACK
8 – $CODE SECTION
Switches control to the current routine's code section psect. Format $CODE_SECTION
8.1 – Description
$CODE_SECTION switches control to the current routine's code section psect.
8.2 – Example
$CODE_SECTION
9 – $DATA SECTION
Switches control to the current routine's data section psect. Format $DATA_SECTION
9.1 – Description
$DATA_SECTION switches control to the current routine's data section psect.
9.2 – Example
$DATA_SECTION
10 – $END EPILOGUE
Marks the end of an epilogue instruction sequence. Format $END_EPILOGUE
10.1 – Description
You can use the $END_EPILOGUE macro to mark the end of an epilogue instruction sequence that you code yourself within a stack or register routine defined with the $ROUTINE macro. At each point where a STACK or REGISTER routine returns to its caller, the routine must perform a sequence of operations to restore any saved registers and to perform stack-frame management. This sequence is called the epilogue and is described in detail in the OpenVMS Calling Standard. You can use the $RETURN macro to generate a standard epilogue instruction sequence for you. Alternatively, you can code your own sequence. If you code your own epilogue sequence, you must mark the beginning and end of the epilogue sequence with the $BEGIN_EPILOGUE and $END_EPILOGUE macros, respectively. Note that you must not use $END_EPILOGUE for an epilogue instruction sequence generated by $RETURN. $RETURN invokes $BEGIN_EPILOGUE and $END_EPILOGUE for you. You may omit the invocation of $END_EPILOGUE if your epilogue sequence occurs at the end of the routine. The $END_ROUTINE macro invokes $END_EPILOGUE for you if you invoke the $BEGIN_EPILOGUE macro without a matching invocation of the $END_EPILOGUE macro. You must invoke $END_EPILOGUE with epilogue sequences that occur in the middle of your routine.
10.2 – Example
$ROUTINE MUMBLE, KIND=REGISTER, SAVE_FP=R1 : : : $BEGIN_EPILOGUE MOV R1,FP ; Restore caller's frame RET (R26) ; Return to caller $END_EPILOGUE : : : $END_ROUTINE MUMBLE
11 – $END PROLOGUE
Marks the end of a prologue instruction sequence. Format $END_PROLOGUE
11.1 – Description
$END_PROLOGUE marks the end of a routine prologue instruction sequence that you code yourself. The prologue instruction sequence begins with the first instruction of the routine. There can only be one prologue instruction sequence in a routine. The prologue is described in detail in the OpenVMS Calling Standard. You invoke $END_PROLOGUE after the last instruction in the routine prologue code. The last instruction in the routine prologue is the one that updates FP (R29, the frame pointer) and makes the frame become current. You must use this macro when the routine type is stack or register and you specify STANDARD_PROLOGUE=FALSE to the $ROUTINE macro.
11.2 – Notes
o Do not use this macro when the $ROUTINE macro generates a standard prologue or when the routine type is null or bound. For example, a standard prologue is generated for you when you specify or leave the default of $ROUTINE's STANDARD_PROLOGUE argument to TRUE.
11.3 – Example
MOV SP, FP $END_PROLOGUE
12 – $END ROUTINE
Marks the end of a routine. Format $END_ROUTINE [name=routine-name]
12.1 – Parameter
name The name of the routine that is ended. This argument is optional. If you specify a name, $END_ROUTINE verifies that the name matches that which was specified with $ROUTINE to begin the routine. If the name does not match, $END_ROUTINE issues a diagnostic message. There is no default. If you omit the name, $END_ROUTINE does not verify a matching name.
12.2 – Description
You must use this macro at the end of a routine that is defined with the $ROUTINE macro to delimit the end the current routine and to perform final macro processing of the routine.
12.3 – Example
$END_ROUTINE NAME=FOOZLE
13 – $LINKAGE PAIR
Locates or defines a linkage pair in the linkage psect. Format $LINKAGE_PAIR name=routine-name, local=boolean
13.1 – Parameters
name Name of the linkage pair to define. This argument is required. local A Boolean value (TRUE or FALSE) that specifies whether the routine is defined within the module for not. The default is to store a linkage pair for a global routine. You must specify LOCAL=TRUE to store a linkage pair for a routine that is not globally visible.
13.2 – Description
You can invoke this macro to locate or define a linkage pair in the linkage psect. The linkage pair is added to a list for later use and retrieval by the $CALL and $LINKAGE_PAIR macros. Thus, only the first invocation of $LINKAGE_PAIR (or $CALL) for a given routine to be called results in a linkage pair being stored. $LINKAGE_PAIR and $CALL use the same list of linkage pairs. $LINKAGE_PAIR restores the current psect when it is done. $LINKAGE_PAIR defines the symbol $LP. This symbol value is the address within the linkage section of the linkage pair for the specified routine to call.
13.3 – Notes
o Because the $CALL macro invokes the $LINKAGE_PAIR macro for you, you do not need to use $LINKAGE_PAIR when you are using $CALL. You may wish to use $LINKAGE_PAIR when you are not using $CALL or when you require a specific ordering or placement of linkage pairs within the linkage section.
13.4 – Example
$LINKAGE_PAIR SUB1 ; define linkage pair in linkage section LDQ R26, $LP LDQ R27, $LP+8 JSR R26, R26
14 – $LINKAGE SECTION
$LINKAGE_SECTION switches control to the current routine's linkage section psect. Format $LINKAGE_SECTION
14.1 – Description
$LINKAGE_SECTION switches control to the current routine's linkage section psect.
14.2 – Example
$LINKAGE_SECTION
15 – $OPDEF
Used to define opcodes. Format $OPDEF MNEMONIC, FORMAT, ENCODING [,DEFAULTS]
15.1 – Parameters
MNEMONIC MNEMONIC is the mnemonic name by which the instruction is called. You may optionally specify a qualifier list separated from the name by a slash (/). A qualifier list is a sequence of one or more letters or digits with no intervening spaces or separators. FORMAT FORMAT is one of the following arguments: Format Description MEMORY Standard memory format instructions. MEMORY_FUNCTION Memory format instructions with a function code. JUMP Memory format instructions formatted like jump instructions. BRANCH Standard branch format instructions. OPERATE Standard operate instructions. FLOATING_OPERATE Standard floating-point operate instructions. PAL Standard PALcode instructions. <CUSTOM=operand_type_list> Custom format. With the CUSTOM format, you may optionally specify a list of the types of operands the instruction is to accept. If you specify a list of operand types, you must enclose the entire FORMAT argument within angle brackets, and you must specify the operand types in the order they are to be used with the instruction. $OPDEF supports the following operand types: IREGISTER Integer register, such as R5 or SP. FREGISTER Floating-point register, such as F7. LITERAL Integer literal, such as #123 or 32767. LIT_IREG Integer literal, such as #123 or 32767, or integer register, such as R5 or SP. INDIRECT Indirect integer register notation such as (R7). DISPLACEMENT Indirect integer register notation with an integer literal displacement, such as FOO(R12). BRANCH_OFFSET Label or address expression, such as L1. For example: FORMAT=<CUSTOM=IREGISTER,DISPLACEMENT> The following example shows the definition of the ADDQ instruction, which takes either an integer register or literal as its second argument: $OPDEF ADDQ, - FORMAT=<CUSTOM=IREGISTER,LIT_IREG,IREGISTER>, - ENCODING=<26:31=^x10, - 21:25=%OP1, - 12:20=%OP2, - 5:11=^x20, - 0:4=%OP3> For a detailed description of instruction formats, see the Alpha Architecture Reference Manual. ENCODING ENCODING is the numeric encoding for the instruction opcode. The default radix is decimal, as is the case for all assembler constants. Prefix the value with ^X for hexadecimal. Certain instruction formats allow multipart encoding: Format Encoding Description MEMORY_FUNCTION Specify the base opcode, followed by a dot, followed by the function code. For example: ENCODING=^X10.F000 JUMP Specify the base opcode, optionally followed by a dot, and the hardware-hint bits optionally followed by a dot and the software- hint bits. For example: ENCODING=^X1A.2.1 OPERATE Specify the base opcode, followed by a dot, followed by the function code. For example: ENCODING=^X12.3C FLOATING_OPERATE Specify the base opcode, followed by a dot and the function code. For example: ENCODING=^X17.02B PAL Specify the base opcode, optionally followed by a dot and the function code. Omit the function code for a generic PAL instruction that accepts an integer-expression argument. For example: ENCODING=^X0.0080 ENCODING=^X19 CUSTOM Specify a comma-separated list of bit ranges and values to place in those bit ranges. For example: ENCODING = < 26:31=^X14, 21:25=%OP1, - 16:20=%OP2.REG, 0:15=%OP2.DISP > For CUSTOM format instructions, specify the ENCODING argument as a comma-separated list of bit ranges and values to place in those bit ranges. Enclose the list within angle brackets. Specify a bit range as start:end where start and end are integer constant expressions. For a 1-bit bit range, start and end are equal. Bit positions range from 0 to 31. Place an equal sign (=) after the bit-range specifier followed by the value you wish to put in the bit range. You can place either a constant integer expression or an operand into the bit range. Start and end expressions and integer constant expressions must not reference any external symbols or symbols not yet defined in the assembly. $OPDEF evaluates these expressions at the time that it defines the instruction as opposed to when the defined instruction is referenced. Operand names are of the form %OPn, where n is the ordinal number of the operand as specified from left to right with the FORMAT argument. For the IREGISTER, FREGISTER, and INDIRECT operands, $OPDEF places the 5-bit register number into the bit positions you specify. For LITERAL operands, $OPDEF places the literal value of the operand into the bit positions you specify. Operand literal values can be up to 32 bits long. The most significant bits are truncated if the size of the operand literal value exceeds the bit range you specify. Forward and external references are allowed. For LIT_IREG operands, $OPDEF places either a literal value or a 5-bit register number into the bit positions you specify. If a literal, the low bit is 1, and the literal value is placed in the upper bits. If an integer register, the low four bits are 0, and the high five bits contain the register number. For DISPLACEMENT operands, $OPDEF defines two parts: a 5-bit register number and a displacement value that can be up to 32 bits long. The most significant bits are truncated from the displacement value if the size of the displacement value exceeds the bit range you specify. You can reference the register number by placing .REG after the operand name. For example: %OP2.REG. Similarly, you can reference the displacement value by placing .DISP after the operand name. For example: %OP2.DISP. Forward references are allowed. Relocatable expressions are not allowed. For BRANCH_OFFSET operands, $OPDEF stores the signed longword offset between the next instruction and the specified address in the bit positions you specify. The address expression specified for a BRANCH_OFFSET operand can be a backward or forward reference to a location within the current psect. It cannot be an external address or an address in a different psect. The resulting offset can be up to 32 bits in size. If the size of the offset exceeds the bit range you specify, the most significant bits are truncated. $OPDEF fills any bit positions you leave unspecified with zeros. DEFAULTS DEFAULTS is an optional list of operand defaults of the form <%OPn=value, ...>, where n is the number of the operand to which the value is to apply as a default. Operand defaults may be specified in any order. If you specify a default for one or more operands, you need not specify a default for all operands. The following example specifies a default of R31 for the first instruction argument: $OPDEF RET, FORMAT=<CUSTOM=IREGISTER,INDIRECT>, - ENCODING=<26:31=^x1A, - 21:25=%OP1, - 16:20:%OP2, - 14;14=^x2,0:13=0>, - DEFAULTS=<%OP1=R31>
15.2 – Description
You can use the $OPDEF macro to define your own opcodes. $OPDEF defines a macro using an unqualified version of the mnemonic name you specify. When this macro is invoked with the instruction qualifiers you specify when you define it with $OPDEF (if any), it expands to the instruction representation you have defined with $OPDEF. You can specify the qualifiers in any order as long as the combination of qualifiers you use is the same. Other uses of the mnemonic name remain valid provided you do not use the mnemonic name as a macro name in a .MACRO directive. For instance, you can use the same mnemonic name in the opcode field with different or no qualifiers. If the qualifiers (or absence thereof) do not match those specified in your $OPDEF instruction definition, the macro defined by $OPDEF processes as though you had not defined an instruction by that mnemonic name. To do so, it expands to a single statement. This expansion statement is identical to the mnemonic-name macro invocation statement, except it is processed in a context that prevents the mnemonic- name macro from expanding recursively. Instead, the statement is processed as a normal, MACRO-64 instruction statement. In this case, you may notice references to the mnemonic-name macro expansion in a MACAUXMSG diagnostic message if the instruction statement contains errors. For instance, if you define a STQ/P instruction using $OPDEF, you can still use the STQ instruction without the /P qualifier. If you do, and your STQ instruction statement contains an error, the assembler generates a MACAUXMSG message indicating that the error occurred during the expansion of macro STQ. Aside from the fact that the STQ instruction is processed in the context of the expansion of the STQ macro, $OPDEF's definition of the STQ/P instruction has no effect on your use of the STQ instruction.
15.3 – Example
$OPDEF MNEMONIC=BANG, FORMAT=PAL, - ENCODING=^X0.0099
16 – .PACKED
Packed decimal string storage macro. Format .PACKED decimal-string[,symbol]
16.1 – Parameters
decimal-string A decimal number from 0 to 31 digits long with an optional sign. Digits can be in the range 0 to 9. symbol An optional symbol that is assigned a value equivalent to the number of decimal digits in the string. The sign is not counted as a digit.
16.2 – Description
.PACKED generates packed decimal data with two digits per byte. Packed decimal data is useful in calculations requiring exact accuracy. It is operated on by the decimal string instructions. A packed decimal string is a contiguous sequence of bytes in memory. It is specified by two attributes: the address A of the first byte and a length L, which is the number of digits in the string and not the length of the string in bytes. The bytes of a packed decimal string are divided into two, 4-bit fields (nibbles). Each nibble except the low nibble (bits 3:0) of the last (highest-addressed) byte must contain a decimal digit. The low nibble of the highest-addressed byte must contain a sign. The representation for the digits and sign is indicated as follows: Digit or Sign Decimal Hexadecimal 0 0 0 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 7 7 7 8 8 8 9 9 9 + 10,12,14, or A,C,E, or F - 15 B or D 11 or 13 The preferred sign representation is 12 for plus (+) and 13 for minus (-). The length L is the number of digits in the packed decimal string (not counting the sign); L must be in the range 0 to 31. When the number of digits is odd, the digits and the sign fit into a string of bytes whose length is defined by the following equation: L/2(integer part only) + 1. When the number of digits is even, it is required that an extra 0 appear in the high nibble (bits 7:4) of the first byte of the string. Again, the length in bytes of the string is L/2 + 1. The address A of the string specifies the byte of the string containing the most-significant digit in its high nibble. Digits of decreasing significance are assigned to increasing byte addresses and from high nibble to low nibble within a byte. Thus, +123 has a length of 3. The packed decimal number -12 has a length of 2.
16.3 – Example
.PACKED -12,PACKED_SIZED ; PACKED_SIZE gets value of 2 .PACKED +500 .PACKED 0 .PACKED -0,SUM_SIZE ; SUM_SIZE gets value of 1
17 – $PROCEDURE DESCRIPTOR
Defines a procedure descriptor structure at the current psect and offset. Format $PROCEDURE_DESCRIPTOR
17.1 – Description
The arguments for the $PROCEDURE_DESCRIPTOR macro are the same as the $ROUTINE macro, with the following exceptions: o The ENTRY argument is required. o There are no CODE_SECTION, LINKAGE_SECTION, DATA_SECTION, DATA_SECTION_POINTER, or STANDARD_PROLOGUE arguments. o There is an additional END_PROLOGUE argument. This argument must be a label that you define at the end of the routine's prologue sequence. This argument is required for stack and register procedure types.
17.2 – Notes
o Because the $ROUTINE macro invokes the $PROCEDURE_DESCRIPTOR macro for you, you do not need to use the $PROCEDURE_DESCRIPTOR macro if you use $ROUTINE. You may wish to use $PROCEDURE_DESCRIPTOR when you are not using $ROUTINE.
17.3 – Example
$PROCEDURE_DESCRIPTOR p1, - KIND=NULL, - ENTRY=p1_entry
18 – $RESET LP LIST
Clears the list of linkage pairs maintained by the $LINKAGE_PAIR and $CALL macros. Format $RESET_LP_LIST
18.1 – Description
The $LINKAGE_PAIR and $CALL macros maintain an assembly-time list of linkage pairs that the $LINKAGE_PAIR macro has stored in the linkage section. This list enables $LINKAGE_PAIR and $CALL to use the same linkage pair for multiple routine calls to the same routine. You can clear this list of linkage pairs with the $RESET_LP_LIST macro. Under normal circumstances, you do not need to clear the linkage- pair list. Some of the times when you do are as follows: o When you change the psect assigned to the linkage section. o If distance from the linkage section of your current routine falls more than 32K bytes beyond where the linkage pair has been stored.
18.2 – Example
; Define the linkage section psect for routines A & B $LINK$ = "AB_LINK,NOEXE,OCTA" $ROUTINE A, KIND=STACK .BASE R27, $LS $CALL D ; Linkage pair is stored in A's linkage ; section and put on the assembly-time list $RETURN $END_ROUTINE A $ROUTINE B, KIND=STACK .BASE R27, $LS $CALL D ; Linkage pair is found on the list, ; and used from A's linkage section $RETURN $END_ROUTINE B ; Define a different linkage section for routine C $LINK$ = "C_LINK,NOEXE,OCTA" ; Linkage pairs that are on the list are in A & B's linkage ; section, which is not easily accessible by C. Therefore, ; clear the list. $RESET_LP_LIST $ROUTINE C, KIND=STACK .BASE R27, $LS $CALL D ; Linkage pair is stored in C's linkage ; section and put on the assembly-time list $RETURN $END_ROUTINE B
19 – $RETURN
Generates a standard epilogue instruction sequence. Format $RETURN
19.1 – Description
Generates a standard epilogue instruction sequence when used within a stack or register routine defined with the $ROUTINE macro. The epilogue sequence generated by $RETURN restores any registers you specify with the SAVED_REGS argument to $ROUTINE and performs stack frame management as necessary. You can use $RETURN whether or not you specify STANDARD_PROLOGUE as TRUE or accept the default. You can use $RETURN any number of times within a given stack or register routine to affect a return to the calling routine. You must not use the $BEGIN_EPILOGUE or $END_EPILOGUE macros for an epilogue sequence generated by $RETURN. $RETURN invokes $BEGIN_EPILOGUE and $END_EPILOGUE for you.
19.2 – Example
$ROUTINE FOOZLE, KIND=REGISTER, SAVE_FP=R1 : : : $RETURN $END_ROUTINE FOOZLE
20 – $ROUTINE
Defines the current routine and creates a context for the routine. Format $ROUTINE NAME=routine name - ALIASES=alias names - LOCAL=boolean value - STANDARD_PROLOGUE=boolean value - ENTRY=code entry point - CODE_SECTION=code section psect name - DATA_SECTION=data section psect name - DATA_SECTION_POINTER=boolean value - LINKAGE_SECTION=linkage section psect name - KIND=routine type- HANDLER_REINVOKABLE=boolean value - BASE_REG_IS_FP=boolean value- REI_RETURN=boolean value - STACK_RETURN_VALUE=boolean value - RSA_OFFSET=integer value - SAVE_FP=register name - SAVE_RA=return address register name - SIZE=numeric value - SAVED_REGS=list of registers - HANDLER=exception handler address - HANDLER_DATA=data address for exception handler - SYNCH_EXCEPTIONS=boolean value- PROC_VALUE=procedure value - ENVIRONMENT=environment value - FUNC_RETURN=function return type - ARGLIST=argument type list - USES_VAX_ARGLIST=boolean value - OVERRIDE_FLAGS=procedure descriptor flags - DEFAULT_SIGNATURE=boolean value - COMMON_BASE=list of registers - TARGET_INVO=boolean value - EXCEPTION_MODE=mode -
20.1 – Parameters
NAME The name of the routine. This argument is required for all procedure kinds. There is no default. For example: NAME=FOOZLE ALIASES List of alias names for the routine. This argument is optional for all procedure types. There is no default. For example: ALIASES=<FOO,BAR,FOOBAR,foo,bar,foobar,Foo,Bar,FooBar> LOCAL Boolean value indicating whether the routine is local (TRUE) or externally visible (FALSE). This argument is optional for all procedure kinds. The default is FALSE. For example: LOCAL=TRUE STANDARD_PROLOGUE Specifies a Boolean value to indicate whether $ROUTINE should generate a standard instruction prologue sequence at the beginning of the routine's code section. This argument is optional and valid only with REGISTER and STACK procedures. If the procedure type is stack or register, the default is TRUE and $ROUTINE generates a standard prologue sequence. The prologue sequence generated by $ROUTINE saves the registers you specify with the SAVED_REGS argument and performs stack-frame management as necessary. If you also specify BASE_REG_IS_FP=FALSE, the standard prologue sequence generated by $ROUTINE makes a copy of the procedure descriptor address that is in R27 upon entry into R29 (FP). While you cannot change the value in R29 before the epilogue, you can use R29 as a working, linkage-section register. If you specify the STANDARD_PROLOGUE argument as FALSE, you must code your own prologue sequence and mark the end of the prologue with the $END_ PROLOGUE macro. Whether or not you specify STANDARD_PROLOGUE as TRUE or accept the default, you can generate a standard epilogue sequence for stack and register procedures with the $RETURN macro. For example: STANDARD_PROLOGUE=FALSE ENTRY The name of the code-entry point. This argument is the code entry-point label that $ROUTINE defines for you at the beginning of the code section for the routine. If this argument is omitted, $ROUTINE generates a label. For example: ENTRY=FOOZLE_ENTRY CODE_SECTION The psect name and attributes of the code section. This argument is optional for all procedure kinds. If omitted, the default is the name and attributes defined by the $CODE$ lexical string symbol. If you specify a name and attributes for the CODE_SECTION argument, $ROUTINE redefines the $CODE$ lexical string symbol such that the specified values become the new default. Initially, $CODE$ is defined as follows: $CODE$ = "$CODE$,OCTA,PIC,CON,REL,LCL,SHR,EXE,NORD,NOWRT" Since you must delimit the psect name and attributes using commas, be sure to enclose this argument within angle brackets to avoid having the assembler interpret the name and attributes as different arguments to $ROUTINE. For example: CODE_SECTION=<MY_CODE,EXE,QUAD,NOWRT> DATA_SECTION The psect name and attributes of the data section. This argument is optional for all procedure kinds. If omitted, the default is the name and attributes defined by the $DATA$ lexical string symbol. If you specify a name and attributes for the DATA_SECTION argument, $ROUTINE redefines the $DATA$ lexical string symbol such that the specified values become the new default. Initially, $DATA$ is defined as follows: $DATA$ = "$DATA$,OCTA,NOPIC,CON,REL,LCL,NOSHR,NOEXE,RD,WRT" Since you must delimit the psect name and attributes using commas, be sure to enclose this argument within angle brackets to avoid having the assembler interpret the name and attributes as different arguments to $ROUTINE. For example: DATA_SECTION=<MY_DATA,NOEXE,QUAD,RD,WRT> DATA_SECTION_POINTER Boolean value indicating whether $ROUTINE should store a pointer to the data section in the linkage section and define $DP as the address of that pointer. This argument is optional for all procedure kinds. The default is FALSE. For example: DATA_SECTION_POINTER=TRUE You can use the DATA_SECTION_POINTER argument as follows: $ROUTINE TALLY_HO, DATA_SECTION_POINTER=TRUE $DATA_SECTION TALLY: .QUAD 0 $CODE_SECTION .BASe R27, $LS ; Inform assembler that R27->$LS LDQ R1, $DP ; R1->$DS .BASE R1,$DS ;Inform assembler that R1-$DS LDQ R0, TALLY ; R0<-TALLY LDA R0, 1(R0) ; R0<-R0++ STQ R0, TALLY ; TALLY<-R0 RET (R26) ; Return $END_ROUTINE TALLY_HO In this example, the DATA_SECTION_POINTER argument is specified in order to obtain linkage to the data section. The first LDQ instruction loads R1 with the pointer to the data section that $ROUTINE stores in the linkage section. The next three instructions increment the value in the TALLY variable in the data section. Finally, the routine returns the incremented value to its caller in R0. LINKAGE_SECTION The psect name and attributes of the linkage section. This argument is optional for all procedure kinds. If omitted, the default is the name and attributes defined by the $LINK$ lexical string symbol. If you specify a name and attributes for the LINKAGE_SECTION argument, $ROUTINE redefines the $LINK$ lexical string symbol such that the specified values become the new default. Initially, $LINK$ is defined as follows: $LINK$ = "$LINK$,OCTA,NOPIC,CON,REL,LCL,NOSHR,NOEXE,RD,NOWRT" Since you must delimit the psect name and attributes using commas, be sure to enclose this argument within angle brackets to avoid having the assembler interpret the name and attributes as different arguments to $ROUTINE. For example: LINKAGE_SECTION=<MY_LINK,NOEXE,QUAD,RD,NOWRT> KIND Specifies the kind of routine being defined. This must be one of the following: STACK, REGISTER, NULL, or BOUND. This is an optional argument. The default is NULL. For example: KIND=STACK HANDLER_REINVOKABLE Specifies a Boolean value to indicate whether the condition handler can be re-invoked. This argument is optional and valid only with STACK and REGISTER procedures. It defaults to FALSE if no value is specified and the procedure kind is STACK or REGISTER. Note that this argument is only valid if a value is also specified for the HANDLER argument. For example: HANDLER_REINVOKABLE=TRUE BASE_REG_IS_FP Specifies a Boolean value to indicate whether register R29 (FP) is used as the frame-pointer base register (TRUE) or not (FALSE). If specified as FALSE, R29 must be used to hold the address of the procedure descriptor (or the address of the address of the procedure descriptor-see the OpenVMS Calling Standard. You can use R29 to hold a working copy of the linkage- section address passed in R27. In addition, your prologue and epilogue instruction sequences can be shorter and more efficient. However, you cannot make standard calls to other routines if BASE_REG_IS_FP is specified as FALSE. This argument is optional and valid only with stack and register procedure kinds. It defaults to TRUE if the procedure type is stack or register. For example: BASE_REG_IS_FP=FALSE REI_RETURN Specifies a Boolean value to indicate whether this routine returns using an REI instruction. This argument is optional and valid only with STACK, REGISTER, and NULL procedure kinds. It defaults to FALSE if the procedure kind is STACK, REGISTER, or NULL. For example: REI_RETURN=TRUE STACK_RETURN_VALUE This argument is obsolete. Do not specify this argument. RSA_OFFSET An integer value specifying the stack offset (in bytes) of the register save area. This argument is optional and valid only for STACK procedures. If you specify BASE_REG_IS_FP as TRUE, the value you specify with RSA_OFFSET must be at least 8. RSA_ OFFSET defaults to 8 if BASE_REG_IS_FP is specified as TRUE, 0 otherwise. For example: RSA_OFFSET=32 SAVE_FP The register that contains a copy of the value of FP (R29) upon entry to this routine. The prologue instruction sequence must copy FP to the register specified by SAVE_FP and the epilogue instruction sequence(s) must restore FP from the register specified by SAVE_FP. This argument is required and only valid for REGISTER procedures. There is no default. For example: SAVE_FP=R1 SAVE_RA The register that contains the return address. This argument is optional and only valid for REGISTER procedures. If SAVE_RA is not R26, the prologue instruction sequence must copy R26 to the register specified by SAVE_RA and the epilogue instruction sequence(s) must use the return address stored in the register specified by SAVE_FP to affect its return to caller. SAVE_RA defaults to R26 if the procedure kind is REGISTER. For example: SAVE_RA=R22 SIZE A numeric value that must be a multiple of 16 specifying the size of the fixed-stack area in bytes. This parameter is valid only for REGISTER and STACK procedure kinds. It defaults to the minimum value possible given the other arguments you specify or default. $ROUTINE computes the amount of stack storage needed for the register save area (if any) and defines the $RSA_END symbol to be the offset of the first byte beyond the register save area. If you wish to allocate a fixed area of stack beyond the register save area, you can specify an expression with the SIZE argument that includes the term $RSA_END plus the amount of fixed-stack storage you need for your application. For example: SIZE=$RSA_END+32 SAVED_REGS A list of registers saved on the stack by the prologue code of this routine. It is valid only for STACK procedures and you must specify at least FP (R29) with this argument. It defaults to FP (R29) for STACK procedures. For example: SAVED_REGS=<R5,FP,F2,F3,F4> The OpenVMS Calling Standard specifies that registers R0, R1, R28, R30 (SP), and R31 must never be saved and restored. If you specify these registers with the SAVED_REGS argument, the $ROUTINE macro issues a diagnostic warning message. HANDLER The address of an exception handler. It is optional and valid only for STACK and REGISTER procedure kinds. By default, the procedure is defined not to have an exception handler. For example: HANDLER=MY_HANDLER HANDLER_DATA The address of data for the specified handler, if any. This argument is optional and valid only for stack and register procedure kinds and has no default value. You cannot specify a HANDLER_DATA argument if you do not specify the HANDLER argument. For example: HANDLER_DATA=MY_HANDLER_DATA SYNCH_EXCEPTIONS An argument to indicate whether exceptions must be synchronized or not. This argument is optional with STACK and REGISTER routines and is not allowed with other kinds of routines. This argument defaults to TRUE if you specify an exception handler with the HANDLER argument. Otherwise, it defaults to FALSE. When this argument is TRUE and you specify or accept the default STANDARD_PROLOGUE=TRUE, $ROUTINE generates a TRAPB instruction as part of the standard prologue sequence. In addition, when this argument is true, the $RETURN macro generates a TRAPB instruction as part of the standard epilogue sequence. When this argument is FALSE, neither $ROUTINE nor $RETURN generate TRAPB instructions. PROC_VALUE The procedure value of a bound procedure's parent. This argument is required for BOUND procedures and is invalid for all other procedure kinds. For example: PROC_VALUE=PARENT_PROC ENVIRONMENT Specifies an environment value. This parameter is optional and valid only for BOUND procedures. It has no default value. For example: ENVIRONMENT=0 FUNC_RETURN Specifies the function return type. This argument is optional and valid for all procedure kinds. If specified, it must be one of the following: I64, D64, I32, U32, FF, FD, FG, FS, FT, FFC, FDC, FGC, FSC, or FTC. These values correspond to those listed in Table 3-7 of the OpenVMS Calling Standard that have an additional "RASE$K_FR_" prefix. There is no default. For example: FUNC_RETURN=U32 ARGLIST Argument type list. This argument is optional and valid for all procedure kinds. If the argument list contains one or more elements, each of the first six elements must be one of the following: Q, I32, U32, FF, FD, FG, FS, or FT. The seventh and subsequent arguments (if any) must be either I32 or Q. These values correspond to the PSIG$K_RA_* and MASE$K_MA_* signature encodings in Table 3-6 of the OpenVMS Calling Standard. There is no default. If you specify this argument, $ROUTINE generates a procedure signature block. For example: ARGLIST=<Q,I32,FF,FF,U32>. USES_VAX_ARGLIST Specifies a Boolean value indicating whether the routine uses a VAX argument list. This argument is optional for all procedure kinds and defaults to FALSE. If you specify this argument, $ROUTINE generates a procedure signature block. For example: USES_VAX_ARGLIST=TRUE OVERRIDE_FLAGS Specifies overriding flags for the PDSC$W_FLAGS field in the procedure descriptor. This argument is optional and valid for all procedure kinds. However, it is required for BOUND procedures when the parameter specified with the PROC_VALUE argument is an external or forward reference. There is no default. For example: OVERRIDE_FLAGS=PARENT_FLAGS DEFAULT_SIGNATURE Specifies a Boolean value to indicate whether the standard procedure signature is used. TRUE means to use the standard signature. It is optional and valid for all procedure kinds. The default is FALSE if you specify either the ARGLIST or USES_ VAX_ARGLIST arguments. Otherwise, the default is TRUE. Note that this argument must be FALSE or blank if you specify either the ARGLIST or USES_VAX_ARGLIST arguments. For example: DEFAULT_SIGNATURE=TRUE COMMON_BASE An argument to specify one or more base registers that are used in common with other routines. This argument is optional for all routine kinds. By default, $ROUTINE invalidates any previous .BASE directives that may be in effect when you invoke $ROUTINE. In this way, you are prevented from inadvertently processing the second or subsequent routines in a module with .BASE directives in effect that apply only to a previous routine. However, you may wish to share a common base register assignment between a number of routines. To do so, you can reissue the appropriate .BASE directive or directives after each invocation of $ROUTINE. Alternatively, you can specify one or more common base registers with the COMMON_BASE argument, and enter the appropriate .BASE directive or directives only once at the beginning of the module. Specify the value for the COMMON_BASE argument as a list of integer registers. For example: COMMON_BASE=<R5,R13> In this example, $ROUTINE invalidates any previous .BASE directives except those for registers R5 and R13. Previous .BASE directives for registers R5 and R13 are unaffected. TARGET_INVO Specifies a Boolean value indicating whether or not the exception handler for this procedure is invoked when this procedure is the target of an invocation unwind. (TARGET_INVO=TRUE) causes the exception handler to be invoked during an unwind. The default is TARGET_INVO=FALSE. EXCEPTION_MODE An argument to specify one of the following exception modes with STACK and REGISTER procedures: o SIGNAL-raise all exceptions except underflow. o SIGNAL_ALL-raise all exceptions. o SILENT-raise no exceptions. o FULL_IEEE-only raise exceptions as per IEEE control bits. The default is EXCEPTION_MODE=SIGNAL.
20.2 – Description
$ROUTINE defines a routine, makes it the current routine, and performs the following actions: o Creates and associates a linkage section, code section, and data section with the routine. o Defines a procedure descriptor and optional signature block in accordance with the values of macro arguments. o Optionally stores a pointer to the data section within the linkage section. o Creates the following numeric and lexical symbols: Symbol Description $CS Address at start of the current routine's code section. $DS Address at start of the current routine's data section. $DP Optional address of a pointer to the current routine's data section. This symbol has a value that is an address in the current routine's linkage section at which the $ROUTINE macro has placed the address of the data section ($DS) as follows: $DP = . .ADDRESS $DS $DP enables you to access the data area of the current routine from its linkage section. $LS Address of the current routine's linkage section. $SIZE Size of fixed area of stack frame of the current routine. This symbol is valid only with STACK and REGISTER routines. $RSA_ The offset within the fixed-stack area to the OFFSET register save area. This symbol is valid only with STACK routines. $RSA_END The offset within the fixed-stack area to the the first byte beyond the end of the register save area (if any). $CODE$ A lexical string symbol that defines the routine's code psect name and attributes. $DATA$ A lexical symbol that defines the routine's data psect name and attributes. $LINK$ A lexical string symbol that defines the routine's linkage psect name and attributes. o Optionally generates a standard instruction prologue sequence at the beginning of the code section. If you specify /NAMES=AS_IS on the command line, all but the last three of these symbols are defined in both complete uppercase and complete lowercase. These symbols are intended for your use outside of the macros themselves. For example, the values of these numeric symbols may be useful as a mnemonic when coding an instruction with a register as in the following example: lda SP,-$SIZE(SP) The last three symbols, $CODE$, $DATA$, and $LINK$, are only defined in uppercase. They are used by the $ROUTINE macro for the default code, data, and linkage section psect names and attributes. You can define these symbols before invoking $ROUTINE to alter the default program sections as follows: - $CODE$ = "MY_CODE,EXE,OCTA,SHR,NORD,NOWRT,GBL" - $DATA$ = "MY_DATA,NOEXE,OCTA,NOSHR,RD,WRT,GBL" - $LINK$ = "MY_LINK,NOEXE,OCTA,SHR,RD,NOWRT,GBL" These statements cause $ROUTINE to use the previous psect names and attributes by default. If you specify any of the CODE_SECTION, DATA_SECTION, or LINKAGE_SECTION arguments in your invocation of $ROUTINE, $ROUTINE uses the psect name and attributes specified with the argument. In addition, $ROUTINE redefines the corresponding $CODE$, $DATA$, or $LINK$ lexical string symbol to the value you specify when you specify any of the CODE_SECTION, DATA_SECTION, or LINKAGE_SECTION arguments with $ROUTINE.
20.3 – Example
$ROUTINE MAIN1, KIND=NULL $ROUTINE MAIN1, - KIND=STACK, - SIZE=48, - SAVED_REGS=<R2,FP,F5>