Home Back to 370 Assembler Tips & Tricks Index Links

General 370/390/z Assembler Language techniques

  • ALWAYS define the addressing mode (AMODE), residency mode (RMODE) and entry point for each CSECT.  Define the entry point using an ENTRY psuedo-op or on the END statement.


FOOSECT  CSECT                     Csect Definition.
FOOSECT  AMODE 31                  31-Bit Addressing.
FOOSECT  RMODE ANY                 Any Residency.
         ENTRY FOOEP               Entry point.
           .
           .
           .
         END   ,                   End of module.

  • NEVER use more than one base register for CSECT addressability and define a new CSECT when you have reached about 70% of the base register addressability.

  • Be consistent with your register usage.  IBM standards work very well.

  • DO NOT use cute register equates like "LINKREG" and "BASEREG".  That's just plain old stupid!


R0       EQU   0                   Parameter Register.
R1       EQU   1                   Parameter Reigster.
R2       EQU   2                   General Purpose & TRT.
R3       EQU   3                   General Purpose.
R4       EQU   4                   General Purpose.
R5       EQU   5                   General Purpose.
R6       EQU   6                   General Purpose.
R7       EQU   7                   General Purpose.
R8       EQU   8                   General Purpose.
R9       EQU   9                   General Purpose.
R10      EQU   10                  General Purpose.
R11      EQU   11                  General Purpose.
R12      EQU   12                  CSECT Base and LE CAA.
R13      EQU   13                  Register Save Area.
R14      EQU   14                  Return Address.
R15      EQU   15                  Link Address.

I had one client who thought it was extremely clever to equate registers 10 through 15 to RA through RF.  Try to find those suckers in the cross reference listing!  When I questioned the client about this unusual convention, they said: "That's hex."

I said: "I know it's hex, but the collating sequence is in EBCDIC stupid!"

  • ALWAYS drop registers as soon as the CSECT or DSECT they base are no longer referenced - even at the end of the module - this is simply for good complete documentation.

  • Here's a code sample of a properly set up assembler language module.  Note that this module is fully re-entrant and re-useable.  Also, note the consistent register usage.  Some things are simply fetishes of mine, such as the redundant CNOP's and commas after pseudo-ops that have no arguments.


MN01CN   TITLE 'Code Sample.' 
*---------------------------------------------------------------------*
*        MN01CN - Private code Csect for copyright preamble.          *
*---------------------------------------------------------------------*
         CSECT ,                   Private code Csect.
         AMODE 31                  Set 31-Bit addressing mode.
         RMODE ANY                 Set any (31/24-Bit) residency mode.
         DC    C'Copyright (C) 1994, Marc Niegowski'
         DC    C'Systems Programmer at large.'
         SPACE ,
*---------------------------------------------------------------------*
*        MN01CN - Symbol 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                   Internal stack pointer.
R9       EQU   9
R10      EQU   10
R11      EQU   11                  Module working storage base.
R12      EQU   12                  CSECT base.
R13      EQU   13                  Register save area anchor.
R14      EQU   14                  Linkage return register.
R15      EQU   15                  Linkage branch register.
         SPACE ,
PSMODE   EQU   0                   Bits 20-24 = 0000 PS Mode.
SSMODE   EQU   256                 Bits 20-24 = 0001 SS Mode.
ARMODE   EQU   512                 Bits 20-24 = 0010 AR Mode.
HMMODE   EQU   768                 Bits 20-24 = 0011 Home Mode.
         SPACE ,
*---------------------------------------------------------------------*
*        MN01CN - General purpose code sample.                        *
*---------------------------------------------------------------------*
         ENTRY MN01EP
MN01CN   CSECT ,                   MN01CN Control section start.
MN01CN   AMODE 31                  Set 31-Bit addressing mode.
MN01CN   RMODE ANY                 Set any (31/24-Bit) residency mode.
         SPACE ,
