Page 1 of 1

ASSEMBLER Information as a beginner

PostPosted: Tue May 05, 2020 3:33 pm
by upendra6921
Hi All,

I don't have knowledge on Mainframe Assembler.

Some one can help me with below details.

1. Structure of Assembler program.
2. Registers used in Assembler and their usage with some examples.
2. Instructions of Mainframe Assemblers (Not all but simple one like display variable or move data..etc)
3. Simple Mainframe Assembler program (Simple Addition program - Adding two numbers)

Thanks!

Re: ASSEMBLER Information as a beginner

PostPosted: Tue May 05, 2020 4:40 pm
by NicC
Try searching the web for Bill Qualls's book "Mainframe Assembler Programming". It is available as a PDF download. You won't be able to run the PC/370 software unless you have Dosbox or an equivalent but you can use the z390 emulator written in Java.
Note that code in the book is not 100% compatible with mainframe assembler e.g. the WTO macro is different.

Re: ASSEMBLER Information as a beginner

PostPosted: Tue May 05, 2020 5:20 pm
by enrico-sorichetti
http://simotime.com/sim4home.htm

http://simotime.com/indexasm.htm

for Assembler 370 , but very good starting point

Re: ASSEMBLER Information as a beginner

PostPosted: Tue May 05, 2020 9:08 pm
by prino
The ultimate reference by the late John R. Ehrman of IBM Silicon Valley Lab:

Assembler Language Programming for IBM System z™ Servers Version 2.00

Re: ASSEMBLER Information as a beginner

PostPosted: Thu May 07, 2020 10:50 am
by steve-myers
prino wrote:The ultimate reference by the late John R. Ehrman of IBM Silicon Valley Lab:

Assembler Language Programming for IBM System z™ Servers Version 2.00

In my opinion, the Ehrman book is the ultimate text book for z/Architecture Assembler programming. This is a better link for the book than prino's link. Download the book to your hard drive and use your preferred PDF viewer rather than the PDF viewer in your browser. If you have 3 reams of paper handy (1 and 1/2 if you can print duplex), plenty of ink available and lots of time, print the book. In US English a "ream" is 500 sheets of letter type paper. Some of it is very detailed. I've been writing programs for this architecture for more than 50 years and quite a lot is more than I can understand. Just skip those sections and press on.

z/Architecture Principles of Operation is another substantial download that you should save to your hard drive and view with your preferred PDF viewer. It is easier to navigate, in some respects, than the Ehrman book, especially if you need details about individual instructions. It is strictly a reference; it will not help you program.

Re: ASSEMBLER Information as a beginner

