tirsdag den 25. august 2015

Mere om at blive reentable ...


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