MN01EP   CNOP  0,8                 EP on doubleword boundary.
         BAKR  R14,0               Save caller's AR's and GPR's.
         SAC   ARMODE              Set AR mode.
         LAE   R12,0(15,0)         Load Csect base register.
         USING MN01EP,R12          Establish Csect addressability.
         SPACE ,
         STORAGE OBTAIN,           Allocate some stg. for reentrancy.  C
               LENGTH=WDSL         Size of storage to allocate.
         SPACE ,
         LAE   R11,0(0,R1)         Load a(storage area).
         USING WDS,R11             Establish stg. area addressability.
         SPACE ,
         MVC   WDSLR13,=CL4'F1SA'  Indicate system stack.
         LAE   R13,WDSLRSA         Load a(Register Save Area).
         EREG  R0,R1               Restore R0 and R1 from stack.
         LAE   R8,WDSSTACK         Initialize internal Stack Pointer.
         SPACE ,
* Csect main processing logic goes here.
         BAL   R14,GETCVT          Go find the MVS CVT.
         BAL   R14,GETTCB          Go find the MVS TCB.
         SPACE ,
MN01EX   DS    0H                  Csect exit routine.
         LAE   R1,0(0,R11)         Load address of storage area.
         SPACE ,
         STORAGE RELEASE,          De-allocate module's storage area.  C
               ADDR=(R1),          Address of storage to de-allocate.  C
               LENGTH=WDSL         Size of storage to de-allocate.
         SPACE ,
         XR    R15,R15             Clear return code (R15).
         PR                        Return to caller & restore regs.
         EJECT ,
*---------------------------------------------------------------------*
*        GETCVT Routine - get the MVS CVT.                            *
*---------------------------------------------------------------------*
GETCVT   DS    0H                  Routine entry point.
         ST    R14,0(,R8)          Store return address to stack.
         LA    R8,4(,R8)           Increment stack pointer.
         SPACE ,
         L     R10,CVTPTR          Load A(MVS CVT) from PSA after IPL.
         USING CVT,R10             Establish CVT addressability.
         MVC   WDSSYS,CVTSNAME     Save current MVS system name.
         SPACE ,
GETCVT99 DS    0H                  Routine exit.
         SH    R8,=H'4'            Decrement stack pointer.
         L     R14,0(,R8)          Restore return address.
         BR    R14                 Return to caller.
         SPACE ,
*---------------------------------------------------------------------*
*        GETTCB Routine - get the current MVS TCB.                    *
*---------------------------------------------------------------------*
GETTCB   DS    0H                  Routine entry point.
         ST    R14,0(,R8)          Store return address to stack.
         LA    R8,4(,R8)           Increment stack pointer.
         SPACE ,
         L     R10,CVTTCBP         Load A(current TCB/ASCB pointers).
         DROP  R10                 Drop MVS CVT.
         L     R9,4(,R10)          Load A(Current TCB).
         SH    R9,=AL2(TCBPXLEN)   Backup to TCB prefix area.
         USING TCBFIX,R9           Establish TCB addressability.
         SPACE ,
GETTCB99 DS    0H                  Routine exit.
         SH    R8,=H'4'            Decrement stack pointer.
         L     R14,0(,R8)          Restore return address.
         BR    R14                 Return to caller.
         SPACE ,
         DROP  R9                  Drop MVS TCB.
         EJECT ,
*---------------------------------------------------------------------*
*        LITERAL pool origin and constants.                           *
*---------------------------------------------------------------------*
         LTORG ,                   Build literal pool.
         SPACE ,
*---------------------------------------------------------------------*
         DROP  R11                 Drop WDS.
         EJECT ,
*---------------------------------------------------------------------*
*        Working storage DSECT.                                       *
*---------------------------------------------------------------------*
WDS      DSECT ,
WDSID    DS    CL4                 Storage block ID '$WDS'.
WDSLRSA  DS    18F                 Register save area.
         ORG   WDSLRSA+4           Set origin to R13 save word
