Sidste gang lavede vi et reentrant program og så troede du måske, at det var alt, men det er det ikke. Det viser sig nemlig, at hvis man skal bruge nogle indbyggede funktioner, som f.eks. at kalde et andet program (LINK), så modificerer nogle af disse funktioner faktisk sig selv og dermed programmet, der bruger dem. Jeg vil gennemgå et eksempel med LINK.
I mit PGM1 laver jeg et LINK til PGM2. Jeg kalder det med en parameter. Læg mærke til de sidste tre instruktioner, som er parameterdefinitionen. Det er indlagt i selve programmet. Det forlanger LINK-macroen, for den genererer adressen på parmen i A(PARM+X’80000000’). Hvis ikke jeg havde PARM med eller det var en konstant i programmet, så kunne jeg godt have brugt denne standard LINK i et reentrant program.
STH R3,PARMLGD
***************************************
** FLYT VARIABEL LÆNGDE AF TEKST
***************************************
BCTR R3,0
EX R3,MVC
B MVC+L'MVC
MVC MVC PARMTXT(0),2(R2)
PGM2 LINK EP=PGM2,PARAM=PARM,VL=1
PGM2 DS 0H
CNOP 0,4
LA 1,IHB0011 LIST ADDRESS
B IHB0011A BYPASS LIST
IHB0011 EQU *
DC A(PARM+X'80000000')
IHB0011A EQU *
CNOP 0,4
BAL 15,*+20 BRANCH AROUND CONSTANTS
DC A(*+8) ADDR. OF PARM. LIST
DC A(0) DCB ADDRESS PARAMETER
DC CL8'PGM2' EP PARAMETER
SVC 6 ISSUE LINK SVC
B RETURN
PARM DS 0F
PARMLGD DS H
PARMTXT DS CL120
|
I stedet for at at bruge én standard LINK, skal du bruge to, - en LIST-form og en EXEC-form. LIST-formen beskriver konstanter og variable felter til LINK-kaldet. EXEC-formen udfører det faktiske LINK, akkurat som standard LINK. Det betyder, at du definerer din LIST-form sammen med dine andre konstanter og definerer et areal i dit Getmain’ede storage, hvor du kan flytte den op, inden du udfører EXEC-formen.
Macroparameteren MF=L fortæller, at du vil have lavet LIST-formen og MF=E, at du laver EXEC-formen. Læg mærke til, at i MF=E kommer navnet på feltet, hvor du flyttede LIST-formen til.
Det er måske lidt besværligt, men dit program bliver reentrant. Og det er smukt.
STORAGE DSECT
STORAGE_EYE_CATCHER DS CL16 EYE CATCHER
PARM DS 0F
PARMLGD DS H
PARMTXT DS CL120
STOR_LGD EQU *-STORAGE
PGM2_EXEC DS XL(PGM2_LGD)
|
STH R3,PARMLGD
******************************************
** FLYT VARIABEL LÆNGDE AF TEKST **
******************************************
BCTR R3,0
EX R3,MVC
B MVC+L'MVC
MVC MVC PARMTXT(0),2(R2)
******************************************
MVC PGM2_EXEC,PGM2_LIST
PGM2 LINK EP=PGM2,PARAM=PARM,VL=1,MF=(E,PGM2_EXEC)
PGM2 DS 0H
* 1ØL1D
* 1ØL1D
LA 1,PGM2_EXEC LOAD PARAMETER REG 1
LA 14,PARM PICKUP PARAMETER
ST 14,0(0,1) STORE INTO PARAM. LIST
OI 0(1),X'80' SET LAST WORD BIT ON ØG860P40
CNOP 0,4
BAL 15,*+20 BRANCH AROUND CONSTANTS
DC A(*+8) ADDR. OF PARM. LIST
DC A(0) DCB ADDRESS PARAMETER
DC CL8'PGM2' EP PARAMETER
SVC 6 ISSUE LINK SVC ØG381P2A
B RETURN
PGM2_LIST LINK EP=PGM2,SF=L
CNOP 0,4
PGM2_LIST DC A(*+8) ADDRESS OF EP PARAMETER
DC A(0) DCB ADDRESS PARAMETER
DC CL8'PGM2' EP PARAMETER
PGM2_LGD EQU *-PGM2_LIST
|
Jeg ved ikke om du har lagt mærke til det, men der er en lille krølle i mit program, som jeg var nødt til at bruge for at kunne flytte parameteren, som kan have variabel længde. Det er den lille EX-kommando. Den tager den højrestillede byte i registeret og lægge det i anden byte af instruktionen, som den peger på, - her MVC. Det er en slags modificeringen af koden, men det er i CPU’en og IKKE i programmet. Jeg kunne også have brugt MVCL (Move Long), men det ville være for kedeligt og besværligt.
Ingen kommentarer:
Send en kommentar