PostPosted: Mon May 11, 2020 11:55 am
by steve-myers
  1. Structure of an Assembler program
    My, you ask a hard one; there are several ways to interpret the question. Assembler lacks the structure of a block oriented language. In other words, there is nothing in Assembler to directly duplicate something like
    if ( ... )
     {
      ...
     }
    else
     {
      ...
     }

    Attempting to directly duplicate something like that control structure really yields hard to understand code. You achieve reasonably easy to understand code by other means. For example, an environmental verification of code that requires two DD statements, and one has fairly stringent requirements might be something like this.
            OPEN  MF=(E,OPARM1)       OPEN SYSPRINT
             TM    (DCBOFLGS-IHADCB)+PRINT,DCBOFOPN  OPEN OK?
             BO    NXT0100                           YES
             MVI   RC,16
             B     EXIT
    NXT0100  DEVTYPE DCBDDNAM-IHADCB+DIRDCB,SVWORK1  GET DEVICE ATTRIBUTES >
                                                      FOR DD SYSUT1
             LTR   15,15               OK?
             BZ    NXT0200             YES
             LA    1,ERR2
             B     UT1ERR
    NXT0200  CLI   DVACLASS,UCB3DACC   SYSUT1 ALLOCATED TO DASD?
             BE    NXT0300             YES
             LA    1,ERR3
             B     UT1ERR
    NXT0300  RDJFCB MF=(E,OPARM2)      READ THE JFCB FOR SYSUT1
             MVC   HDRDSN,JFCBDSNM     DATA SET NAME TO PAGE HEADER
             MVC   HDRVOL,JFCBVOLS     VOLUME SERIAL TO PAGE HEADER
             OI    JFCBTSDM,JFCNWRIT+JFCNDSCB+JFCNDCB  SET FLAGS
             TM    JFCBIND1,JFCPDS     DSNAME SPECIFY A MEMBER NAME?
             BZ    NXT0400             NO, OK
             LA    1,ERR4
             B     UT1ERR
    NXT0400  SR    0,0                 READ THE FORMAT 1 DSCB FOR THE
             OBTAIN CAMLST              SYSUT1 DATA SET
             LTR   15,15               OK?
             BZ    NXT0500             YES
             LA    1,ERR5
             B     UT1ERR
    NXT0500  NI    DS1DSORG,255-DCBDSGU      VERIFY DATA SET IS
             CLC   DS1DSORG,=AL1(DCBDSGPO,0)  PARTITIONED
             BE    NXT0600                   OK
             LA    1,ERR6
             B     UT1ERR
    NXT0600  OPEN  MF=(E,OPARM2),TYPE=J  OPEN THE DIRECTORY
             ...
    UT1ERR   MVI   RC,12
    EXITMSG  BAL   14,OUTEDIT
    EXIT  ...
             ...
    OPARM1   OPEN  (PRINT,OUTPUT),MF=L
    OPARM2   OPEN  (DIRDCB,INPUT),MF=L
    CPARM    CLOSE (PRINT,,DIRDCB),MF=L
    XLIST1   DC    0A(0),AL1(X'80'+0),AL3(*-*)
    XLIST2   DC    0A(0),AL1(X'80'+7),AL3(JFCB)
    CAMLST   CAMLST SEARCH,JFCBDSNM,JFCBVOLS,F1DSCB
             ...
    PRINT    DCB   DSORG=PS,MACRF=PM,DDNAME=SYSPRINT,RECFM=VBA,LRECL=125, ->
                   EXLST=XLIST1
    DIRDCB   DCB   DSORG=PS,MACRF=GL,DDNAME=SYSUT1,EODAD=DIREOF,          ->
                   EXLST=XLIST2,RECFM=F,LRECL=256,BLKSIZE=256
    Now don't worry in detail about this code as it does things that beginners don't really use, like the DEVTYPE, RDJFCB and OBTAIN macros.

    The first OPEN macro does return to your program with a return code, but many programmers prefer to check the DCBOFOPN bit in the DCB rather than use the return code. In C terms, the structure would be
    FILE *print;
    int rc = 0;
    ...
    if (print = FOPEN(...) )
     {
      rc= 16;
      goto exit;
     }
    Now this fragment has the goto statement C programmers avoid at all costs, but you can't really get away from unconditional branches (the goto statement) in Assembler.
  2. Register usage
    You may already know the machine has 16 "general purpose" registers, numbered from 0 through 15. There are advantages to having large numbers of registers, and disadvantages. One surprising disadvantage is Assembler programmers tend to be very inefficient assigning registers. The compilers tend to do better! This code fragment just uses registers 1 and 15 directly, though there is implicit use of other registers. So let's start out discussing what is in specific registers.

    When the system starts your program the registers contain -
    Register Contents
        1    Address of parameter list
       13    Address of a register save area
       14    Address of next instruction to execute when your program terminates
       15    Address of the first instruction in your program

    Now, your program is expected to restore the original contents of registers 2 though 14. Register 15 is often used for a return code, and registers 0 and 1 are sometimes used to pass data of some sorts, though this is not applicable for programs entered through the JCL EXEC statement.

    The first thing most programs do when they are entered is to store the registers the program uses in the register save area provided by the caller. Now notice I did not say all registers. I did say the registers the program uses, actually the key word is registers the program modifies. The hardware has the Store Multiple (STM) instruction which is optimized to store several registers in consecutive storage locations quickly. But it highlights one of the disadvantages of a large number of registers: no matter how optimized STM is, and its paired Load Multiple (LM) instruction is, it still takes quite a long time to save and restore a lot of registers. Of course, for a "main" program, the time spent saving and restoring registers is insignificant, but it is important for a program entered thousands or millions of times.

    Many programmers often use register 12 as a base register.
  3. "Simple" instructions
    • Display variable
      Another hard one. You have to do two things to display a variable: convert the data to a printable form (assuming it is numeric), and actually printing the data. There are no library functions, though there are instructions that can help. You do have library macros to help, like the PUT macro, which is analogous to the C FPUTS library macro. So, I'll show some simple code later.
    • Move data
      Well, that one is easy. The MVC (Move Character) instruction, though a better name might be Move Data, is very easy, and I'll illustrate it below.
  4. Simple mainframe program
    This program adds 2 numbers and prints the result.
    START    CSECT                     ESTABLISH START CSECT
             USING *,12                ESTABLISH START ADDRESSABILITY
             SAVE  (14,12),,*          SAVE REGISTERS
             LR    12,15               PREPARE START BASE REGISTER
             LR    15,13               ADD NEW
             LA    13,SAVEAREA          SAVE AREA
             ST    13,8(,15)             TO THE
             ST    15,4(,13)              SAVE AREA CHAIN
             OPEN  (PRINT,OUTPUT)      OPEN THE OUTPUT DATA SET
             LA    14,OUTLINE          COMPUTE ADDRESS OF THE OUTLINE LINE
             L     0,NUM1              CONVERT NUM1 TO
             BAL   15,EDNUM             DECIMAL DIGITS
             MVC   0(3,14),=CL3' + '   ADD +
             LA    14,3(,14)
             L     0,NUM2              CONVERT NUM2 TO
             BAL   15,EDNUM             DECIMAL DIGITS
             MVC   0(3,14),=C' = '     ADD = SIGN
             LA    14,3(,14)
             A     0,NUM1              ADD NUM1 TO NUM2
             BAL   15,EDNUM            CONVERT SUM TO DECIMAL DIGITS
             LA    0,OUTLINE           PRINT THE LINE
             SR    14,0
             STH   14,(DCBLRECL-IHADCB)+PRINT
             PUT   PRINT,(0)
             CLOSE PRINT               CLOSE OUTPUT DATA SET
             L     13,4(,13)           LOAD ADDRESS OF THE HIGHER SAVE AREA
             RETURN (14,12),RC=0       RESTORE REGISTERS & RETURN
    EDNUM    ST    15,SAVE15           SAVE THE LINK REGISTER
             CVD   0,DWORK             CONVERT VALUE TO PACKED DECIMAL
             LA    15,WORKAREA+L'WORKAREA-1  PREPARE REGISTER 15
             LR    1,15                       AND REGISTER 1
             MVC   WORKAREA,EDPATT     COPY EDMK PATTERN TO WORK AREA
             EDMK  WORKAREA,DWORK+L'
    DWORK-L'EDMAX  CONVERT PACKED DECIMAL  X
                                                    DATA IN DWORK TO DIGITS
             BNM   NOTMINUS            BR IF VALUE IS POSITIVE
             BCTR  1,0                 BACKUP 1 BYTE
             MVI   0(1),C'
    -'           INSERT A LEADING -
    NOTMINUS SR    15,1                COMPUTE NUMBER OF BYTES TO MOVE
             EX    15,EDMVC            MOVE DECIMAL DIGITS TO OUTPUT
             LA    14,1(15,14)         UPDATE REG 14
             L     15,SAVE15           RESTORE THE LINK REGISTER
             BR    15
    EDMVC    MVC   0(0,14),0(1)        ** OBJECT OF EX INSTRUCTION **
    PRINT    DCB   DSORG=PS,MACRF=PM,DDNAME=SYSPRINT,RECFM=U,BLKSIZE=80
    SAVE15   DC    F'
    0'
    NUM1     DC    F'
    3415'
    NUM2     DC    F'
    -77'
    DWORK    DC    D'
    0'
    SAVEAREA DC    18F'
    0'
    EDPATT   DC    0C'
    12,345',C' ',2X'20',C',',X'202120'
    EDMAX    DC    0P'
    12345'
    WORKAREA DC    CL(L'
    EDPATT)' '
    OUTLINE  DC    CL80' '
             LTORG ,
             DCBD  DSORG=QS,DEVD=DA    DEFINE SYMBOLS FOR DCB DATA AREA
             END   START

    The output printed by the program is -
    3,415 + -77 = 3,338

    The main part of the program is deceptively simple.
            LA    14,OUTLINE          COMPUTE ADDRESS OF THE OUTLINE LINE
             L     0,NUM1              CONVERT NUM1 TO
             BAL   15,EDNUM             DECIMAL DIGITS
             MVC   0(3,14),=CL3' + '   ADD +
             LA    14,3(,14)
             L     0,NUM2              CONVERT NUM2 TO
             BAL   15,EDNUM             DECIMAL DIGITS
             MVC   0(3,14),=C' = '     ADD = SIGN
             LA    14,3(,14)
             A     0,NUM1              ADD NUM1 TO NUM2
             BAL   15,EDNUM            CONVERT SUM TO DECIMAL DIGITS
             LA    0,OUTLINE           PRINT THE LINE
             SR    14,0
             STH   14,(DCBLRECL-IHADCB)+PRINT
             PUT   PRINT,(0)

    The EDNUM internal function to convert a binary value in register 0 makes this code very simple. The output of EDNUM is the decimal digits left justified with leading 0s suppressed at the storage location specified by register 14, and with register updated to the address after the last digit.

    EDNUM    ST    15,SAVE15           SAVE THE LINK REGISTER
             CVD   0,DWORK             CONVERT VALUE TO PACKED DECIMAL
             LA    15,WORKAREA+L'WORKAREA-1  PREPARE REGISTER 15
             LR    1,15                       AND REGISTER 1
             MVC   WORKAREA,EDPATT     COPY EDMK PATTERN TO WORK AREA
             EDMK  WORKAREA,DWORK+L'
    DWORK-L'EDMAX  CONVERT PACKED DECIMAL  X
                                                    DATA IN DWORK TO DIGITS
             BNM   NOTMINUS            BR IF VALUE OID POSITIVE
             BCTR  1,0                 BACKUP 1 BYTE
             MVI   0(1),C'
    -'           INSERT A LEADING -
    NOTMINUS SR    15,1                COMPUTE NUMBER OF BYTES TO MOVE
             EX    15,EDMVC            MOVE DECIMAL DIGITS TO OUTPUT
             LA    14,1(15,14)         UPDATE REG 14
             L     15,SAVE15           RESTORE THE LINK REGISTER
             BR    15
    The code saves its link register and sets registers 1 and 15. Register 15 is the address of the last digit after the number is converted by the Edit and Mark (EDMK) instruction. EDMK does not always set register 1, so it is preset to the value it should have. The data in DWORK is a packed decimal number, right justified. DWORK+L'DWORK computes the address of the end of DWORK; EDMAX is a packed decimal number that defines the length of a packed decimal number with the same number of packed decimal digits as there are digit select characters in EDPATT.

    The EX instruction is a little complicated. It loads the instruction into an internal register, and ORs the low order 8 bits in the register into the second byte of the instruction (the number of bytes to move, in the MVC instruction), then runs the modified instruction. The instruction in storage is not modified.