WDSLR13  DS    F                   R13 save word.
         ORG   ,                   Reset origin.
WDSXRSA  DS    18F                 Register save area for others.
WDSSTACK DS    64F                 Internal stack space.
WDSSYS   DS    CL8                 Current MVS System name.
WDSL     EQU   ((*-WDS+7)/8)*8     Length of DSECT to nearest dblwd.
         EJECT ,
*---------------------------------------------------------------------*
*        MVS ASCB Dsect.                                              *
*---------------------------------------------------------------------*
         IHAASCB DSECT=YES,                                            C
               LIST=YES
         EJECT ,
*---------------------------------------------------------------------*
*        MVS ASSB Dsect.                                              *
*---------------------------------------------------------------------*
         IHAASSB LIST=YES
         EJECT ,
*---------------------------------------------------------------------*
*        MVS JSAB Dsect.                                              *
*---------------------------------------------------------------------*
         IAZJSAB DSECT=YES,                                            C
               LIST=YES
         EJECT ,
*---------------------------------------------------------------------*
*        MVS JSCB Dsect.                                              *
*---------------------------------------------------------------------*
         IEZJSCB
         EJECT ,
*---------------------------------------------------------------------*
*        MVS CVT Dsect.                                               *
*---------------------------------------------------------------------*
         CVT   DSECT=YES,                                              C
               LIST=YES
         EJECT ,
*---------------------------------------------------------------------*

*        MVS PSA Dsect.                                               *
*---------------------------------------------------------------------*
         IHAPSA DSECT=YES,                                             C
               LIST=YES
         EJECT ,
*---------------------------------------------------------------------*
*        MVS TCB Dsect.                                               *
*---------------------------------------------------------------------*
         IKJTCB DSECT=YES,                                             C
               LIST=YES
         EJECT ,
*---------------------------------------------------------------------*
*        MVS TIOT Dsect.                                              *
*---------------------------------------------------------------------*
TIOT     DSECT ,
         IEFTIOT1
         EJECT ,
*---------------------------------------------------------------------*
         END   MN01EP              End of module & entry point def.
         PUNCH ' ENTRY MN01EP   '  Linkage Editor/Binder card.
         PUNCH ' NAME MN01CN(R) '  Linkage Editor/Binder card.
         END   ,                   End of Linkage Editor/Binder input.

  • Contribution from Marc Reibstein - Systems Programmer


OK . . . I'll nit pick.  The
CNOP 0,8 is redundant following a CSECT which by definition is double word aligned.

If you make a minor change to the exit sequence in
GETCVT, you could use it to illustrate unbased code . . .

             LA    R14,4
             SR    R8,R14
             L     R14,0(,R8)
             BR    R14

You might want to specifically mention using
DS 0H for tags and the importance of the comma in RX format instructions especially in AR mode.

Now get the F%$# out of my office!

Obviously, he's WRONG! (Only kidding)

  • Here's an excellent submission from Systems Programmer John Wood:
    You can contact John Wood via email at jpw@marcsweb.com

  • Note that an SCON generates a displacement and NOT an address.


Hey Marc,
What's the method for including patch space where the space is initialized to the address?
Example:
          Addr    Data
          A100    A100A102A104A106



John,
Use an SCON.
Example:
          PATCH   DC   128S(*)

Regards, 
Marc Niegowski 

I will continue to add tips and techniques as time permits.

Please direct any inquiries or problems regarding this web to webmaster@marcsweb.com


Page design, composition and HTML by Marc Niegowski
Copyright © 1998-2012, Marc Niegowski - Connectivity, Inc., All Rights Reserved
23 W. Fourth Street • Media • Pennsylvania • 19063-2805 • USA
Phone: 610-566-0227 • Fax: 610-566-0641 • Email: Marc@Tech-Center.com

Revision Date: Wednesday, November 15, 2006 10:03:50 AM