Month: February 2013

Structured Assembler Macros: The Case StatementStructured Assembler Macros: The Case Statement

Here’s a simple case statement using the HLASM structured CASE macro. Register 4 is selected (your choice not = 0) and l0 is loaded into R4. The contents of the register are used to select the correct case. In this case, “Fall” is MVC-ed to the SEASON field. More complex CASE examples will be the subject of future posts.


LA R4,10
CASENTRY R4
CASE 12,1,2
MVC SEASON,=CL6’WINTER’
CASE 3,4,5
MVC SEASON,=CL6’SPRING’
CASE 6,7,8
MVC SEASON,=CL6’SUMMER’
CASE 9,10,11
MVC SEASON,=CL6’FALL’
ENDCASE
PUT FILEOUT,RECOUT

Structured Assembler Macros: The While LoopStructured Assembler Macros: The While Loop

Build a while loop using the structured assembler Do macro. Here is the relevant code:

         DO WHILE=(CP,X,LT,=P'10')                                      
            AP   X,=P'1'                                                
            MVC  XOUT,EDWD                                              
            ED   XOUT,X                                                 
            PUT  FILEOUT1,RECOUT                                        
         ENDDO                                                                                                                  

The test at the top of the loop compares X with a packed decimal 10 and enters the loop if X is less than 10. Sweet! Here’s the complete program that makes it work:

//CSUP004A JOB (ASSY),'WOOLBRIGHT',CLASS=A,MSGCLASS=A,                  
//   NOTIFY=&SYSUID,MSGLEVEL=(1,1)                                      
//ASM      EXEC PROC=HLASMCLG                                           
//C.SYSLIB   DD   DSN=SYS1.MACLIB,DISP=SHR                              
//           DD   DSN=HLA.SASMMAC2,DISP=SHR                             
//SYSIN    DD   *                                                       
         COPY   ASMMSP                                                  
         TITLE  'SKELETON ASSEMBLER PROGRAM'                            
         PRINT  ON,DATA,NOGEN                                           
******************************************************************      
*                                                                *      
*   PROGRAMMER:  WOOLBRIGHT                                      *      
*   COMMENTS  :  ASM SKELETON PROGRAM                            *      
*                                                                *      
******************************************************************      
*                                                                *      
*     REGISTER EQUATES                                           *      
*                                                                *      
******************************************************************      
R0       EQU   0                                                        
R1       EQU   1                                                        
R2       EQU   2                                                        
R3       EQU   3                                                        
R4       EQU   4                                                        
R5       EQU   5                                                        
R6       EQU   6                                                        
R7       EQU   7                                                        
R8       EQU   8                                                        
R9       EQU   9                                                        
R10      EQU   10                                                       
R11      EQU   11                                                       
R12      EQU   12                                                       
R13      EQU   13                                                       
R14      EQU   14                                                       
R15      EQU   15                                                       
******************************************************************      
*                                                                *      
*     SYMBOLIC EQUATES                                           *  
 *                                                                *      
******************************************************************      
MACRO3   CSECT                         STANDARD ENTRY CODE              
         STM   R14,R12,12(R13)                                          
         BASR  R12,R0                  ESTABLISH...                     
         USING *,R12                   ADDRESSABILITY                   
         ST    R13,SAVEAREA+4          BACKWARD CHAIN CALLER            
         LA    R13,SAVEAREA            ADDRESS OF MY SAVE AREA          
******************************************************************      
* BEGIN THE PROGRAM LOGIC. FIRST OPEN THE OUTPUT FILE         
******************************************************************      
         OPEN  (FILEOUT1,(OUTPUT))                                      
         ZAP   X,=P'0'                                                                                                         
LOOP     EQU   *                                                        
         DO WHILE=(CP,X,LT,=P'10')                                      
            AP   X,=P'1'                                                
            MVC  XOUT,EDWD                                              
            ED   XOUT,X                                                 
            PUT  FILEOUT1,RECOUT                                        
         ENDDO                                                                                                                  
EXIT     EQU   *                                                        
         CLOSE (FILEOUT1)                                               
         L     R13,SAVEAREA+4          POINT AT OLD SAVE AREA           
         LM    R14,R12,12(R13)         RESTORE THE REGISTERS            
         LA    R15,0                   RETURN CODE = 0                  
         BR    R14                     RETURN TO OPERATING SYSTEM       

******************************************************************      
              *                                                                *      
*     OUTPUT FILE - DATA CONTROL BLOCK                           *      
*                                                                *      
******************************************************************      
               DC X'FFFFFFFF'                                           
FILEOUT1 DCB   DSORG=PS,                                               X
               MACRF=(PM),                                             X
               DEVD=DA,                                                X
               DDNAME=FILEOUT1,                                        X
               RECFM=FB,                                               X
               LRECL=80                                                 

******************************************************************      
*                                                                       
*    OUTPUT RECORD AREA                                                 
*                                                                       
******************************************************************      
RECOUT   DS   0CL80               PRINT AREA                            
         DC    CL10' '                                                  
XOUT     DS    CL5                                                      
         DC    CL65' '                                                  
EDWD     DC    X'4020212060'                                            
X        DS    PL2                                                      
******************************************************************      
*                                                                       
*    REGISTER SAVE AREA                                                 
*                                                                       
******************************************************************      
SAVEAREA DS  18F                                                        
******************************************************************      
*                                                                       
*    LITERAL POOL                                                       
*                                                                       
******************************************************************      
         LTORG *                                                        
         END   MACRO3                                                   