Re: ASSEMBLER Information as a beginner

PostPosted: Sun Jun 21, 2020 11:19 pm
by steve-myers
Now.going back to the structure of an Assembler program, remember these points.
  • The initial contents of the registers.
  • Before your program exits, it must restore the contents of any registers it altered, except as noted in the next bullet.
  • Many times, register 15 is used as a return code.
These bullets lead us to this famous utility, though it is more commonly known by another name.
YF       CSECT
         SR    15,15
         BR    14
         END   YF
Except for register 15, it does not alter any registers, so it does not have to restore any registers.

Now, in the real world, a program has to use registers to do anything, so real world programs save registers in the register save area supplied by the caller, and restore the registers before the program returns.
YF       CSECT
         SAVE  (14,12),,YF-&SYSDATE-&SYSTIME
         RETURN (14,12),RC=0
         END   YF
SAVE and RETURN are macros provided by IBM. The (14,12) are just the registers to save or restore. The YF-&SYSDATE-&SYSTIME in the SAVE macro is just a character string the macro inserts into the program that serves as a program identifier. &SYSDATE and &SYSTIME represent the date and time the Assembler processed the program, and are a convenient method to locate the program in storage and verifying the correct version of the program is in storage. RC=0 in the RETURN macro directs the macro load 0 into register 15.

Now, if your program is going to use other programs, or use any of the common I/O macros, it must prepare a register save area for the other programs to use -
YF       CSECT
         SAVE  (14,12),,YF-&SYSDATE-&SYSTIME
         BALR  12,0
         USING *,12
         LA    15,SAVEAREA
         ST    13,4(,15)
         ST    15,8(,13)
         LR    13,15
         L     13,4(,13)
         RETURN (14,12),RC=0
SAVEAREA DC    9D'0'
         DCBD  DSORG=QS,DEVD=DA
         END   YF
Huh!? Doesn't register 13 already point to a register save area?

Yes, but the SAVE macro stored registers in that save area. If some other program then stores your registers in the save area the ability of your program to properly return to the calling program is impaired.