External Subroutines
External subroutines are routines that are created and maintained separately from the program that will be calling them
Each routine should begin with:
rtnName CSECT
where rtnName is the label by which the subroutine will be called.
Pattern for a program with external subroutines
MAINPGM CSECT * * *** MAINPGM code, LTORG, and storage goes here * * SUBRTN1 CSECT * * *** SUBRTN1 code, LTORG, and storage goes here * * SUBRTN2 CSECT * * *** SUBRTN2 code, LTORG, and storage goes here * * END MAINPGM
Each new control section will automatically begin on a doubleword boundary
LTORG is included within each CSECT to ensure that the literals for each routine are assembled as part of that control section, rather than as a part of the first control section (in the above case MAINPGM).
To call an external subroutine, you must:
Step 2 is accomplished by using a V-type literal:
L R15,=V(SUBRTN)
Step 3 is accomplished by using the BALR instruction
Format: label BALR R1,R2
The BALR instruction works just like the BAL instruction. R1 is the address of the instruction immediately following the BALR instruction. R2 is the address of the routine being called
Standard Linkage Conventions
When control is passed to an external subroutine, register 15 should contain the address of the subroutine, register 14 should contain the address of the next instruction to execute, and register 13 should contain the address of an 18F savearea in the calling routine in which its initial register values will be saved.
Parameters are passed to an external subroutine through a parameter list. The address of the parameter list is contained in register 1
Return codes are passed back to a calling routine in register 15
Calculated values are passed back to a calling routine in register 0
The subroutine is responsible for storing the contents of the registers upon entry to the routine and restoring those values before returning control to the calling routine.
Standard Entry Linkage
The following code should be included as the first lines of each CSECT, including the MAIN one
rtnName CSECT STM R14,R12,12(R13) LR R12,R15 USING rtnName,R12 LA R14,name_of_18F_save_area_in_rtnName ST R13,4(,R14) ST R14,8(,R13) LR R13,R14
STM R14,R12,12(R13) saves all of the calling routine's registers, except for register 13, in the calling routine
LR R12,R15 puts the address of rtnName in register 12
USING rtnName,R12 sets register 12 as the base register for rtnName
LA R14,name_of_18F_save_area_in_rtnName points register 14 to an area in rtnName where its registers will be saved if rtnName calls another routine
ST R13,4(,R14) stores the address of the calling routine's save area in rtnName's save area. The value in register 13 is known as the backward pointer.
ST R14,8(,R13) stores the address of rtnName's save area in the calling routine's save area. The value in register 14 is known as the forward pointer.
LR R13,R14 points register 13 to rtnName's save area in case another routine is going to be called
Format of the 18F register save area
Unused |
Backword Pointer |
Forward Pointer |
Register 14 |
Register 15 |
Register 0 |
Register 1 |
Register 2 |
Register 3 |
Register 4 |
Register 5 |
Register 6 |
Register 7 |
Register 8 |
Register 9 |
Register 10 |
Register 11 |
Register 12 |
Standard Exit Linkage
The following code should be included as the last lines of executable code in each CSECT if no values are being passed back, including the MAIN one
L R13,4(,R13) LM R14,R12,12(R13) BR R14
L R13,4(,R13) loads the address of the calling routine's save area into register 13
LM R14,R12,12(R13) reloads all of the calling routine's registers, except for register 13
BR R14 returns control to the calling routine
Exit Linkage for a routine passing a return code back in register 15
All of the registers, except for 13 and 15, are going to be restored
L R13,4(,R13) L R14,12(,R13) LM R0,R12,20(R13) BR R14
L R13,4(,R13) loads the address of the calling routine's save area into register 13
L R14,12(,R13) restores the calling routine's register 14
LM R0,R12,20(R13) restores registers 0 through 12 of the calling routine
BR R14 returns control to the calling routine
Exit Linkage for a routine passing a calculated value back in register 0
All of the registers, except for 0 and 13, are going to be restored
L R13,4(,R13) LM R14,R15,12(R13) LM R1,R12,24(R13) BR R14
L R13,4(,R13) loads the address of the calling routine's save area into register 13
LM R14,R15,12(R13) restores the calling routine's register 14 and 15
LM R1,R12,24(R13) restores registers 1 through 12 of the calling routine
BR R14 returns control to the calling routine