HLASM Macros: Defining, Invoking, and Parameterising Macros
HLASM Macros: Defining, Invoking, and Parameterising Macros
HLASM macros are a powerful text-substitution and code-generation facility. A macro expands at assembly time into one or more HLASM statements. System macros like WTO and OPEN are provided by IBM; you can write your own for repeated code patterns.
Basic Macro Definition
MACRO
&LABEL MYMAX &R1,&R2,&RESULT
* Compare R1 and R2, put larger value in RESULT register
CR &R1,&R2 Compare R1 and R2
BNH &LABEL.SKIP Branch if R1 <= R2
LR &RESULT,&R1 R1 is larger
B &LABEL.DONE
&LABEL.SKIP LR &RESULT,&R2 R2 is larger
&LABEL.DONE DS 0H
MENDThe macro starts with MACRO and ends with MEND. The second line is the prototype: &LABEL is the name field parameter, MYMAX is the operation name, and &R1, &R2, &RESULT are positional parameters.
Invoking a Macro
FINDMAX MYMAX 3,4,5 &LABEL=FINDMAX, &R1=3, &R2=4, &RESULT=5This expands to:
CR 3,4
BNH FINDMAXSKIP
LR 5,3
B FINDMAXDONE
FINDMAXSKIP LR 5,4
FINDMAXDONE DS 0HKeyword Parameters
Keyword parameters have names and default values, making macros more readable:
MACRO
ADDTOTAL ®=3,&FIELD=TOTAL,&LEN=4
A ®,&FIELD
MEND
*
* Invoke with keyword parameters (order doesn't matter):
ADDTOTAL REG=5,FIELD=GRANDTOT
ADDTOTAL FIELD=SUBTOTAL,REG=4,LEN=4Set Symbols: Variables at Assembly Time
HLASM provides three types of set symbols for conditional assembly:
&COUNT SETA 0 Arithmetic set symbol (integer)
&NAME SETB 1 Boolean set symbol (0 or 1)
&TEXT SETC 'HELLO' Character set symbol (string)Increment a counter:
&COUNT SETA &COUNT+1AIF, AGO, ANOP — Conditional Assembly
AIF (condition).label branches at assembly time if the condition is true:
MACRO
GENMSG &TYPE=INFO
AIF ('&TYPE' EQ 'ERROR').DOERR
* Generate INFO message
WTO 'INFORMATION MESSAGE'
AGO .DONE
.DOERR ANOP
* Generate ERROR message
WTO 'ERROR MESSAGE',ROUTCDE=11
.DONE ANOP
MENDAIF (condition).label— conditional branch in macro expansionAGO .label— unconditional branch in macro expansionANOP— no operation (used as a branch target)
LCLA, LCLB, LCLC — Local Variables
Local set symbols exist only within the current macro invocation:
MACRO
GENTRY &COUNT
LCLA &I Local counter
&I SETA 0
.LOOP ANOP
AIF (&I GE &COUNT).DONE
DC F'0' Generate one fullword per count
&I SETA &I+1
AGO .LOOP
.DONE ANOP
MEND
*
GENTRY 5 Generates 5 DC F'0' statementsGBLA, GBLB, GBLC — Global Variables
Global set symbols persist across macro invocations:
GBLA &TOTALFIELDS
&TOTALFIELDS SETA 0 Initialize once in the main source
MACRO
ADDFIELD &LEN
GBLA &TOTALFIELDS
DS CL&LEN
&TOTALFIELDS SETA &TOTALFIELDS+1
MENDMNOTE — Assembly-Time Messages
AIF ('&TYPE' NE 'A' AND '&TYPE' NE 'B').BADTYPE
AGO .OK
.BADTYPE MNOTE 8,'Invalid TYPE parameter: &TYPE'
.OK ANOPMNOTE severity,'message' prints a message during assembly. Severity 8 or higher marks the assembly as having errors.
System Macros
IBM provides hundreds of system macros in SYS1.MACLIB and SYS1.MODGEN:
* Write to operator console
WTO 'PROGRAM STARTED'
* Open a file
OPEN (INFILE,(INPUT))
* Get a record
GET INFILE,INREC
* Put a record
PUT OUTFILE,OUTREC
* Close files
CLOSE (INFILE,,OUTFILE)
* Allocate storage
GETMAIN R,LV=256 Allocate 256 bytes, address in reg 1
* Free storage
FREEMAIN R,LV=256,A=(1)Frequently Asked Questions
Q: How do I avoid duplicate label errors when a macro is invoked multiple times?
Use the &LABEL name field parameter concatenated with a suffix: &LABEL.SKIP, &LABEL.DONE. Each invocation provides a unique label (e.g., STEP1, STEP2), so the generated labels are STEP1SKIP, STEP2SKIP, etc. If the macro has no name field parameter, use LCLA &SYSNDX — &SYSNDX is a system variable that increments for each macro call, giving unique generated labels like L00001, L00002.
Q: What is the difference between a macro and an assembler instruction? A macro exists only at assembly time — it generates HLASM statements which are then assembled into machine instructions. A machine instruction corresponds directly to hardware operation codes. Macros provide abstraction and code generation; they have no runtime cost beyond the instructions they generate. Complex macros like OPEN and GET generate multiple machine instructions and data areas.
Q: Where does the assembler look for macro definitions? The assembler looks in the SYSLIB DD statement in the JCL. This typically points to SYS1.MACLIB (IBM system macros) and SYS1.MODGEN (DFSMS and other macros). Your own macros can be in a private macro library, which you add to the SYSLIB concatenation. Macros can also be defined inline in the source before their first use.
Part of HLASM Mastery Course — Module 14 of 22.
