I den seneste blog skrev jeg sidst i artiklen “Det er altså op til programmøren, at styre ændringerne i modulets kode eller værdier”. Jeg vil nu vise, hvordan det gøres. Vi skal opnå, at intet i programmet bliver ændret. Det betyder, at alle variable skal ligge i storage, som tilhører den enkelte process uden for programmet; vi skal altså lave en såkaldt Getmain, - altså hente main storage.
GETMAIN RC,LV=STOR_LGD
OR R1,R1
BZ NO_STORAGE_OBTAINED
LR R10,R1
USING STORAGE,R10
MVC EC,=CL(L’EC)’PGM2-STORAGE’
Et sted i programmet, uden for kontrolsektionen (CSECTen, den med instruktioner), lægger du en DSECT, der beskriver dit arbejdsareal.
STORAGE DSECT
EC DS CL16 EYE CATCHER
VALUE1 DS F
VALUE2 DS H
VALUE3 CL120
VALUE4 DS F
STOR_LGD EQU *-STORAGE
Du starter altså med at getmaine arealet med en længde, som er beregnet af sidste instruktion i DSECT’en. Derefter tjekker du, om der er en adresse i Register 1 (R1) med OR-instruktionen. Hvis ikke, så går du til fejlrutinen NO_STORAGE_OBTAINED. I næste instruktion flytter du adressen over i R10 og siger derefter, at når du refererer til felterne i dette storage, så skal R10 bruges. Til sidst flytter du en såkaldt Eye Catcher forrest i arealet. Det er rart, hvis programmet skulle dumpe sit storage. Så kan du lave en “Find” på Eye Catcheren, for at finde arealet.
DSECT’en beskriver udseenet af dit areal. Den starter med DSECT og navnet på denne DSECT, så du kan referere til den i USING. Derefter kommet dine variable og til sidst beregnes arealets længde. Så er vi kørende….
Eller, det vil sige, - det var den nemme del. Der kommer meget mere, men lige nu tager vi lige endnu en Getmain, som skal komme allerførst i programmet. Det skal bruges, hvis vi kalder andre programmer, så disse kan gemme vore registre (R14 til R12), så den kan genetablere dem inden den vender tilbage til os. I andre oprerativsystemer kalder man det at putte på stakken og hente fra stakken. I z/OS kaldes det, at overholde Linkage Conventions
Vi er jo imidlertid jo selv et program, der er kaldt, - måske af operativsystemet, måske af et andet program. Vi skal derfor gemme kalderens registre. Heldigvis findes der en Macro til det:
SAVE (14,12),,'PGM2 - &SYSDATE..&SYSTIME'
Det sidste er en kommentar, som fortæller programnavnet (PGM2) og programmets assembleringstidspunkt. Det skal ikke bare anbefales, men kræves, at du bruger det!. Det hjælper i uhyre mange tilfælde til at sikre, at vi har fat i den rigtige version af programmet i en fejlfindingssituation.
Efter at have gemt kalderens registre, skal vi have et storageareal til vore registre, hvis vi skulle finde på at kalde et andet program.
Efter at have gemt kalderens registre, skal vi have et storageareal til vore registre, hvis vi skulle finde på at kalde et andet program.
RSA GETMAIN RC,LV=72
OR R1,R1
BZ NO_STORAGE_OBTAINED
ST R1,8(,R13)
ST R13,4(,R1)
LR R13,R1
USING SA,R13
OR R1,R1
BZ NO_STORAGE_OBTAINED
ST R1,8(,R13)
ST R13,4(,R1)
LR R13,R1
USING SA,R13
SA DSECT
SAVEAREA DS 18F
Vi henter 72 bytes, svarende til 18 fuldord (18F). Det er alt vi skal bruge.
De to Storeinstruktioner (ST) laver en sammenkædning af registersavearealerne og til sidste lader vi R13 pege på vort Register Save Area og skaber adressability til det med USING.
Lige inden vi forlader programmet skal vi genetablere kalderens registre. Det gøres således:
L R13,SAVEAREA+4
LM R14,R12,12(R13)
RETURN RC=0
Først skal R13 peger på kalderens Registe Save Area. Derefter hentes alle registre fra dette areal, - undtagen R13 selvfølgelig. Til slut returnerer vi til kalderen.
Dit program er fuldt reentable og kan lægges i Link Pack Area (LPA). Det er et ReadOnly-areal, som er tilgængeligt for alle address spaces (regioner). Det kan også bruges samtidig at flere tasks/threads.
I næste artikel skal vi snakke om at kalde andre programmer, hvis du stadig vil have dit program til at være reentable. Det er ikke så lige til, som det lyder.
Læsestof:
Ingen kommentarer:
Send en kommentar