Notes on IBM Mainframe Assembly Language
Kevin C. O'Kane
Last update: March 8, 2007

  1. Resources

    On-Line IBM S/390 Principles of Operation

    PC Based Simulator for IBM 370 (PC370.ZIP)

    Note: the author of the simulator, Donald S. Higgins, no longer accepts registrations and states that you may freely distribute the shareware version without charge.

  2. Registers: 16 general purpose 32 bit registers numbered 0 through 15. 4 64 bit floating point registers.

  3. Addressing -

    1. Register: the operand is in the register. Example:

      AR R2,R3 *Contents of R3 added to R2, result remains in R2
      SR R3,R4 *Contents of R4 subtracted from R3, result in R3
      LR R4,R5 *Contents of R5 copyed to R4

    2. Immediate: the operand is an 8 bit byte contained in the instruction. Examples:

      OI MEM1,X'0F' *a byte containing X0F is OR'ed with the byte in memory at MEM1

    3. Memory: the operand is in memory and its address is calculated: (Note: exception: if either the index register and/or the base register is designated as register 0, there is no contribution - register zero does not participate in address computation.)

      1. for RX instructions, by adding the contents of the index (X2) register, base register (B2) and the displacement (D2). The memory address is the second operand and a register is normally the first operand. Examples:

        A R5,0(R0,R8) *the word in memory pointed to by R8 is added to R5
        A R5,20(R0,R8) *the word in memory 20 bytes past the address in R8 is added to R5
        A R5,20(R8,R0) *same as above
        A R5,20(R0,R0) *the word at location 20 is added to R5
        A R5,20(R7,R8) *the word 20 bytes past the sum of R7 and R8 is added to R5
        LA R5,20(R7,R8) *the address is calculated and placed in R5
        LA R5,4(R0,R5) *the value in R5 is incremented by 4
        A R5,MEM2 *the word at memory location labeled MEM2 is added to R5.
        A R5,MEM2+4 *the word 4 bytes past MEM2 is added to R5
        A R5,MEM2(R7) *the word at MEM2 + R7 is added to R5

        The last three examples assume you have established a base register and that MEM2 is a label in the data area of your program.

      2. for instructions with an S operand (SI, RS, SS), by adding the contents of the base register (B) and the displacement (D). Examples:

        MVC 0(30,R6),0(R7) *30 bytes in memory beginning at the address in R7 are copied 
                   *to memory the address beginning at the address in R6
        MVC 20(30,R6),50(R7) *30 bytes in memory beginning at 50 bytes past the address
                     *in R7 are copied to memory beginning at 20 bytes past the
                     *address in R6
        MVC MEM1,MEM2 *the bytes beginning at label MEM2 are copied to the memory beginning
              *at MEM1.  Assumes a base register exists and the MEM1 and MEM2
              *are labels with length attributes. The length code is determined by
              *the length attribute of the target.
        

  4. Instruction formats:

    1. RR - generally, both operands are in registers. Instruction consists of a one byte op code followed by a byte containing 2 4 bit fileds: one for each register specification. Exception: the BCR instruction where the first register field is a mask. In most cases, the result is left in the first operand.

    2. RX - generally, the first operand (the target) is in a register and the second argument is in memory. The memory address is calculated from the contents of the base register, index register and the displacement.

    3. SS - generally, both operands are in memory. The result is normally placed in th first operand. The second byte of the instruction is a length field. It is treated as an 8 bit length or two 4 bit lengths, depending on the instruction.

    4. RS - generally, two registers and a memory operand. The meaning varies dependingon the instruction


