In this example, a primary mode target program receives control from calling program that provided a 72-byte word-aligned save area pointed to by GPR 13. The calling program can make the call through the following two instructions:
L 15,=V(PGM)
BASR 14,15
The target program saves the calling program's registers into the save area that the calling program provides. It uses the GETMAIN macro to obtain storage for its own save area. The code is in 31-bit addressing mode and is reentrant.
PGM CSECT
PGM AMODE 31
PGM RMODE 31
SYSSTATE ARCHLVL=2
STM 14,12,SAVGRS14-SAVER(13)
* Save caller's registers in caller-
* provided R13 savearea
CNOP 0,4
BRAS 12,*+8
DC A(STATIC_DATA)
L 12,0(12,0) Set up to address of static data
USING STATIC_DATA,12
SRLG 0,0,32 Move high half of GPR 0 into low half of GPR 0
LR 2,0 Save high half of GPR 0 in low half of GPR 2
SRLG 1,1,32 Move high half of GPR 1 into low half of GPR 1
LR 3,1 Save high half of GPR 1 in low half of GPR 3
SRLG 15,15,32 Move high half of GPR 15 into low half of GPR 15
LR 4,15 Save high half of GPR 15 in low half of GPR 4
GETMAIN RU,LV=SAVF5SA_LEN Get my reentrant savearea
STG 13,SAVF5SAPREV-SAVF5SA(,1)
* Save caller's savearea address in my
* savearea (backward chain)
STMH 2,14,SAVF5SAG64HS2-SAVF5SA(1)
ST 2,SAVF5SAG64HS0-SAVF5SA(1)
ST 3,SAVF5SAG64HS1-SAVF5SA(1)
ST 4,SAVF5SAG64HS15-SAVF5SA(1)
MVC SAVF5SAID-SAVF5SA(4,1),=A(SAVF5SAID_VALUE)
* Set ID into savearea to indicate how
* caller's regs are saved
LGR 13,1 Put my savearea address in R13
* End of entry code. Begin program code here . . .
*
*
*
*
* Begin exit code
LGR 1,13 Copy my savearea address
LMH 2,14,SAVF5SAG64HS2-SAVF5SA(13)
* Restore high halves
LG 13,SAVF5SAPREV-SAVF5SA(,13)
* Restore caller's savearea address
FREEMAIN RU,A=(1),LV=SAVF5SA_LEN Free my reentrant savearea
SLR 15,15 Set return code of zero
L 14,SAVGRS14-SAVER(,13) Restore caller's R14
LM 2,12,SAVGRS2-SAVER(13) Restore caller's R2-R12
BR 14 Return to caller
*
STATIC_DATA DS 0D
* Begin static data here
* ...
*
IHASAVER
PGM CSECT
LTORG ,
END