CICS TS V5.1 introduced support for applications to run in AMODE(64), namely within 64-bit storage in the CICS address space, and thereby access up to 16 exabytes (EB) of virtual storage. This support allows you to develop programs written in non-Language Environment® (LE) assembler language, which are able to process large amounts of data. CICS also provides 64-bit versions of a subset of EXEC CICS API commands to manipulate this data in 64-bit storage (which has been referred to as ‘above the bar’).

Because CICS also allows linkage between AMODE(64) and AMODE(31) or even AMODE(24) programs, it is possible to provide service routines that handle data in 64-bit storage without rewriting other parts of the application.

This blog post is intended for those who have an understanding of CICS assembler application development, but would like to know more about AMODE(64) and its use in CICS; or application owners who need to manage large amounts of data and have a friendly assembler developer within earshot. It describes what is involved in writing an AMODE(64) native assembler program, and shows how you can incorporate this into existing applications to provide greater access to data.

CICS AMODE(64) Native Assembler Application Programming

Writing a CICS AMODE(64) native assembler application program is very similar to writing a CICS AMODE(31) native assembler application program.The same CICS macros that are included in the AMODE(31) version of the application program are included in an AMODE(64) application program.

Having said that, there are a number of differences between writing in AMODE(64) and AMODE(31), which are as follows:

  • The z/OS SYSSTATE macro must specify AMODE64=YES. The CICS macros DFHEISTG, DFHEIEND, DFHEIENT, DFHEIRET and DFHECALL are SYSSTATE aware and generate AMODE(64) assembler when SYSSTATE AMODE64=YES has been specified. The SYSSTATE macro must be invoked before any of the SYSSTATE aware CICS macros are invoked.
  • Macro DFHEIENT must use relative addressing. To specify that relative addressing is to be used, CODEREG=0 must be specified and STATREG and STATIC values must be supplied.
  • The AMODE(64) version of the CICS stub must be included in the Binder (Link-edit) step in a similar way that the AMODE(31) CICS stub must be included in the Binder step for an AMODE(31) or AMODE(24) application. The AMODE(64) CICS stub is DFHEAG.

When writing AMODE(64) assembler, whether for CICS or batch, care should be taken to ensure that the registers used to reference storage have valid addresses. There are assembler instructions that ensure that a clean 31-bit address is loaded into a 64-bit register. These instructions are LLGT and LLGTR. LLGT loads a 31-bit address into a registers and clears the top 33 bits of the registers. LLGTR loads a register from another register and clears the top 33 bits. Instruction LLGF can be used to load a fullword into a 64-bit register; the fullword is loaded into the bottom 32 bits of the register and the top 32 bits of the registers are cleared.

EXEC CICS 64-bit Commands