Programming

  1. Generally, code goes first and the data area at the end.

  2. The first lines of code are devoted to linkage - saving the calling programs registers and establishing a base register. For the simulator, this is done with macros and assmebler directives.

                PRINT NOGEN
    BEGIN       BEGIN
                REGS
    

    The PRINT NOGEN is a directive to the assembler and tells it to print your expanded code. The BEGIN macro with the label BEGIN established the linkage and sets up R13 as your base register (an unusual choice). It also names your control section BEGIN (from the label - it does not need to be BEGIN - use any name up to 8 characters beginning with a letter and containing letters and numbers). The REGS macro makes it possible to use R0, R1, R2, ... rather than 0, 1, 2, ... which would be required otherwise.

    To return and restore the calling program's registers, use the RETURN macro. The very end of the file has an END directive with the name of the control section.

    Example of a program to sum the integers from 0 to 10:

                PRINT NOGEN
    BEGIN       BEGIN
                REGS
                SR R2,R2 * zero R2
                SR R3,R3 * zero R3
    LOOP        AR R2,R3
                LA R3,1(R0,R3) * increment R3
                C R3,=F'10'
                BNE LOOP
                CVD   R2,DBL * converts from binary to packed
                ED    RESULT,DBL+6 * converts from packed to zoned
                WTO   RESULT
                RETURN
                LTORG
    RESULT      DC    X'40202120'
    DBL         DC    D'0'
                END   BEGIN
    

    The program zero's out R2 and R3. It adds R3 to R2 and increments R3. It tests R3 against the value 10 and branches back up to LOOP if not equal. Whne R3 equals 10, it falls through. Printing the contents of a register involve converting the binary contents of the register (R3) to packed decimal (CVD) then unpacking the reslult to zoned decimal (printable). The unpacking is done by the ED instruction. The WTO macro prints the value in the memory locations associated with the label RESULT.

  3. Conditional Branch Instructions (BC, BCR)

    These instructions branch depending on settings in the condition code. The condition code can range in value from 0 to 3. It is set after many instructions to indicate the result (negative, zero, positive, overflow, for example, after binary arithmetic instructions). In both the BC and BCR, RX and RR instructions, respectively, the first operand is treated as a mask rather than as a register designation. The mask is thus 4 bits. Each bit corresponds to a condition code value for which the instruction will branch. If mask bit one is 1, the instruction will branch if the condition code is zero, if mask bit two is 1, the instruction will branch if the condition code is 1, mask bit three for a condition code of 2, and mask bit four for condition code of 3. Thus is bits 0 and 2 of the mask are 1, the instruction will branch if the condition code is either 0 or 2. If all bits of the mask are zero, no branch ever takes place. If all bits of the mask are 1, a branch always takes place (called an unconditional branch).

    The mask can be specified in any manner. The most popular are as a decimal number or as a bit string. As a bit string, the bits are set by position to indicate the branch. If specified as a decimal, the decimal number is the equivalent of the bit string. Examples:

    BC B"1000",LAB  or  BC 8,LAB   Branch if condition code is zero
    BC B"0100",LAB  or  BC 4,LAB   Branch if condition code is one
    BC B"0010",LAB  or  BC 2,LAB   Branch if condition code is two
    BC B"0001",LAB  or  BC 1,LAB   Branch if condition code is three
    BC B"1001",LAB  or  BC 9,LAB   Branch if condition code is three or zero
    BC B"1011",LAB  or  BC 11,LAB  Branch if condition code is three, two or zero
    

    Additionally, there are builtin extended mnemonic branch instructions. These are instructions where the assmbler will fill in the mask for you. See the instruction list for details.

    Note: in the BC instruction, the branch address is computer in the usual way for an RX instruction. For the BCR instruction, the branch address is the contents of the register specified as the second operand except, if the second operand is specified as register zero, no branch takes place.

  4. Compare Instructions

    *     Signed arithmetic
    
          C R3,LAB     *artihmetic full word binary compare
          CR R3,R4     *arithmetic full word binary compare
          CH R3,LAB    *arithmetic half word compare
          CP LAB1,LAB2 *signed packed decimal compare
    
    *     condition code:  A = B  1000
    *                      A < B  0100
    *                      B > C  0010
    
    *     Unsigned logical compare
    
          CL R3,LAB     *unsigned full word binary compare
          CLR R3,R4     *unsigned full word compare
          CLC LAB1,LAB2 *unsigned string comparison
          CLI LAB,C'X'  *unsigned one byte comparison
    
    *     condition code:  A = B 1000
    *                      A > B 0100
    *                      A < B 0010
    

  5. Other Branch Instructions

    1. BAL and BALR - Branch and Link

      The BAL and BALR instructions unconditionally (i.e., they always branch - they do not depend on the condition code) branch to the address specified by the second operand (a base, index, displacement address in the case of the BAL and the address contained in the register designated as the second operand in the case of the BALR [except if the register specified is R0, in which case no branch takes place]). In both cases, the abosolute memory address of the instruction following the BAL or BALR is placed into the register specified as the first operand.

      An important use for these instructions is to branch to a subroutine and load into a register the address of the return point. In the case of the BALR, it is often used, in combination with R0 as the second operand, to load a register with the absolute memory address of the byte following the instruction. Example:

            L R15,=V(SUB1) * load the address of a subroutine
            BALR R14,R15   * branch to subroutine 
      

  6. Packed Decimal Format and Zoned Format

    The IBM mainframe has a data type called packed decimal. In this format, decimal numbers are represented as a sequence of 1 to 16 bytes, with two decimal digits to the byte except for the last byte which has one digit and a sign. Thus, numbers from 1 to 31 digits can be respresented. Each digit is stored in 4 bits - half a byte. The final byte has its low order 4 bits as the sign of the number. The hex digits C, A, F, and E indicate the number is positive while D and B indicate a negative number.

    A printable number is said to be in zoned format. In zoned format, the high oreder 4 bits of each byte are all ones (hex F) and the low order 4 bits are the digit portion.

    The instruction CVD converts a binary quantity in a register to packed decimal; the instruction CVB converts a packed decimal to binary. The ED (edit) instruction converts from packed decimal to zoned decimal and the PACK instruction converts from zoned decimal to packed decimal. The CVD is unusual in that the target is addressed by the second operand.

  7. Data Specification - DC and DS

    A DC statement reserves and initializes memory in your program. The DS statement reserves memory without initialization. There are a number of format variations:

    LAB01       DC F'123'               *binary full word
    LAB2        DC C'HELLO WORLD'       *character string
    LAB3        DC B'1011101010001001'  *bit string
    LAB4        DC X'2F3C'              *hexadecimal string
    LAB5        DC P'1234'              *packed decimal string
    
    LAB6        DS 18F                  *reserve 18 full words
    

  8. Literals

    You may use a shorthand notation in place of a label for the source memory operand in many instructions. A literal looks like a DC operand but is preceeded by an "=" sign. Note: Immediate operands are not literals, they are a single byte value. Examples:

          L R1,=F'123'                *loads R1 with 123 
          MVC MESSAGE,=C'Hello World' *moves the string to MESSAGE
          MVC RESULT,=X'40202120'     *moves an edit pattern to RESULT
          CLI LAB,C'X'                *immediate - no = sign
    

    Literals become DC's and placed in your program immediately after the LTORG directive.

  9. Base Register Addressing

    Memory operands in RX, SI, SS and RS instructions are addressed as a combination of index register, base register and displacement (RX), or displacement and base (all others). Even in the case of RX instructions, the index register is seldom used and addressing of the memory operand is accomplished mainly by base and displacement.

    When addressing a memory operand with base and displacement, the base register (any register between R1 and R15 but usually R12 or lower) contains the absolute address of a location in memory. The memory operand is calculated as a forward displacement from the location in memory pointed to by the base register. Displacements are positive 12 bit numbers and thus can range from 0 to 4095. An assembly language program loads its base register at the beginning and the assmebler, having been told which register is the base and where it is pointing, calculates the displacements for symbolic labels used in the program.

    The purpose of base-displacement addressing was to permit code modules to be relocatable to any place in real memory. In order for that to happen, program modules need to address operands without using absolute addresses. Instead, addresses are relative to the contents of a base register. If a module is loaded to another area of memory, so long as the base registers are adjusted, the operands of the program are still at the same relative displacement from the base. (Note: most programs have a few absolute addresses that are adjusted for the load point during actual program load.)

    One problem with base-displacement addressing is that the maximum distance from a base register is 4095 bytes. This is solved by having multiple base registers with the second pointing 4096 bytes beyond the first and so forth. However, for large programs, there are not enough spare registers so other techniques are employed. In larger programs, blocks of code establish their own base register on entry so the same register or registers are re-used. Loading a base register with the an absolute addres can be achieved by a BALR instruction with the second operand being R0. No branch takes place but the first operand receieves the absolute address of the byte immediately following the BALR:

          BALR R12,R0
          USING *,R12
    

    The above loads the absolute address of the byte following the BALR into R12 then tells the assmebler to use R12 as a base register. You will also note the DROP directive. This discontinues use of a base register. The use of USING and DROP are assemble-time directives - they cover areas of code and are not run time states.

    When operands can be addressed with a valid base and displacement combination, they are said to be 'in using'; if an operand is beyond the 4095 byte displacement of a base register, it is said to be 'out of using'.

    The following is often seen if more than one base register is being set:

          BALR R12,R0
          USING *,R12,R11,R10
          LA R11,2048(R0,R12)
          LA R11,2048(R0,R11)
          LA R10,2048(R0,R11)
          LA R10,2048(R0,R10
    

    This loads R12 with the absolute address of the byte imeediately beyond the BALR. Then it tells the assmebler that registers 12, 11 and 10 maybe used for addressing. The assembler assumes that these registers are set to 4096 and 8192 bytes apart, respectively. Then, the LA instruction is used to set R11 and R10 from the value in R12. Note: the maximum displacement is 4095 so two LA's are required to add 4096.

    For example, take the program:

                PRINT NOGEN
    BEGIN       BEGIN
                REGS
                SR R2,R2 * zero R2
                SR R3,R3 * zero R3
    LOOP        AR R2,R3
                LA R3,1(R0,R3) * increment R3
                C R3,=F'10'
                BNE LOOP
                CVD   R2,DBL * converts from binary to packed
                ED    RESULT,DBL+6 * converts from packed to zoned
                WTO   RESULT
                RETURN
                LTORG
    RESULT      DC    X'40202120'
    DBL         DC    D'0'
                END   BEGIN
    

    This program ostensibly makes use of four symbolic references whose base/displacement must be calculated by the assembler. These are: LOOP, RESULT, DBL and =F'10'. Additionally, there are several other symbolic references generated by the macros (BEGIN, REGS, WTO and RETURN). If you assemble the above and look at the listing file (the .PRN file from the simulator), you see:

      SUM                                                PAGE    1
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
    
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
     000000                               1
     000000                               2          PRINT    NOGEN
     000000                               3 *++++    BEGIN
     000000                               4 BEGIN    CSECT
     000000                               5          USING    *,15
     000000 47F0F058              0058    6          B        KZHQX001
     000004 0B                            7          DC       AL1(11)
     000005 C2C5C7C9D5404040              8          DC       CL11'BEGIN   '
     000010 0000000000000000              9 HZQKX001 DC       18F'0'
     000058 90ECD00C              000C   10 KZHQX001 STM      14,12,12(13)
     00005C 50D0F014              0014   11          ST       13,HZQKX001+4
     000060 18ED                         12          LR       14,13
     000062 41D0F010              0010   13          LA       13,HZQKX001
     000066 50D0E008              0008   14          ST       13,8(0,14)
     00006A                              15          DROP     15
     00006A                              16          USING    HZQKX001,13
     00006A                              17 *+++++++ REGS
     00006A              00000000        18 R0       EQU      0
     00006A              00000001        19 R1       EQU      1
     00006A              00000002        20 R2       EQU      2
     00006A              00000003        21 R3       EQU      3
     00006A              00000004        22 R4       EQU      4
     00006A              00000005        23 R5       EQU      5
     00006A              00000006        24 R6       EQU      6
     00006A              00000007        25 R7       EQU      7
     00006A              00000008        26 R8       EQU      8
     00006A              00000009        27 R9       EQU      9
     00006A              0000000A        28 R10      EQU      10
     00006A              0000000B        29 R11      EQU      11
     00006A              0000000C        30 R12      EQU      12
     00006A              0000000D        31 R13      EQU      13
     00006A              0000000E        32 R14      EQU      14
     00006A              0000000F        33 R15      EQU      15
     00006A 1B22                         34          SR       R2,R2 * zero R2
     00006C 1B33                         35          SR       R3,R3 * zero R3
     00006E 1A23                         36 LOOP     AR       R2,R3
     000070 41303001              0001   37          LA       R3,1(R0,R3) * increment R3
     000074 5930D09C              00AC   38          C        R3,=F'10'
     000078 4770D05E              006E   39          BNE      LOOP
     00007C 4E20D0A8              00B8   40          CVD      R2,DBL
     000080 D203D0A4D098   00B4   00A8   41          MVC      RESULT,=X'40202120'
     000086 DE03D0A4D0AE   00B4   00BE   42          ED       RESULT,DBL+6
     00008C                              43 *+++++++ WTO   RESULT
     00008C 4300D0A8              00B8   44          IC       0,RESULT+L'RESULT
     000090 925BD0A8              00B8   45          MVI      RESULT+L'RESULT,C'$'
     000094 4120D0A4              00B4   46          LA       2,RESULT
     000098 0AD1                         47          SVC      209
     00009A 4200D0A8              00B8   48          STC      0,RESULT+L'RESULT
     00009E                              49 *+++++++ RETURN
     00009E 58DD0004              0004   50          L        13,4(13)
     0000A2 98ECD00C              000C   51          LM       14,12,12(13)
    
     SUM                                                PAGE    2
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
    
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
     0000A6 07FE                         52          BR       14
     0000A8                              53          LTORG
     0000A8 40202120                     53                   X'40202120'
     0000AC 0000000A                     53                   F'10'
     0000B0 0005                         54 FIVE     DC       H'5'
     0000B2 0003                         55 THREE    DC       H'3'
     0000B4 40202120                     56 RESULT   DC       X'40202120'
     0000B8 4000000000000000             57 DBL      DC       D'0'
     0000C0                              58          END      BEGIN
    
     SUM                                                PAGE    3
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
    
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
    
      SYMBOL   VALUE    LENGTH  TYPE ID DEF#  XREF#
    
      BEGIN    00000000 000000C0 CST 01 00004 00058
      DBL      000000B8 00000008 REL 01 00057 00042 00040
      FIVE     000000B0 00000002 REL 01 00054
      HZQKX001 00000010 00000004 REL 01 00009 00016 00013 00011
      KZHQX001 00000058 00000004 REL 01 00010 00006
      LOOP     0000006E 00000002 REL 01 00036 00039
      R0       00000000 00000001 ABS 00 00018 00037
      R1       00000001 00000001 ABS 00 00019
      R10      0000000A 00000001 ABS 00 00028
      R11      0000000B 00000001 ABS 00 00029
      R12      0000000C 00000001 ABS 00 00030
      R13      0000000D 00000001 ABS 00 00031
      R14      0000000E 00000001 ABS 00 00032
      R15      0000000F 00000001 ABS 00 00033
      R2       00000002 00000001 ABS 00 00020 00040 00036 00034 00034 00040
      R3       00000003 00000001 ABS 00 00021 00038 00037 00037 00036 00035
                                              00035 00038 00037
      R4       00000004 00000001 ABS 00 00022
      R5       00000005 00000001 ABS 00 00023
      R6       00000006 00000001 ABS 00 00024
      R7       00000007 00000001 ABS 00 00025
      R8       00000008 00000001 ABS 00 00026
      R9       00000009 00000001 ABS 00 00027
      RESULT   000000B4 00000004 REL 01 00056 00048 00048 00046 00045 00045
                                              00044 00044 00042 00041
      THREE    000000B2 00000002 REL 01 00055
    . SUM                                                PAGE    4
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
     LITERAL CROSS REFERENCE
     0000A8                              58                   X'40202120'
     0000A8                              58                   00041
     0000AC                              58                   F'10'
     0000AC                              58                   00038
    

    Notes on the above:

    1. Lines 2 through 16 represent the expansion of the BEGIN macro. It establishes the linkage with the calling program and sets up a base register:

      1. Line 3: a comment indicating the name of the macro being expanded.
      2. Line 4: an assembly directive indicating the beginning of a control section named BEGIN.
      3. Line 5: an assembly directive telling the assembler that register 15 is now the base register and it is pointing here (* means current value of the location counter - see rightmost column).
      4. Line 6: branch unconditionally to label KZHQX001 and around the small intervening data area. Note the code generated for this instruction: 47F0F058 (second column). This means a BC instruction (op code 47) with a mask of F (all bits on - always branch) and an index register of 0, base register of 15 (F) and a displacement of 058. Since the index register is specified as 0, it does not contribute (register 0 does not participate in addressing). Thus, the address to branch to is X058 bytes past the contents of register 15.

        Why is R15 used as a base register and why is it pointing at the beginning of your program? Because on entry into a program, R15 always points at the first instruction of the program. At assembly time, we normally list the addresses of the program beginning as location counter value 000000. However, when the program runs, it will be located at some other address, let us say 100000. In that case, R15 will have 100000 in it but the label we are branching to will still be X058 bytes away.

      5. Line 7: A byte in memory initialized with the value 11.
      6. Line 8: 11 bytes of memory with the name of the program BEGIN in the first 8 butes padded to the right with blanks.
      7. Line 9: reserved memory for 18 full words each initialized to zero to be used as a save area.
      8. Line 10: a Store Multiple instruction that is storing registers 14, 15, 0, 1, 2, ... 11, and 12 into the 15 full words beginning at 12 bytes past the address contained in register 13. On entry into a subroutine, register 13 points to the address of an 18 full word save area in the calling program. This instruction is saving the contents of teh calling program's registers in the calling program's save area.
      9. Line 11: store the contents of register 13 in the second full word (+4) of our save area. Note the index (0), base (15) and displacement (014) in teh store (op code 50) instruction.
      10. Line 12: copy contents of register 13 to register 14.
      11. Line 13: load the address of the label HZQKX001 into register 13.
      12. Line 14: store the contents of register 14 into the second full word (8 past R14) of the calling program's save area (whose address is now in R14).
      13. Line 14: tell the assmbler to discontinue using R15 as a base register.
      14. Line 15: tell the assembler to begin using R13 as a base register and assume that it is pointing at HZQKX001.

    2. Lines 17-33: Expansion of the REGS macro. The REGS macro contains 16 pre-processor directives telling the preprocessor that an instance of, for example, R5 should be replaced by 5.

    3. Lines 34-42: Your code.
      1. Lines 34 and 35: zero the contents of R2 and R3 by subtracting them from themselves.
      2. Line 36: add the contents of R3 to R2 and leave the result in R2. note that this line has a label - it is the loop re-entry point.
      3. Line 37: increment the contents of R3 by one. It is a common trick to use the LA instruction for small, positive increments on numbers that do not exceed the address size of the machine. The LA instrustion does address arithmetic and places the result in the register designated as the first operand. In this case, we have it add a displacement of 1 to the contents of R3 and then placing the answer in R3.
      4. compare the value in R3 with a full word in memory conmtaining the binary equivalent of decimal 10. Note the =F'10' literal format. This tells the assembler to create full word in memory and initialize it with 10 and place its base/displacement address in the second operand portion of the C instruction.
      5. Line 39: branch if the values compared were not equal. Note the mask in the extended BC instruction. If teh branch takes place, execution resumes at the istruction labelled LOOP. If the branch does not take place, the program moves to line 40.
      6. Line 40: convert the binary number in R2 to packed decimal format and place the result in the double word (8 bytes) at label DBL.
      7. Line 41: move the edit pattern to RESULT. The pattern will be replaced by the printable answer. The pattern means: the fill character is blank (Hex 40), there are three digit positions, the first 2 of which will be replaced byb teh fill character if zero but the final position will be printed as zero if that is its value.
      8. Line 42: the ED command converts the packed format answer to to zone decimal. The last 2 bytes of DBL are the only ones converted. The result is in RESULT.
    4. Lines 43-48: expansion of the WTO macro which prints the value in RESULT.
    5. Lines 49-52: expansion of the RETURN macro. Restore the resgisters and branch unconditionally to the address contained in R14 (the resturn linkage address).
    6. Lines 53: tell the assembler to place any literals here. Two literals are placed here - both have line number 53.
    7. Lines 54-57: our data.
    8. Line 58: tells the assembler that this is the end of the CSECT named BEGIN.

  10. Input/Output

    Input/output operations on a mainframe were traditionally record oriented - usually involving fixed length records. Both input and output operations first require that you create a DCB - Data Control Block - a macro that creates a table that the system uses to communicate with the file or device. A DCB has many possible optional parameters, only a few of which are shown here.

    In the following example, input is read from a file named INPUT.DAT and written to the console (standadr out, on a PC). The input DCB is named INDCB (see below) and the parameters to in mean the following:

    LRECL=32          logical record length of 32 bytes
    RECFM=F           fixed length records
    MACRF=G           the GET macro will be used to access the file
    EODAD=ATEND       branch to label ATEND on end of data
    DDNAME=INPUT.DAT  file name to be opened and read
    

    Note that the continuation of the DCB begins in exactly column 16. Note also, that no line may extend past column 71.

    The program begins as usual. The OI instruction sets a flag in the DCB requesting conversion from ASCII to EBCDIC. This is not needed on an actual mainframe. The OPEN macro invokes the operating system and tells it to open the file named in INDCB. The GET macro causes input records to be read from the file and placed in REC. The GET macro always specifies the DCB associated with the file being read. The WTO writes out the record and the branch (unconditional) loops. The loop terminates when an end of file is reached at which time control is passed to the label ATEND and the file is closed and the program terminates.

    The input file INPUT.DAT looks like:

    123456789012345678901234567890
    test 1 .......................
    test 2 .......................
    test 3 .......................
    

    Note that each line is exactly 30 bytes long. However, 32 bytes are actually read. This is because, on a Windows PC, carriage-return and line-feed (CR/LF) are appended to the end of every line. This will be obvious when you write the records. Each will have a blank line after it because of the CR/LF in the record and because the WTO also writes a CRLF after each record it prints.


             PRINT NOGEN
             START 0
             REGS
    BEGIN    BEGIN
             OI    INDCB+10,X'08'     convert ASCII to EBCDIC
             OPEN  INDCB
    LOOP     GET   INDCB,REC          read a record
             WTO   REC                write the record
             B     LOOP               loop
    *
    *        EOJ processing
    *
    
    ATEND    CLOSE INDCB
             RETURN
    *
    *        Literals
    *
             LTORG
    *
    *        File DCB's
    *
    
    INDCB    DCB   LRECL=32,RECFM=F,MACRF=G,EODAD=ATEND,
                   DDNAME='INPUT.DAT'
    
    *
    *        input record
    *
    
    REC      DS    CL32
             END   BEGIN
    
    
    
    C:\asmdisk\min>asm IOEX1
    
    C:\asmdisk\min>del report.txt
    Could Not Find C:\asmdisk\min\report.txt
    
    C:\asmdisk\min>m370 IOEX1
    
    C:\asmdisk\min>a370 IOEX1/lx
     ***********************************************
     *    PC/370 System Release 4.2    01/07/88    *
     *    Copyright (C) 1988 Donald S. Higgins     *
     *                                             *
     * You are encouraged to copy and share this   *
     * package with other users on the condition   *
     * the package is not distributed in modified  *
     * form, and that no fee is charged.  If you   *
     * find PC/370 useful, send 45 dollars to the  *
     * address below to become registered user and *
     * support continued shareware development.    *
     * Registered users will receive notices of    *
     * future PC/370 releases.                     *
     *                                             *
     *      Don Higgins                            *
     *      6365 - 32 Avenue, North                *
     *      St. Petersburg, Florida 33710          *
     ***********************************************
    PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
    STATS SYM=00025  MAXSTD=00005  LIT=00000  MAXLTD=00000  BTMEM=51764
    NO ERRORS FOUND
    
    C:\asmdisk\min>l370 IOEX1/lx
     ***********************************************
     *    PC/370 System Release 4.2    01/07/88    *
     *    Copyright (C) 1988 Donald S. Higgins     *
     *                                             *
     * You are encouraged to copy and share this   *
     * package with other users on the condition   *
     * the package is not distributed in modified  *
     * form, and that no fee is charged.  If you   *
     * find PC/370 useful, send 45 dollars to the  *
     * address below to become registered user and *
     * support continued shareware development.    *
     * Registered users will receive notices of    *
     * future PC/370 releases.                     *
     *                                             *
     *      Don Higgins                            *
     *      6365 - 32 Avenue, North                *
     *      St. Petersburg, Florida 33710          *
     ***********************************************
    PC/370 LINKAGE EDITOR  OPTIONS ON = LXEFIP
    STATS SYM=00002  MAXSTD=00001  BTMEM=57752
    NO ERRORS FOUND
    
    C:\asmdisk\min>IOEX1
    123456789012345678901234567890
    
    test 1 .......................
    
    test 2 .......................
    
    test 3 .......................
    
    
    C:\asmdisk\min>pause
    Press any key to continue . . .
    

    Output is handled similarly:

             PRINT NOGEN
             START 0
             REGS
    BEGIN    BEGIN
             OI    INDCB+10,X'08'     convert ASCII to EBCDIC
             OI    OUTDCB+10,X'08'    convert EBCDIC to ASCII
             OPEN  INDCB
             OPEN  OUTDCB
    LOOP     GET   INDCB,REC          read a record
             PUT   OUTDCB,REC         write the record
             B     LOOP               loop
    *
    *        EOJ processing
    *
    
    ATEND    CLOSE INDCB
             CLOSE OUTDCB
             RETURN
    *
    *        Literals
    *
             LTORG
    *
    *        File DCB's
    *
    
    INDCB    DCB   LRECL=32,RECFM=F,MACRF=G,EODAD=ATEND,
                   DDNAME='INPUT.DAT'
    OUTDCB   DCB   LRECL=32,RECFM=F,MACRF=P,DDNAME='OUT.DAT'
    
    *
    *        input record
    *
    
    REC      DS    CL32
             END   BEGIN
    

    The output file OUT.DAT is identical to the input file (PUT does not add CR/LF's)

  11. Reading and Adding a Table of Numbers.

    Arithmetic

    Arithmetic on an IBM mainframe can be carried out in binary integer mode, packed decimal mode and floating point. Flointing point is not covbered here.

    When numbers are read from character (EBCDIC) input, they are in Zoned Decimal format. For example, the number 1234 in EBCDIC appears as:

    F1 F2 F3 F4 (Hex)

    Arithmetic may not be performed on these character representations of numbers. Instead, they must be converted to one of the numeric types, such as Packed Decimal or Integer (binary).

    A Packed Decimal is a string of bytes containing in each half byte a value (in bits) from 0 to 9 except for the last half byte. The last half byte contains the sign of the number. The hex codes C,A,F, and E mean the number is positive and the codes D and B mean its negative. Thus, the above Zoned Decimal number, in packed format would be:

    01 23 4F (Hex)

    In this format, it can be seen that the zones have been eliminated and a sign appended.

    Packed Decimal numbers can occupy up to 16 bytes and thus can represent numbers up to 31 digits in length. Packed Decimal is especially useful for business applications where many digits of accuracy are required. Packed Decimal operations do not involved round-off errors that are common with floating point numbers.

    Use the PACK instruction to convert a positive Zoned Decimal number to Packed Decimal. The PACK instruction removes the zones and packs the numerics except for the last byte where the zone and numeric are swapped. Since the zone of a text number is F, all numbers appear to be positive (sign of F). To change the sign, modify the numeric field of the last bytes with something like a MVN (Move Numerics). The PACK instruction packs into the first operand from the second. Each operand may be up to 16 bytes in length.

    Once a number is in packed format, you may do arithmetic on it. While packed (called decimal) arithmetic is slower thatn binary arithmetic, it can handle more digits of accuracy and it does not need any further conversion. To read in a number and convert it to binary, you first must pack the number (PACK is very fast), then perform a CVB (convert to binary) which converts the packed number to binary leaving the result in a register. The CVB is non-trivial. For many commercial transactions where a record is read and updated (by adding or subtracting) then written back to disk, packed arithmetic is faster and more flexible.

    The most simple packed instructions are AP (Add Packed), SP (Subtract Packed), and CP (Compared Packed). The following illustrates reading in a table of numbers, packing them and adding them to a sum.

             PRINT NOGEN
             START 0
             REGS
    BEGIN    BEGIN
             OI    INDCB+10,X'08'     convert ASCII to EBCDIC
             OPEN  INDCB
    LOOP     GET   INDCB,REC          read a record
             WTO   REC1               write the record
             PACK  NBR,REC1
             AP    SUM,NBR
             B     LOOP               loop
    *
    *        EOJ processing
    *
    
    ATEND    CLOSE INDCB
             WTO   MSG
             ED    RSLT,SUM
             WTO   RSLT
             RETURN
    *
    *        Literals
    *
             LTORG
    *
    *        File DCB's
    *
    
    INDCB    DCB   LRECL=10,RECFM=F,MACRF=G,EODAD=ATEND,
                   DDNAME='INPUT1.DAT'
    
    *
    *        input record
    *
    
    REC1     DS    0CL8   dummy overlapping short record
    REC      DS    CL10   actual input record
    NBR      DS    PL8
    SUM      DC    PL4'0'
    RSLT     DC    X'4020202020202120'
    MSG      DC    C'DONE***************'
             END   BEGIN
    

    Listing file for the above (.PRN):

      ADDEX1                                             PAGE    1
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
     000000                               1          PRINT    NOGEN
     000000                               2          START    0
     000000                               3 *+++++++ REGS
     000000              00000000         4 R0       EQU      0
     000000              00000001         5 R1       EQU      1
     000000              00000002         6 R2       EQU      2
     000000              00000003         7 R3       EQU      3
     000000              00000004         8 R4       EQU      4
     000000              00000005         9 R5       EQU      5
     000000              00000006        10 R6       EQU      6
     000000              00000007        11 R7       EQU      7
     000000              00000008        12 R8       EQU      8
     000000              00000009        13 R9       EQU      9
     000000              0000000A        14 R10      EQU      10
     000000              0000000B        15 R11      EQU      11
     000000              0000000C        16 R12      EQU      12
     000000              0000000D        17 R13      EQU      13
     000000              0000000E        18 R14      EQU      14
     000000              0000000F        19 R15      EQU      15
     000000                              20 *++++    BEGIN
     000000                              21 BEGIN    CSECT
     000000                              22          USING    *,15
     000000 47F0F058              0058   23          B        KZHQX002
     000004 0B                           24          DC       AL1(11)
     000005 C2C5C7C9D5404040             25          DC       CL11'BEGIN   '
     000010 0000000000000000             26 HZQKX002 DC       18F'0'
     000058 90ECD00C              000C   27 KZHQX002 STM      14,12,12(13)
     00005C 50D0F014              0014   28          ST       13,HZQKX002+4
     000060 18ED                         29          LR       14,13
     000062 41D0F010              0010   30          LA       13,HZQKX002
     000066 50D0E008              0008   31          ST       13,8(0,14)
     00006A                              32          DROP     15
     00006A                              33          USING    HZQKX002,13
     00006A 9608D0DA              00EA   34          OI       INDCB+10,X'08'     convert ASCII to EBCDIC
     00006E                              35 *+++++++ OPEN  INDCB
     00006E 4120D0D0              00E0   36          LA       2,INDCB
     000072 0A01                         37          SVC      1
     000074                              38 *+++     GET   INDCB,REC          read a record
     000074              00000074        39 LOOP     EQU      *
     000074 4120D0D0              00E0   40          LA       2,INDCB
     000078 4110D131              0141   41          LA       1,REC
     00007C 0A05                         42          SVC      5
     00007E                              43 *+++++++ WTO   REC1               write the record
     00007E 4300D139              0149   44          IC       0,REC1+L'REC1
     000082 925BD139              0149   45          MVI      REC1+L'REC1,C'$'
     000086 4120D131              0141   46          LA       2,REC1
     00008A 0AD1                         47          SVC      209
     00008C 4200D139              0149   48          STC      0,REC1+L'REC1
     000090 F277D13BD131   014B   0141   49          PACK     NBR,REC1
     000096 FA37D143D13B   0153   014B   50          AP       SUM,NBR
     00009C 47F0D064              0074   51          B        LOOP               loop
    . ADDEX1                                             PAGE    2
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
     0000A0                              52 *
     0000A0                              53 *        EOJ processing
     0000A0                              54 *
     0000A0                              55
     0000A0                              56 *++++    CLOSE INDCB
     0000A0              000000A0        57 ATEND    EQU      *
     0000A0 4120D0D0              00E0   58          LA       2,INDCB
     0000A4 0A02                         59          SVC      2
     0000A6                              60 *+++     WTO   MSG
     0000A6 4300D162              0172   61          IC       0,MSG+L'MSG
     0000AA 925BD162              0172   62          MVI      MSG+L'MSG,C'$'
     0000AE 4120D14F              015F   63          LA       2,MSG
     0000B2 0AD1                         64          SVC      209
     0000B4 4200D162              0172   65          STC      0,MSG+L'MSG
     0000B8 DE07D147D143   0157   0153   66          ED       RSLT,SUM
     0000BE                              67 *+++++++ WTO   RSLT
     0000BE 4300D14F              015F   68          IC       0,RSLT+L'RSLT
     0000C2 925BD14F              015F   69          MVI      RSLT+L'RSLT,C'$'
     0000C6 4120D147              0157   70          LA       2,RSLT
     0000CA 0AD1                         71          SVC      209
     0000CC 4200D14F              015F   72          STC      0,RSLT+L'RSLT
     0000D0                              73 *+++++++ RETURN
     0000D0 58DD0004              0004   74          L        13,4(13)
     0000D4 98ECD00C              000C   75          LM       14,12,12(13)
     0000D8 07FE                         76          BR       14
     0000DA                              77 *
     0000DA                              78 *        Literals
     0000DA                              79 *
     0000E0                              80          LTORG
     0000E0                              81 *
     0000E0                              82 *        File DCB's
     0000E0                              83 *
     0000E0                              84
     0000E0                              85 *++++    DCB   LRECL=10,RECFM=F,MACRF=G,EODAD=ATEND,
     0000E0                              86 *+++++++LABEL$ DDNAME='INPUT1.DAT'
     0000E0                              87 INDCB    DS       0F,0CL86
     0000E0 C1C4C3C2                     88          DC       C'ADCB'
     0000E4 00000136                     89          DC       A(DCBDD010)
     0000E8 FFFF00                       90          DC       X'FFFF',X'00'
     0000EB E2C7C6                       91          DC       CL1'S',CL1'G',CL1'F'
     0000EE 0A1A                         92          DC       X'0A1A'
     0000F0 000A0000                     93          DC       H'10',H'0'
     0000F4 000000A0000000A0             94          DC       A(ATEND,ATEND,0)
     000100 0000000000000000             95          DC       54X'00'
     000136 C9D5D7E4E3F14BC4             96 DCBDD010 DC       C'INPUT1.DAT',X'00'
     000141                              97
     000141                              98 *
     000141                              99 *        input record
     000141                             100 *
     000141                             101
     000141                             102 REC1     DS       0CL8   dummy overlapping short record
    . ADDEX1                                             PAGE    3
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
     000141                             103 REC      DS       CL10   actual input record
     00014B                             104 NBR      DS       PL8
     000153 0000000C                    105 SUM      DC       PL4'0'
     000157 4020202020202120            106 RSLT     DC       X'4020202020202120'
     00015F C4D6D5C55C5C5C5C            107 MSG      DC       C'DONE***************'
     000000                             108          END      BEGIN
    . ADDEX1                                             PAGE    4
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
    
      SYMBOL   VALUE    LENGTH  TYPE ID DEF#  XREF#
    
      $$CSECT  00000000 00000000 CST 01 00002
      ATEND    000000A0 00000001 REL 02 00057 00094 00094 00094 00094
      BEGIN    00000000 00000172 CST 02 00021 00108
      DCBDD010 00000136 0000000A REL 02 00096 00089
      HZQKX002 00000010 00000004 REL 02 00026 00033 00030 00028
      INDCB    000000E0 00000004 REL 02 00087 00058 00040 00036 00034
      KZHQX002 00000058 00000004 REL 02 00027 00023
      LOOP     00000074 00000001 REL 02 00039 00051
      MSG      0000015F 00000013 REL 02 00107 00065 00065 00063 00062 00062
                                              00061 00061
      NBR      0000014B 00000008 REL 02 00104 00050 00049
      R0       00000000 00000001 ABS 00 00004
      R1       00000001 00000001 ABS 00 00005
      R10      0000000A 00000001 ABS 00 00014
      R11      0000000B 00000001 ABS 00 00015
      R12      0000000C 00000001 ABS 00 00016
      R13      0000000D 00000001 ABS 00 00017
      R14      0000000E 00000001 ABS 00 00018
      R15      0000000F 00000001 ABS 00 00019
      R2       00000002 00000001 ABS 00 00006
      R3       00000003 00000001 ABS 00 00007
      R4       00000004 00000001 ABS 00 00008
      R5       00000005 00000001 ABS 00 00009
      R6       00000006 00000001 ABS 00 00010
      R7       00000007 00000001 ABS 00 00011
      R8       00000008 00000001 ABS 00 00012
      R9       00000009 00000001 ABS 00 00013
      REC      00000141 0000000A REL 02 00103 00041
      REC1     00000141 00000008 REL 02 00102 00049 00048 00048 00046 00045
                                              00045 00044 00044
      RSLT     00000157 00000008 REL 02 00106 00072 00072 00070 00069 00069
                                              00068 00068 00066
      SUM      00000153 00000004 REL 02 00105 00066 00050
    . ADDEX1                                             PAGE    5
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
    
      RELOCATION LISTING
      SEG ADDRESS LENGTH SIGN RLD SEG
    
      02 000000E4  4      +    02
      02 000000F4  4      +    02
      02 000000F8  4      +    02
     LITERAL CROSS REFERENCE
    

    Data file for the above (INPUT1.DAT):

    00000010
    00000020
    00000030
    00000040
    

    Execution for the above:

    C:\asmdisk\min>asm addex1
    
    C:\asmdisk\min>del report.txt
    Could Not Find C:\asmdisk\min\report.txt
    
    C:\asmdisk\min>m370 addex1
    
    C:\asmdisk\min>a370 addex1/lx
     ***********************************************
     *    PC/370 System Release 4.2    01/07/88    *
     *    Copyright (C) 1988 Donald S. Higgins     *
     *                                             *
     * You are encouraged to copy and share this   *
     * package with other users on the condition   *
     * the package is not distributed in modified  *
     * form, and that no fee is charged.  If you   *
     * find PC/370 useful, send 45 dollars to the  *
     * address below to become registered user and *
     * support continued shareware development.    *
     * Registered users will receive notices of    *
     * future PC/370 releases.                     *
     *                                             *
     *      Don Higgins                            *
     *      6365 - 32 Avenue, North                *
     *      St. Petersburg, Florida 33710          *
     ***********************************************
    PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
    STATS SYM=00030  MAXSTD=00005  LIT=00000  MAXLTD=00000  BTMEM=51604
    NO ERRORS FOUND
    
    C:\asmdisk\min>l370 addex1/lx
     ***********************************************
     *    PC/370 System Release 4.2    01/07/88    *
     *    Copyright (C) 1988 Donald S. Higgins     *
     *                                             *
     * You are encouraged to copy and share this   *
     * package with other users on the condition   *
     * the package is not distributed in modified  *
     * form, and that no fee is charged.  If you   *
     * find PC/370 useful, send 45 dollars to the  *
     * address below to become registered user and *
     * support continued shareware development.    *
     * Registered users will receive notices of    *
     * future PC/370 releases.                     *
     *                                             *
     *      Don Higgins                            *
     *      6365 - 32 Avenue, North                *
     *      St. Petersburg, Florida 33710          *
     ***********************************************
    PC/370 LINKAGE EDITOR  OPTIONS ON = LXEFIP
    STATS SYM=00002  MAXSTD=00001  BTMEM=57752
    NO ERRORS FOUND
    
    C:\asmdisk\min>addex1
    00000010
    00000020
    00000030
    00000040
    DONE***************
         100
    
    C:\asmdisk\min>pause
    Press any key to continue . . .
    

  12. Now handle negative numbers

             PRINT NOGEN
             START 0
             REGS
    BEGIN    BEGIN
             OI    INDCB+10,X'08'     convert ASCII to EBCDIC
             OPEN  INDCB
    
    LOOP     GET   INDCB,REC          read a record
             WTO   REC1               write the record
    
             LA    R3,REC
             MVI   NEGFLG,C'0'        make flag 0
    
    L1       CLI   0(R3),C'-'         minus sign found?
             BE    MINUS
    
             CLI   0(R3),C'+'         plus sign found
             BE    PLUS
    
             CLI   0(R3),C' '         blank found
             BE    BLANK
    
             CLI   0(R3),C'0'         0 or greater found?
             BNL   NUM
    
    ERR      WTO   ERRMSG             must be bad data
             RETURN
    
    MINUS    MVI   NEGFLG,C'1'        set flag to 1
             MVI   0(R3),C' '         make - a blank
             B     PCK
    
    PLUS     MVI   0(R3),C' '         make + a blank
             B     PCK
    
    NUM      CLI   0(R3),C'9'         9 or less?
             BH    ERR                must be bad data
    
    BLANK    LA    R3,1(R0,R3)        increment pointer
             LA    R4,REC+8           get address of end
             CR    R3,R4              compare pointers
             BL    L1                 loop if not done
    
    PCK      PACK  NBR,REC1
             CLI   NEGFLG,C'1'        is this number neg
             BNE   ADD                no
             NI    NBR+7,X'FD'        yes - make its sign D - CORRECTED
    ADD      AP    SUM,NBR
             B     LOOP               loop
    *
    *        EOJ processing
    *
    
    ATEND    CLOSE INDCB
             WTO   MSG
             ED    RSLT,SUM
             WTO   RSLT
             RETURN
    *
    *        Literals
    *
             LTORG
    *
    *        File DCB's
    *
    
    INDCB    DCB   LRECL=10,RECFM=F,MACRF=G,EODAD=ATEND,
                   DDNAME='INPUT2.DAT'
    
    *
    *        input record
    *
    
    REC1     DS    0CL8   dummy overlapping short record
    REC      DS    CL10   actual input record
    NBR      DS    PL8
    NEGFLG   DC    C'0'
    SUM      DC    PL4'0'
    RSLT     DC    X'4020202020202120'
    MSG      DC    C'DONE***************'
    ERRMSG   DC    C'ERROR - BAD DATA'
             END   BEGIN
    

    The PRN file is:

      ADDEX2                                             PAGE    1
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
     000000                               1          PRINT    NOGEN
     000000                               2          START    0
     000000                               3 *+++++++ REGS
     000000              00000000         4 R0       EQU      0
     000000              00000001         5 R1       EQU      1
     000000              00000002         6 R2       EQU      2
     000000              00000003         7 R3       EQU      3
     000000              00000004         8 R4       EQU      4
     000000              00000005         9 R5       EQU      5
     000000              00000006        10 R6       EQU      6
     000000              00000007        11 R7       EQU      7
     000000              00000008        12 R8       EQU      8
     000000              00000009        13 R9       EQU      9
     000000              0000000A        14 R10      EQU      10
     000000              0000000B        15 R11      EQU      11
     000000              0000000C        16 R12      EQU      12
     000000              0000000D        17 R13      EQU      13
     000000              0000000E        18 R14      EQU      14
     000000              0000000F        19 R15      EQU      15
     000000                              20 *++++    BEGIN
     000000                              21 BEGIN    CSECT
     000000                              22          USING    *,15
     000000 47F0F058              0058   23          B        KZHQX002
     000004 0B                           24          DC       AL1(11)
     000005 C2C5C7C9D5404040             25          DC       CL11'BEGIN   '
     000010 0000000000000000             26 HZQKX002 DC       18F'0'
     000058 90ECD00C              000C   27 KZHQX002 STM      14,12,12(13)
     00005C 50D0F014              0014   28          ST       13,HZQKX002+4
     000060 18ED                         29          LR       14,13
     000062 41D0F010              0010   30          LA       13,HZQKX002
     000066 50D0E008              0008   31          ST       13,8(0,14)
     00006A                              32          DROP     15
     00006A                              33          USING    HZQKX002,13
     00006A 9608D152              0162   34          OI       INDCB+10,X'08'     convert ASCII to EBCDIC
     00006E                              35 *+++++++ OPEN  INDCB
     00006E 4120D148              0158   36          LA       2,INDCB
     000072 0A01                         37          SVC      1
     000074                              38
     000074                              39 *+++     GET   INDCB,REC          read a record
     000074              00000074        40 LOOP     EQU      *
     000074 4120D148              0158   41          LA       2,INDCB
     000078 4110D1A9              01B9   42          LA       1,REC
     00007C 0A05                         43          SVC      5
     00007E                              44 *+++++++ WTO   REC1               write the record
     00007E 4300D1B1              01C1   45          IC       0,REC1+L'REC1
     000082 925BD1B1              01C1   46          MVI      REC1+L'REC1,C'$'
     000086 4120D1A9              01B9   47          LA       2,REC1
     00008A 0AD1                         48          SVC      209
     00008C 4200D1B1              01C1   49          STC      0,REC1+L'REC1
     000090                              50
     000090 4130D1A9              01B9   51          LA       R3,REC
    . ADDEX2                                             PAGE    2
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
     000094 92F0D1BB              01CB   52          MVI      NEGFLG,C'0'        make flag 0
     000098                              53
     000098 95603000              0000   54 L1       CLI      0(R3),C'-'         minus sign found?
     00009C 4780D0C4              00D4   55          BE       MINUS
     0000A0                              56
     0000A0 954E3000              0000   57          CLI      0(R3),C'+'         plus sign found
     0000A4 4780D0D0              00E0   58          BE       PLUS
     0000A8                              59
     0000A8 95403000              0000   60          CLI      0(R3),C' '         blank found
     0000AC 4780D0E0              00F0   61          BE       BLANK
     0000B0                              62
     0000B0 95F03000              0000   63          CLI      0(R3),C'0'         0 or greater found?
     0000B4 47B0D0D8              00E8   64          BNL      NUM
     0000B8                              65
     0000B8                              66 *++      WTO   ERRMSG             must be bad data
     0000B8 4300D1EB              01FB   67 ERR      IC       0,ERRMSG+L'ERRMSG
     0000BC 925BD1EB              01FB   68          MVI      ERRMSG+L'ERRMSG,C'$'
     0000C0 4120D1DB              01EB   69          LA       2,ERRMSG
     0000C4 0AD1                         70          SVC      209
     0000C6 4200D1EB              01FB   71          STC      0,ERRMSG+L'ERRMSG
     0000CA                              72 *+++++++ RETURN
     0000CA 58DD0004              0004   73          L        13,4(13)
     0000CE 98ECD00C              000C   74          LM       14,12,12(13)
     0000D2 07FE                         75          BR       14
     0000D4                              76
     0000D4 92F1D1BB              01CB   77 MINUS    MVI      NEGFLG,C'1'        set flag to 1
     0000D8 92403000              0000   78          MVI      0(R3),C' '         make - a blank
     0000DC 47F0D0EE              00FE   79          B        PCK
     0000E0                              80
     0000E0 92403000              0000   81 PLUS     MVI      0(R3),C' '         make + a blank
     0000E4 47F0D0EE              00FE   82          B        PCK
     0000E8                              83
     0000E8 95F93000              0000   84 NUM      CLI      0(R3),C'9'         9 or less?
     0000EC 4720D0A8              00B8   85          BH       ERR                must be bad data
     0000F0                              86
     0000F0 41303001              0001   87 BLANK    LA       R3,1(R0,R3)        increment pointer
     0000F4 4140D1B1              01C1   88          LA       R4,REC+8           get address of end
     0000F8 1934                         89          CR       R3,R4              compare pointers
     0000FA 4740D088              0098   90          BL       L1                 loop if not done
     0000FE                              91
     0000FE F277D1B3D1A9   01C3   01B9   92 PCK      PACK     NBR,REC1
     000104 95F1D1BB              01CB   93          CLI      NEGFLG,C'1'        is this number neg
     000108 4770D100              0110   94          BNE      ADD                no
     00010C 94FDD1BA              01CA   95          NI       NBR+7,X'FD'        yes - make its sign D
     000110 FA37D1BCD1B3   01CC   01C3   96 ADD      AP       SUM,NBR
     000116 47F0D064              0074   97          B        LOOP               loop
     00011A                              98 *
     00011A                              99 *        EOJ processing
     00011A                             100 *
     00011A                             101
     00011A                             102 *++++    CLOSE INDCB
    . ADDEX2                                             PAGE    3
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
     00011A              0000011A       103 ATEND    EQU      *
     00011A 4120D148              0158  104          LA       2,INDCB
     00011E 0A02                        105          SVC      2
     000120                             106 *+++     WTO   MSG
     000120 4300D1DB              01EB  107          IC       0,MSG+L'MSG
     000124 925BD1DB              01EB  108          MVI      MSG+L'MSG,C'$'
     000128 4120D1C8              01D8  109          LA       2,MSG
     00012C 0AD1                        110          SVC      209
     00012E 4200D1DB              01EB  111          STC      0,MSG+L'MSG
     000132 DE07D1C0D1BC   01D0   01CC  112          ED       RSLT,SUM
     000138                             113 *+++++++ WTO   RSLT
     000138 4300D1C8              01D8  114          IC       0,RSLT+L'RSLT
     00013C 925BD1C8              01D8  115          MVI      RSLT+L'RSLT,C'$'
     000140 4120D1C0              01D0  116          LA       2,RSLT
     000144 0AD1                        117          SVC      209
     000146 4200D1C8              01D8  118          STC      0,RSLT+L'RSLT
     00014A                             119 *+++++++ RETURN
     00014A 58DD0004              0004  120          L        13,4(13)
     00014E 98ECD00C              000C  121          LM       14,12,12(13)
     000152 07FE                        122          BR       14
     000154                             123 *
     000154                             124 *        Literals
     000154                             125 *
     000158                             126          LTORG
     000158                             127 *
     000158                             128 *        File DCB's
     000158                             129 *
     000158                             130
     000158                             131 *++++    DCB   LRECL=10,RECFM=F,MACRF=G,EODAD=ATEND,
     000158                             132 *+++++++LABEL$ DDNAME='INPUT2.DAT'
     000158                             133 INDCB    DS       0F,0CL86
     000158 C1C4C3C2                    134          DC       C'ADCB'
     00015C 000001AE                    135          DC       A(DCBDD012)
     000160 FFFF00                      136          DC       X'FFFF',X'00'
     000163 E2C7C6                      137          DC       CL1'S',CL1'G',CL1'F'
     000166 0A1A                        138          DC       X'0A1A'
     000168 000A0000                    139          DC       H'10',H'0'
     00016C 0000011A0000011A            140          DC       A(ATEND,ATEND,0)
     000178 0000000000000000            141          DC       54X'00'
     0001AE C9D5D7E4E3F24BC4            142 DCBDD012 DC       C'INPUT2.DAT',X'00'
     0001B9                             143
     0001B9                             144 *
     0001B9                             145 *        input record
     0001B9                             146 *
     0001B9                             147
     0001B9                             148 REC1     DS       0CL8   dummy overlapping short record
     0001B9                             149 REC      DS       CL10   actual input record
     0001C3                             150 NBR      DS       PL8
     0001CB F0                          151 NEGFLG   DC       C'0'
     0001CC 0000000C                    152 SUM      DC       PL4'0'
     0001D0 4020202020202120            153 RSLT     DC       X'4020202020202120'
    . ADDEX2                                             PAGE    4
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
     0001D8 C4D6D5C55C5C5C5C            154 MSG      DC       C'DONE***************'
     0001EB C5D9D9D6D9406040            155 ERRMSG   DC       C'ERROR - BAD DATA'
     000000                             156          END      BEGIN
    . ADDEX2                                             PAGE    5
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
    
      SYMBOL   VALUE    LENGTH  TYPE ID DEF#  XREF#
    
      $$CSECT  00000000 00000000 CST 01 00002
      ADD      00000110 00000006 REL 02 00096 00094
      ATEND    0000011A 00000001 REL 02 00103 00140 00140 00140 00140
      BEGIN    00000000 000001FB CST 02 00021 00156
      BLANK    000000F0 00000004 REL 02 00087 00061
      DCBDD012 000001AE 0000000A REL 02 00142 00135
      ERR      000000B8 00000004 REL 02 00067 00085
      ERRMSG   000001EB 00000010 REL 02 00155 00071 00071 00069 00068 00068
                                              00067 00067
      HZQKX002 00000010 00000004 REL 02 00026 00033 00030 00028
      INDCB    00000158 00000004 REL 02 00133 00104 00041 00036 00034
      KZHQX002 00000058 00000004 REL 02 00027 00023
      L1       00000098 00000004 REL 02 00054 00090
      LOOP     00000074 00000001 REL 02 00040 00097
      MINUS    000000D4 00000004 REL 02 00077 00055
      MSG      000001D8 00000013 REL 02 00154 00111 00111 00109 00108 00108
                                              00107 00107
      NBR      000001C3 00000008 REL 02 00150 00096 00095 00092
      NEGFLG   000001CB 00000001 REL 02 00151 00093 00077 00052
      NUM      000000E8 00000004 REL 02 00084 00064
      PCK      000000FE 00000006 REL 02 00092 00082 00079
      PLUS     000000E0 00000004 REL 02 00081 00058
      R0       00000000 00000001 ABS 00 00004 00087
      R1       00000001 00000001 ABS 00 00005
      R10      0000000A 00000001 ABS 00 00014
      R11      0000000B 00000001 ABS 00 00015
      R12      0000000C 00000001 ABS 00 00016
      R13      0000000D 00000001 ABS 00 00017
      R14      0000000E 00000001 ABS 00 00018
      R15      0000000F 00000001 ABS 00 00019
      R2       00000002 00000001 ABS 00 00006
      R3       00000003 00000001 ABS 00 00007 00089 00087 00087 00084 00081
                                              00078 00063 00060 00057 00054
                                              00051 00087 00051
      R4       00000004 00000001 ABS 00 00008 00089 00088 00088
      R5       00000005 00000001 ABS 00 00009
      R6       00000006 00000001 ABS 00 00010
      R7       00000007 00000001 ABS 00 00011
      R8       00000008 00000001 ABS 00 00012
      R9       00000009 00000001 ABS 00 00013
      REC      000001B9 0000000A REL 02 00149 00088 00051 00042
      REC1     000001B9 00000008 REL 02 00148 00092 00049 00049 00047 00046
                                              00046 00045 00045
      RSLT     000001D0 00000008 REL 02 00153 00118 00118 00116 00115 00115
                                              00114 00114 00112
      SUM      000001CC 00000004 REL 02 00152 00112 00096
    . ADDEX2                                             PAGE    6
     PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
        LOC                ADR1   ADR2 LINE LABEL    OP       OPERANDS
    
      RELOCATION LISTING
      SEG ADDRESS LENGTH SIGN RLD SEG
    
      02 0000015C  4      +    02
      02 0000016C  4      +    02
      02 00000170  4      +    02
     LITERAL CROSS REFERENCE
    

    The input data is:

    C:\asmdisk\min>type input2.dat
          10
         -20
         +30
          40
    

    The execution is:

    C:\asmdisk\min>asm addex2
    
    C:\asmdisk\min>del report.txt
    Could Not Find C:\asmdisk\min\report.txt
    
    C:\asmdisk\min>m370 addex2
    
    C:\asmdisk\min>a370 addex2/lx
     ***********************************************
     *    PC/370 System Release 4.2    01/07/88    *
     *    Copyright (C) 1988 Donald S. Higgins     *
     *                                             *
     * You are encouraged to copy and share this   *
     * package with other users on the condition   *
     * the package is not distributed in modified  *
     * form, and that no fee is charged.  If you   *
     * find PC/370 useful, send 45 dollars to the  *
     * address below to become registered user and *
     * support continued shareware development.    *
     * Registered users will receive notices of    *
     * future PC/370 releases.                     *
     *                                             *
     *      Don Higgins                            *
     *      6365 - 32 Avenue, North                *
     *      St. Petersburg, Florida 33710          *
     ***********************************************
    PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
    STATS SYM=00040  MAXSTD=00005  LIT=00000  MAXLTD=00000  BTMEM=51272
    NO ERRORS FOUND
    
    C:\asmdisk\min>l370 addex2/lx
     ***********************************************
     *    PC/370 System Release 4.2    01/07/88    *
     *    Copyright (C) 1988 Donald S. Higgins     *
     *                                             *
     * You are encouraged to copy and share this   *
     * package with other users on the condition   *
     * the package is not distributed in modified  *
     * form, and that no fee is charged.  If you   *
     * find PC/370 useful, send 45 dollars to the  *
     * address below to become registered user and *
     * support continued shareware development.    *
     * Registered users will receive notices of    *
     * future PC/370 releases.                     *
     *                                             *
     *      Don Higgins                            *
     *      6365 - 32 Avenue, North                *
     *      St. Petersburg, Florida 33710          *
     ***********************************************
    PC/370 LINKAGE EDITOR  OPTIONS ON = LXEFIP
    STATS SYM=00002  MAXSTD=00001  BTMEM=57752
    NO ERRORS FOUND
    
    C:\asmdisk\min>addex2
          10
         -20
         +30
          40
    DONE***************
          60
    
    C:\asmdisk\min>pause
    Press any key to continue . . .
    

    Notes: The above scans the input looking for blanks, numbers and either a plus or minus sign. If it detects a minus sign, it sets a flag. Plus and minus signs are replaced by blanks (Hex 40). After the number has been packed, it checks the flag. If the flag is true - a minus sign was found - it performs and AND-IMMEDIATE (NI) on the last byte of the packed number. The packed number, after the PACK instruction is positive due to the zone on the final numeric character (Hex F) becomming the digit portion of the final byte (PACK reverses the zone and digit in the last byte of the packed field). By AND'ing Hex FD with this byte, the zone portion is retained and the digit portion becomes Hex D.

  13. Translate and Test

    Scanning input fields is important so the architecture provided for a single instruction to do this, the TRT (Translate and Test) instruction. The TRT uses a table (second operand) and a string (first operand). Bytes in the string are successively (left to right) used to index into the table. The table is 256 bytes long. The byte found in the table determines what should happen:

    1. If the byte in the table is zero, the operation continues.
    2. If the byte in the table is non-zero, the operation terminates and the byte from the table is placed in the low order byte of R2 and the address of the byte from the source string causing the halt is places in R1.
    3. If all tested bytes are zero, the condition code becomes zero. If a tested byte is non-zero, the condition code becomes 1 if the bytes from the source string was not the final byte of the source string and 2 if the source string byte was the final byte of the source string.
    4. The source string is not altered.

    Building a TRT table to halt on non-numeric and non-blanks:

    TAB      DC    256X'01'
             ORG   TAB+C' '
             DC    X'00'
             ORG   TAB+C'0'
             DC    10X'00'
             ORG
    

    In the above, first you build a table of 256 bytes all initialized to X01 (these bytes, since they are not zero, will halt the TRT), Then, you back into the table and replace the byte correcponding to the offset of blank (X40) with X00 and move again to the offset associated with a character zero (XF0) and replace it and the next nine bytes with X00. The ORG directive resets the location counted to the value specified. An ORG with no argument resets the location counter to the highes value it has ever held.

    The effect of the above is to create a table mainly of X01 codes except in the offset positions for blank and the character versions of the numbers from zero to nine, inclusive.

    Doing th above add example with a TRT:

             PRINT NOGEN
             START 0
             REGS
    BEGIN    BEGIN
             OI    INDCB+10,X'08'     convert ASCII to EBCDIC
             OPEN  INDCB
    
    LOOP     GET   INDCB,REC          read a record
             WTO   REC1               write the record
             MVI   NEGFLG,C'0'        set flag to 0
    
             TRT   REC1,TAB
             BE    PCK                only blanks and numbers
    
             CLI   0(R1),C'-'         minus sign found?
             BNE   PLUS
             MVI   NEGFLG,C'1'        set flag to 1
             MVI   0(R1),C' '         make - a blank
             B     PCK
    
    PLUS     CLI   0(R1),C'+'         plus sign found
             BNE   PCK
             MVI   0(R1),C' '         make + a blank
             B     PCK
    
    ERR      WTO   ERRMSG             must be bad data
             RETURN
    
    
    PCK      PACK  NBR,REC1
             CLI   NEGFLG,C'1'        is this number neg
             BNE   ADD                no
    
             NI    NBR+7,X'FB'        yes - make its sign D
    
    ADD      AP    SUM,NBR
             B     LOOP               loop
    *
    *        EOJ processing
    *
    
    ATEND    CLOSE INDCB
             WTO   MSG
             MVC   RSLT,=X'4020202020202120'
             ED    RSLT,SUM
             WTO   RSLT
             RETURN
    *
    *        Literals
    *
             LTORG
    *
    *        File DCB's
    *
    
    INDCB    DCB   LRECL=10,RECFM=F,MACRF=G,EODAD=ATEND,
                   DDNAME='INPUT2.DAT'
    
    *
    *        input record
    *
    
    REC1     DS    0CL8   dummy overlapping short record
    REC      DS    CL10   actual input record
    NBR      DS    PL8'0'
    NEGFLG   DC    C'0'
    SUM      DC    PL4'0'
    RSLT     DC    X'4020202020202120'
    MSG      DC    C'DONE***************'
    ERRMSG   DC    C'ERROR - BAD DATA'
    TAB      DC    256X'01'
             ORG   TAB+C'0'
             DC    10X'00'
             ORG   TAB+C' '
             DC    X'00'
             ORG
             END   BEGIN
    

    The results are the same as for the above.

  14. Scan input images for the first word.

             PRINT NOGEN
             START 0
             REGS
    
    BEGIN    BEGIN
    
             OI    INDCB+10,X'08'     convert ASCII to EBCDIC
             OPEN  INDCB
    
    LOOP     GET   INDCB,REC          read a record
             WTO   REC1               write the record
    
             LA    R3,REC1
    
             TRT   0(L'REC1,R3),TAB
             BE    EXIT               only blanks found
    
             LR    R3,R1
             LA    R5,WORD
             MVC   0(1,R5),0(R3)
    
    L1       LA    R3,1(R0,R3)
             LA    R5,1(R0,R5)
             LA    R4,REC1+30
             CR    R3,R4
             BNL   PRNT
             CLI   0(R3),C' '
             BE    PRNT
             MVC   0(1,R5),0(R3)
             B     L1
    
    PRNT     WTO   WORD
             MVI   WORD,C' '
             MVC   WORD+1(L'WORD-1),WORD
             B     LOOP
    
    *
    *        EOJ processing
    *
    
    ATEND    CLOSE INDCB
             WTO   MSG
    
    EXIT     RETURN
    *
    *        Literals
    *
             LTORG
    *
    *        File DCB's
    *
    
    INDCB    DCB   LRECL=32,RECFM=F,MACRF=G,EODAD=ATEND,
                   DDNAME='INPUT3.DAT'
    
    *
    *        input record
    *
    
    REC1     DS    0CL30   dummy overlapping short record
    REC      DS    CL32    actual input record
    WORD     DC    CL30' '
    MSG      DC    C'***** DONE *****'
    ERRMSG   DC    C'ERROR - BAD DATA'
    TAB      DC    256X'01'
             ORG   TAB+C' '
             DC    X'00'
             ORG
             END   BEGIN
    

    The input images:

           TEST1                 *
                  TEST2          *
     TEST3                       *
    

    Execution:

    C:\asmdisk\min>asm scan
    
    C:\asmdisk\min>del report.txt
    Could Not Find C:\asmdisk\min\report.txt
    
    C:\asmdisk\min>m370 scan
    
    C:\asmdisk\min>a370 scan/lx
     ***********************************************
     *    PC/370 System Release 4.2    01/07/88    *
     *    Copyright (C) 1988 Donald S. Higgins     *
     *                                             *
     * You are encouraged to copy and share this   *
     * package with other users on the condition   *
     * the package is not distributed in modified  *
     * form, and that no fee is charged.  If you   *
     * find PC/370 useful, send 45 dollars to the  *
     * address below to become registered user and *
     * support continued shareware development.    *
     * Registered users will receive notices of    *
     * future PC/370 releases.                     *
     *                                             *
     *      Don Higgins                            *
     *      6365 - 32 Avenue, North                *
     *      St. Petersburg, Florida 33710          *
     ***********************************************
    PC/370 CROSS ASSEMBLER  OPTIONS=LXACE
    STATS SYM=00033  MAXSTD=00005  LIT=00000  MAXLTD=00000  BTMEM=51472
    NO ERRORS FOUND
    
    C:\asmdisk\min>l370 scan/lx
     ***********************************************
     *    PC/370 System Release 4.2    01/07/88    *
     *    Copyright (C) 1988 Donald S. Higgins     *
     *                                             *
     * You are encouraged to copy and share this   *
     * package with other users on the condition   *
     * the package is not distributed in modified  *
     * form, and that no fee is charged.  If you   *
     * find PC/370 useful, send 45 dollars to the  *
     * address below to become registered user and *
     * support continued shareware development.    *
     * Registered users will receive notices of    *
     * future PC/370 releases.                     *
     *                                             *
     *      Don Higgins                            *
     *      6365 - 32 Avenue, North                *
     *      St. Petersburg, Florida 33710          *
     ***********************************************
    PC/370 LINKAGE EDITOR  OPTIONS ON = LXEFIP
    STATS SYM=00002  MAXSTD=00001  BTMEM=57752
    NO ERRORS FOUND
    
    C:\asmdisk\min>scan
           TEST1                 *
    TEST1
                  TEST2          *
    TEST2
     TEST3                       *
    TEST3
    ***** DONE *****
    
    C:\asmdisk\min>pause
    

  15. Initializing a table for a TR instruction

    .
    .
    .
             SR    R5,R5
             LA    R6,TAB
    
    LOOP     STC   R5,0(0,R6) * init whole TAB
             LA    R6,1(0,R6)
             LA    R5,1(0,R5)
             CL    R5,CODE
             BNH   LOOP
    
             LA    R6,TAB+C'a' * re-set beginning at a
             L     R5,AAA
    
    LOOP1    STC   R5,0(0,R6)
             LA    R5,1(0,R5)
             LA    R6,1(0,R6)
             CL    R5,AAA1
             BNH   LOOP1
    .
    .
    .
    
             DS    0F        * align to full word
    AAA      DC    X'000000' * 3 bytes of zeros
             DC    C'A'      * 1 byte contianing A
    AAA1     DC    X'000000'
             DC    C'Z'
    CODE     DC    X'000000FF'
    TAB      DS    256C
    

  16. Isolation of bits from a byte.

    A byte is 8 bits. You can isolate the high order bits of a byte by shifting the byte right by 4 thus causing loss of the low order 4 bits. You can isolate the lower 4 bits by ANDing the byte with a mask 0f B'00001111' (X'0F').

    If the byte is in memory, load it into a register using the Insert Character instruction (IC). The IC loads the byte from the address designated by the second operand into the low order 8 bits of the register designated as the first operand. The high order 24 bits of the register are unchenged. Thus, you should probably zero out the register before loading the character.

    Once the character is loaded, you may proceed to extract the 4 bit fields. These can then, as done in class, be used to index into a table to get the Hex character code equivalent. The following fragment extracts the low and high order bits, looks them up in the table and puts the character code found into an output string.

    
          .
          .
          .
    
    * Assume: R6 points to the byte in memory to be worked on.
    *         R5 points to the next available byte in the output string
    
              SR  R4,R4
              IC  R4,0(R0,R6)
              SRL R4,4
              LA  R4,TAB(R4)    * R4 becomes the index register
              MVC 0(1,R5),0(R4) * move to output
              LA  R5,1(R0,R5)
              IC  R4,0(R0,R6)
              N   R4,MASK       * zero all but lower 4 bits
              LA  R4,TAB(R4)
              MVC 0(1,R5),0(R4) * move to output
              LA  R5,1(R0,R5)
          .
          .
          .
    HEX       DC C'0123456789ABCDEF'
              DS 0F             * alignment
    MASK      DC X'0000000F'
    

    The SRL is the Shift Right Logical instrunction. The other shifts are:

    SRA   Shift Right Arithmetic
    SLL   Shift Left Logical
    SLA   Shift Left Arithmetic
    SLDL  Shift Left Double Logical
    SRDL  Shift Right Double Logical
    SLDA  Shift Left Double Arithmetic
    SRDA  Shift Right Double Arithmetic
    

    The Arithmetic shifts take into account the sign of the value. On right shifts, bits like the sign are shifted in at the hight end. On left shifts, if a bit unlike the sign bit is shifted into the sign bit position, an overflow takes place. On a lft shift, zeros are shifted into the low order positions.

    The Logical shifts treat the values as unsigned bit strings. Zeros are shifted in at the high and low ends as needed.

    The Double shifts operate of a 64 bit value formed from an even-odd pair of registers such as R2 and R3, R0 and R1, etc.