/*                                                                      
//G.SYSABOUT DD SYSOUT=*                                                
//G.SYSUDUMP DD SYSOUT=*                                                
//G.FILEOUT1 DD SYSOUT=*                                                                                                          
//                                                                      

Structured Programming Macros: SELECT – You Gotta Try It!Structured Programming Macros: SELECT – You Gotta Try It!

The structured programming macros in HLASM are just too sweet to ignore.  Make your programming life easier by adopting them.  The SELECT statement works like Java’s SWITCH except the default behavior is to exit each case automatically (no pesky BREAKs) – just as God intended.  The code below examines a two-byte character field that contains a 01 for January, 02 for February, …, 12 for December.  The code substitutes a character version of the month in the output.  Notice how clean the code looks compared to what we would write in native assembler.

SELECT CLC,MONTHIN,EQ                   
   WHEN =C'01'                          
      MVC  MNTHOUT,=CL9'JANUARY'        
   WHEN =C'02'                          
      MVC  MNTHOUT,=CL9'FEBRUARY'       
   WHEN =C'03'                          
      MVC  MNTHOUT,=CL9'MARCH'          
   WHEN =C'04'                          
      MVC  MNTHOUT,=CL9'APRIL'          
   WHEN =C'05'                          
      MVC  MNTHOUT,=CL9'MAY'            
   WHEN =C'06'                          
      MVC  MNTHOUT,=CL9'JUNE'           
   WHEN =C'07'                          
      MVC  MNTHOUT,=CL9'JULY'           
   WHEN =C'08'                          
      MVC  MNTHOUT,=CL9'AUGUST'         
   WHEN =C'09'                          
      MVC  MNTHOUT,=CL9'SEPTEMBER'      
   WHEN =C'10'                          
       MVC  MNTHOUT,=CL9'OCTOBER'      
    WHEN =C'11'                        
       MVC  MNTHOUT,=CL9'NOVEMBER'     
    WHEN =C'12'                        
       MVC  MNTHOUT,=CL9'DECEMBER'     
    OTHRWISE                           
       MVC  MNTHOUT,=CL9'UNKNOWN'      
 ENDSEL                                

Just so you can see the difference, here is part of the generated code, which would be similar to the code we would write without the macro:

 SELECT CLC,MONTHIN,EQ
WHEN =C'01'
+       CLC MONTHIN,=C'01'
+       BC 7,#@LB2
        MVC MNTHOUT,=CL9'JANUARY'
WHEN =C'02'
+       BC 15,#@LB1 SKIP TO END
+#@LB2  DC 0H
+       CLC MONTHIN,=C'02'
+       BC 7,#@LB4
        MVC MNTHOUT,=CL9'FEBRUARY'
WHEN =C'03'
+       BC 15,#@LB1 SKIP TO END
+#@LB4  DC 0H
+       CLC MONTHIN,=C'03'
+       BC 7,#@LB6
        MVC MNTHOUT,=CL9'MARCH'
WHEN =C'04'
+       BC 15,#@LB1 SKIP TO END

Which is easier to debug and understand?

Structured Assembler Macros: The IF statementStructured Assembler Macros: The IF statement

Back in the 70′s many thoughtful computer scientists weighed in on a now-dead issue of the GoTo statement in high-level languages.  The issue seems to be pretty much settled now, with many new languages avoiding GoTo altogether, and high-level programmers avoiding their use except in very specialized circumstances.   But assembler programmers depend on branch statements (conditional and unconditional) as a required part of any program logic. We can’t avoid coding Branch statements, so the goal is to use them in a reasonably straightforward way, avoiding spaghetti logic.  Good assembler programmers do this intuitively after a while, but IBM has included some high-level macros that make the job even easier now.  The macros are distributed in the HLASM Toolkit.  The macros are stored in a library called hlg.SASMMAC2 (where hlq is a high-level qualifier that varies from system to system).  If your system has the toolkit, include the macro library in your SYSLIB for the compile.  On my system, the JCL looks like this:

//C.SYSLIB   DD   DSN=SYS1.MACLIB,DISP=SHR
//                  DD   DSN=HLA.SASMMAC2,DISP=SHR

In the next few postings, we will look at the macros that are available.  In this first note, we look at three macros that support if-statements:  If, ELSE, and ENDIF.

   The IF statement comes in a variety of formats, but I especially like the format below:

        IF (CLC,X,LT,Y)                   
            MVC  SMALLER,X                 
            MVC  LARGER,Y                  
         ELSE                              
            MVC  SMALLER,Y                 
            MVC  LARGER,X                  
         ENDIF               

The predicate in the If statement has four parts:

1)  A compare instruction mnemonic (like CLC or CP)

2)  The operand 1 field

3)  A condition parameter (H – high, GT -greater than, L – low, LT – less than, E or EQ – equal)

4) The operand 2 field

Like if-statements in high-level languages, the true block occurs between the IF and the ELSE, and the false block occurs after the ELSE and before the ENDIF.

When the macros are assembled, the required branch statements and labels are inserted.  IF statements can be nested and used in conjuction with other structured macros, just as you would hope for. 

    Examine the generated code by coding PRINT ON,NODATA,GEN just before the if statement, and PRINT ON,NODATA, NOGEN just after the ENDIF.

   Give the IF statement a try – you’ll like it.