To allow AMODE(64) programs to use above-the-bar storage, CICS provides 64-bit variants of some of the CICS API commands, which can be used when running in AMODE(64). These are:

  • GETMAIN64 – To get storage above the bar (by default: other storage locations can be explicitly specified)
  • FREEMAIN64 – To release storage that was acquired by a program running in AMODE(64), typically used to free storage above the bar
  • PUT64 CONTAINER – To put data from 64-bit storage into a named channel container
  • GET64 CONTAINER – To get data from a named channel container into 64-bit storage
  • CICS AMODE(64) Assembler Example

    The example below shows an example of a CICS AMODE(64) native assembler application program. The source code has been augmented with annotations. There are many styles in which assembler code can be written, and no one is better than any other, it is just a matter of the writer’s preference. This example illustrates a possible style for writing AMODE(64) assembler in CICS.

    The example shows how to obtain shared storage located above the bar and save the address of the shared storage address in the CWA. The example does not show how data is loaded into the shared storage, as there are many ways in which this could be done. For example, you might want to read data from a VSAM file or from a Db2 database.

    The data stored in the shared storage above the bar in this example cannot be accessed by AMODE(31) or AMODE(24) applications, but an AMODE(64) assembler program called by the AMODE(31) or AMODE(24) application would be able to access this data and then return all, or portions of, the data to its caller.

    There are several ways in which the data could be returned to the AMODE(31) or AMODE(24) caller, including:

    • CICS COMMAREA
    • CICS container, within a channel
    • A buffer supplied by the caller

    The *ASM XOPTS statement is used to pass options to the translator. In this case NOPROLOG and NOEPILOG are specified to stop the translator inserting PROLOG and EPILOG instructions.

    *ASM XOPTS(NOPROLOG NOEPILOG) Translator options
    The SYSSTATE macro tells SYSSTATE aware macros that the AMODE is 64 and also specifies the architecture level of the machine that the program will execute on. The CICS native assembler macros are SYSSTATE aware so will generate AMODE 64 code when AMODE64=YES is set.


             SYSSTATE AMODE64=YES,ARCHLVL=4   Sysstate AMODE 64, Z10  
    ***********************************************************************  
    *        Register equates.                                               
    ***********************************************************************  
    r0       equ   0                                                         
    r1       equ   1                                                         
    r2       equ   2                                                         
    r3       equ   3                                                         
    r4       equ   4                                                         
    r5       equ   5                                                         
    r6       equ   6                                                         
    r7       equ   7                                                         
    r8       equ   8                                                         
    r9       equ   9                                                         
    r10      equ   10                                                        
    r11      equ   11                                                        
    r12      equ   12                                                       
    r13      equ   13                                                       
    r14      equ   14                                                       
    r15      equ   15                                                       
    *********************************************************************** 
    *        Module’s working storage.                                       
    *********************************************************************** 
    


    Macros DFHEISTG and DFHEIEND are SYSSTATE aware. These macros define DSECT DFHEISTG. As the SYSSTATE macro specified AMODE64=YES the CICS portion of this DSECT is defined for an AMODE 64 application.

    The CICS portion of the DSECT defines a format-four save area, the 64-bit address of the COMMAREA and EIB, and other fields used by CICS when the application program issues a CICS command.

    The application’s working storage variables are defined after the DFHEISTG macro and before the DFHEIEND macro. In this case these variables are wk_shared_storage_addr, wk_cwa_address and wk_flength.

    The DFHEIEND indicates the end of the DSECT.


             dfheistg ,                                                     
             ds    0ad                                                      
    wk_shared_storage_addr   ds  ad      Shared storage address             
    wk_cwa_addr              ds  ad      CWA address                        
    wk_flength               ds  f       Getmain64 flength                  
             dfheiend                                                       
    The next two DSECTs (cwa_mapping and shared_data) map the CWA and the shared data storage area.
    *********************************************************************** 
    *        CWA dsect.                                                     
    *********************************************************************** 
    cwa_mapping  dsect                                                      
    cwa_shared_storage_addr  ds  ad      Shared storage address             
    *********************************************************************** 
    *        Shared data dsect.                                             
    *********************************************************************** 
    shared_data  dsect                                                      
    shared_thing ds   xl1000             Shared data object                 
    shared_data_length equ *-shared_data Length of shared data 
    


    The following statements name the CSECT and its AMODE and RMODE.


    AMODE64X csect                                                          
    AMODE64X amode 64                                                       
    AMODE64X rmode 31  
    


    Macro DFHEIENT generates the program’s entry code. This code:

    • Saves the caller’s registers in the format-four save area pointed to be R13.
    • Makes a call to DFHEAG0 is obtain the program’s working storage. This storage must be obtained below the bar to allow all CICS command processors to function correctly.
    • Sets up the working storage, static and EIB registers. The working storage register is R13, the static register is R12 and the EIB register is R11.


                                                         
             DFHEIENT CODEREG=0,           Relative addressing             -
                   DATAREG=R13,            Data register                   -
                   EIBREG=R11,             EIB register                    -
                   STATREG=R12,            Static register                 -
                   STATIC=STATIC_AREA      Static label                     
    *********************************************************************** 
    *        Obtain above the bar shared storage.                           
    *********************************************************************** 
    


    The CICS command below obtains above the bar shared storage. The address of the shared storage obtained is returned in R2 if the command is successful.


             EXEC CICS GETMAIN64                                           -
                   FLENGTH(LENGTH_OF_SHARED_STORAGE)                       -
                   SET(R2)                                                 -
                   SHARED                                                  -
                   NOHANDLE
    


    The code below checks the EIB response and if it is not normal jumps to label abend1.


             clc  eibresp,dfhresp(normal)                                   
             jne  abend1
    


    If the response to the command is normal the address of the shared storage is saved in the program’s working storage.


             stg  r2,wk_shared_storage_addr  Save shared storage address   
    


    Insert code here to load data into the shared storage. Data could be read from many sources including VSAM files or databases.


    *********************************************************************** 
    *        Obtain address of CWA.                                         
    *********************************************************************** 
    


    The CICS command below returns the address of the CWA in R3 if the command is successful.


             EXEC CICS ADDRESS CWA(R3) NOHANDLE 
    


    The code below checks the EIB response and if it is not normal jumps to label abend2.


             clc  eibresp,dfhresp(normal)                                   
             jne  abend2 
    


    If the response to the command is normal the address of the CWA is saved in the program’s working storage.


             stg  r3,wk_cwa_addr             Save CWA address               
    *********************************************************************** 
    *        Save shared storage address in CWA.                            
    *********************************************************************** 
    


    The code below uses the CWA mapping to save the address of the shared data area in the CWA.


             using cwa_mapping,r3                                           
             stg  r2,cwa_shared_storage_addr Save shared storage addr       
             drop r3                         Drop r3                        
    *********************************************************************** 
    *        Return to CICS.                                                
    *********************************************************************** 
    return   ds   0h
    


    The command below returns control to CICS. In fact the DFHEIRET macro could have been used instead the of the CICS return command.


             EXEC CICS RETURN                                               
    *********************************************************************** 
    *        Issue abend.                                                   
    *********************************************************************** 
    


    The CICS command below issues abend ERR1 if the CICS GETMAIN command is not successful.


    Abend1   ds   0h                                                        
             EXEC CICS ABEND ABCODE('ERR1')                                 
    The CICS command below issues abend ERR2 if the CICS ADDRESS command is not successful. 
    Abend2   ds   0h                                                        
             EXEC CICS ABEND ABCODE('ERR2')                               
    *********************************************************************** 
    *        Static   
    *********************************************************************** 
    


    The program’s static area


    static_area   ds  0fd                                                   
    length_of_shared_storage  dc  al4(shared_data_length)                   
    *********************************************************************** 
    *        Ltorg                                                          
    *********************************************************************** 
             ltorg                                                          
             end   
    


    Using AMODE(64) native assembler programs

    An AMODE(64) program such as the example shown above could be used to store large amounts of data, and return portions of this to other programs within an application. In this scenario, the AMODE(64) program could act as a service routine which is called by programs in other addressing modes to manipulate large storage areas on their behalf.

    One particularly valuable way of using an AMODE(64) program could be to put data from a 64-bit storage area directly into a container within a channel (either a named channel or the default current channel). This data in this container can then be accessible to an AMODE(31), or even AMODE(24), program by using the container API. The EXEC CICS GET CONTAINER command will return the 64-bit data into a 31-bit (or 24-bit) storage area provided by the invoking program. This can be a useful way of sharing data between 64-bit ‘service’ routines and other programs in the application, without the need to convert all of the application to AMODE(64) native assembler.

    To invoke an AMODE(64) program from a program in another addressing mode, use EXEC CICS LINK or XCTL.

    Further Reading

    If you would like to learn more about AMODE(64) programming in CICS, the following topics in the KnowledgeCenter could be of interest:

    Join The Discussion

    Your email address will not be published. Required fields are marked *