$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.
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.