Top ten ways to shoot yourself in the foot in S/390 Assembler

To make this list, the problem must cause you to spend half a day or more going over and over your program to locate the offending bug.

  1. Modifying a base register

    Typically this happens when you are adding a new feature to an old program. You jump in and cut&paste a routine from another program and suddenly you've shot-yourself-in-the-foot. For example:
        USING csect,R12,R11,R10
        ...
        ...
        BAS   R10,do_something
        
    You'll get a S0C1, S0C4 or some other nasties.

  2. Using the wrong branching code or extended mnemonic

    Some S/390 machine instructions change the condition code and later code must act correctly based on the condition. The assembler does not have a PARM='DOWHATIMEAN'. For example, you've decided that you'd rather be testing a flag byte instead of a value byte.
    Buried somewhere in your program is:
        TM    field,value
        BE    here
        
    but you needed this code:
        TM    field,value
        BO    here
        


  3. L vs LA

    Two rules to understand:
    • Using a "L" instruction when you need the "LA" instruction will cause you untold grief.
    • Using a "LA" instruction when you need the "L" instruction will cause you untold grief.

    Thanks to Roland Schiradin for sending me the suggestion about L vs. LA.

  4. Linking a non-Reentrant program Reentrant

    You have a program that's been running for years and it starts S0C4ing out of the blue. One thing to check is if it has been linked Reentrant but doesn't follow the rules of reentrancy. This will only byte bite you if the load library is APF-authorized. Reentrant program that reside in APF authorized libraries get loaded into key zero storage. Attempts to modify key zero storage by unauthorized programs result in... a nice user-friendly S0C4.

  5. Specifing immediate character instead of literal

    There are a few machine instructions that take operands that are easily miscoded and overlooked. For example, let's say you coded CLC FLAG,C'1' when you meant CLC FLAG,=C'1'. Your program will assemble with a RC=0 but will not execute as expected.

    Looking at the generated OPCODEs, you can see the difference:
      Loc  Object Code    Addr1 Addr2  Stmt   Source Statement
    000000                00000 00011     1 MYCSECT  CSECT ,
                     R:F  00000           2          USING *,R15
                                          3 *
    000000 D500 F00C 00F1 0000C 000F1     4          CLC   FLAG,C'1'
                                          5 *
    000006 D500 F00C F010 0000C 00010     6          CLC   FLAG,=C'1'
                                          7 *
    00000C F1                             8 FLAG     DC    C'1'
                                          9 *
    000010                               10          LTORG ,
    000010 F1                            11                =C'1'
        
    I'd like to thank Gilbert Saint-flour for sending me this suggestion.

  6. Register operands on Macros may be specified incorrectly

    You may shoot-yourself-in-the-foot by assuming that the register operand you've specified on a Macro was specified correctly. Many times you will need to look at the expansion of the Macro to see if what you intended was actually used by the Macro.

    Bob Shannon sent me this example:

    This is what was intented:

              LA    R6,32                    length for obtain
              STORAGE OBTAIN,LENGTH=(6),ADDR=(7),LOC=ANY
    +         CNOP   0,4
    +         B      IHB0001B                     .BRANCH AROUND DATA
    +IHB0001F DC     BL1'00000000'                        .FLAGS        @D5C
    +         DC     AL1(0*16)                    .KEY
    +         DC     AL1(0)                       .SUBPOOL
    +         DC     BL1'00110010'                .FLAGS
    +IHB0001B DS     0F
    +         LR     0,6                          .STORAGE LENGTH
    +         L      15,IHB0001F                  .CONTROL INFORMATION
    +         L      14,16(0,0)                   .CVT ADDRESS
    +         L      14,772(14,0)                 .ADDR SYST LINKAGE TABLE
    +         L      14,160(14,0)                 .OBTAIN LX/EX FOR OBTAIN
    +         PC     0(14)                        .PC TO STORAGE RTN
    +         LR     7,1                          .SAVE ADDR OF STORAGE
        

    This STORAGE OBTAIN is incorrect and gets 6 bytes and not 32:

              LA    R6,32                    length for obtain
              STORAGE OBTAIN,LENGTH=6,ADDR=(7),LOC=ANY
    +         CNOP   0,4
    +         B      IHB0002B                     .BRANCH AROUND DATA
    +IHB0002L DC     A(6)                         .STORAGE LENGTH
    +IHB0002F DC     BL1'00000000'                        .FLAGS        @D5C
    +         DC     AL1(0*16)                    .KEY
    +         DC     AL1(0)                       .SUBPOOL
    +         DC     BL1'00110010'                .FLAGS
    +IHB0002B DS     0F
    +         L      0,IHB0002L                   .STORAGE LENGTH
    +         L      15,IHB0002F                  .CONTROL INFORMATION
    +         L      14,16(0,0)                   .CVT ADDRESS
    +         L      14,772(14,0)                 .ADDR SYST LINKAGE TABLE
    +         L      14,160(14,0)                 .OBTAIN LX/EX FOR OBTAIN
    +         PC     0(14)                        .PC TO STORAGE RTN
    +         LR     7,1                          .SAVE ADDR OF STORAGE
        
    In this case, the only way to find the error was to check the expansion of the Macro to see how it used the LENGTH= operand.

  7. Rob Scott sent me this one:
    1. Program uses R2 as a base or linkage register
    2. You add a TRT instruction to the code
    This program will function fine until the TRT returns a non-zero value (eg fails the TRT) - R2 will now be overwritten by the TRT instruction and now you 'branch to the car-park' (0C4).

  8. Reserved for future items. Send email to dave@planetmvs.com.

Ways to avoid "Shooting yourself in the foot"


Ways to make debugging easier





Here are the web pages that inspired this S/390 Assembler page: Those page differ in that they deal with bugs that originate because of the way the languages are designed rather than ways the programmers can shoot-themselves-in-the-foot.

Here is a mainframe-related programming page: Common REXX Coding Errors

S/390 is a registered trademark of IBM.
If you find this page useful, you may also want to check out IBM's HLASM web site

BC 15,S/390 assembler FAQ.

Dave's S/390 Assembler FAQ web page IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.



Last Updated: 2000-05-27
This web page is © 1997-2001+ by David Alcock. All Rights Reserved.