IBM HLASM Macro
IBM High Level Assembler and its powerful macro and conditional-assembly language, the modern standard assembler for z/OS, z/VM, and z/VSE mainframes since 1992.
Created by IBM (lead architect John R. Ehrman)
IBM High Level Assembler (HLASM) is IBM’s standard assembler for its mainframe operating systems, and its macro and conditional-assembly language is one of the most capable metaprogramming systems ever built into an assembler. First released in June 1992, HLASM is the direct successor to Assembler H and the latest link in a chain of IBM mainframe assemblers reaching back to the original System/360 in 1964. While the machine-instruction layer translates familiar IBM mainframe opcodes into object code, what sets HLASM apart is the language sitting above the instructions: a full preprocessor with variables, expressions, branching, and subroutines that runs entirely at assembly time. This conditional-assembly language — driven by MACRO/MEND definitions, SETA/SETB/SETC variables, and AIF/AGO control flow — lets programmers generate code, enforce conventions, and build their own higher-level constructs on top of raw assembler.
History & Origins
The System/360 assembler heritage
HLASM cannot be understood in isolation; it is the modern member of a family that began with the IBM System/360 in 1964. The earliest Basic Assembly Language (BAL) was so memory-constrained that it offered no macro facility at all. The macro concept arrived shortly after with Assembler D, the first IBM mainframe assembler to support macro instructions, and matured through Assembler E and F, which shipped as standard parts of OS/360. In the 1970s, Assembler XF extended Assembler F with System/370 instructions, and the faster, more powerful Assembler H emerged. Assembler H Version 2, announced in 1981 with Extended Architecture support, was HLASM’s immediate predecessor.
A “high level” assembler
IBM released High Level Assembler V1R1 in June 1992, replacing Assembler H Version 2 while remaining upward-compatible with it so that decades of existing source could be reassembled unchanged. The principal architect was John R. Ehrman of IBM’s Silicon Valley Laboratory, often described as the “father of High Level Assembler.” Ehrman’s writings for the SHARE user community famously argued that the assembler’s macro and conditional-assembly facilities effectively made it a higher-level language — hence the product’s name. The “high level” label refers not to the machine instructions, which remain low-level, but to the rich macro language layered on top.
Design Philosophy
HLASM’s design reflects two priorities that pull in different directions: absolute compatibility with an enormous legacy code base, and expressive metaprogramming for those who want it.
Compatibility above all
A mainframe assembler exists to assemble code that organizations cannot afford to rewrite. HLASM’s upward compatibility with Assembler H — and through it, the broader System/360 assembler lineage — is a foundational design constraint. Programs written across decades of IBM mainframe history continue to assemble, which is precisely why the language has remained stable rather than chasing new paradigms.
Three languages in one
A useful way to view HLASM is as three layers combined in a single source file:
- Machine instructions — the native opcodes of the target architecture (System/360 through z/Architecture).
- Assembler instructions (directives) — statements such as
DC,DS,USING,CSECT, andDSECTthat control storage layout, addressing, and the assembly process. - The conditional assembly language — a complete metaprogramming layer with typed variables, expressions, conditional and unconditional branching, built-in functions, and subroutines, all evaluated at assembly time.
It is this third layer that gives HLASM its character and its name.
Key Features
The macro facility
Macros are defined between MACRO and MEND statements. When invoked, a macro generates assembler source, with parameters substituted into the body. MEXIT allows early exit, and MNOTE emits messages and diagnostics during assembly.
Typed conditional-assembly variables
HLASM provides three types of SET symbols (assembly-time variables):
| Declaration | Type | Set by | Purpose |
|---|---|---|---|
LCLA / GBLA | Arithmetic (integer) | SETA | Counters, computed values |
LCLB / GBLB | Binary (0/1) | SETB | Boolean flags and conditions |
LCLC / GBLC | Character (string) | SETC | Text, names, generated labels |
Each comes in local (LCL*) and global (GBL*) scope, and SET symbols can be subscripted to form arrays.
Conditional assembly control flow
The conditional-assembly language is genuinely a programming language that runs at build time:
AIF— conditional branch on a logical expression to a sequence symbol.AGO— unconditional branch.ANOP— a no-operation that serves as a branch target.- Sequence symbols (e.g.,
.LOOP) mark branch destinations.
Because these provide variables, conditional branching, and unbounded iteration, the conditional-assembly language is widely regarded as Turing-complete and is frequently called one of the most powerful macro facilities in any language. (This characterization is well established in practice and in IBM’s own descriptions, though it is a general statement of capability rather than a formal published theorem.)
System variable symbols
HLASM supplies built-in variables such as &SYSNDX (a unique macro-invocation counter, useful for generating distinct labels), &SYSLIST (positional parameter access), and &SYSDATE, among many others.
HLASM-specific extensions
Beyond the inherited facilities, HLASM adds capabilities such as external function calls from conditional assembly (SETAF, SETCF), additional object formats, and improved diagnostics over Assembler H.
A small macro example
The following macro builds a length-prefixed greeting at assembly time, choosing default text when no operand is supplied. It demonstrates MACRO/MEND, a SETC variable, and AIF/AGO/ANOP conditional assembly:
MACRO
&LABEL GREET &WHO
.* Conditional-assembly macro: build a greeting at assembly time
LCLC &MSG Local character work variable
AIF ('&WHO' EQ '').NONE Branch if no operand supplied
&MSG SETC 'Hello, &WHO.!' Substitute the parameter into text
AGO .GEN
.NONE ANOP Branch target (no operation)
&MSG SETC 'Hello, World!' Default when &WHO is omitted
.GEN ANOP
&LABEL DC AL1(L'TEXT&SYSNDX) One-byte length prefix
TEXT&SYSNDX DC C'&MSG' Generated message text
MEND
*
* --- Invocations ---
MSG1 GREET ME Generates: Hello, ME!
MSG2 GREET Generates: Hello, World!
Here the period in &WHO.! is the concatenation delimiter, &SYSNDX keeps generated labels unique across expansions, and the .NONE/.GEN sequence symbols are conditional-assembly branch targets that produce no object code themselves.
The Toolkit Feature
The HLASM Toolkit Feature is a separately priced companion product that adds a substantial set of programmer aids, including:
- Structured programming macros —
IF/ELSE/ENDIF,DO/ENDDO,CASENTRY/CASE/ENDCASE, andSELECT/WHEN/ENDSEL, which bring high-level control structures to assembler. - A Disassembler for turning object code back into source.
- The Program Understanding Tool (PUT) for visualizing program structure.
- The Source XREF (ASMXREF) cross-reference utility.
- An Interactive Debug Facility (IDF).
- An enhanced SuperC source-comparison utility.
IBM sells the combined offering as “IBM High Level Assembler and Toolkit Feature.”
Platform Support
According to IBM’s product documentation, HLASM runs on IBM mainframe operating systems and, from Release 6, on Linux on IBM Z:
- Operating systems: At its 1992 release it supported MVS, VM, and VSE; the current product is branded High Level Assembler for z/OS, z/VM, and z/VSE, and documentation also lists z/TPF. Release 6 (2008) added Linux on IBM Z.
- Hardware architectures: it targets the native instruction sets of System/360, System/370, System/370-XA, ESA/370, ESA/390, and z/Architecture.
- Object formats: traditional object modules, GOFF, and ELF (ELF32/ELF64) for Linux on Z.
Because specific operating-system and architecture support varies by release, anyone targeting a particular environment should consult the current HLASM documentation for the details that apply to their installation.
Evolution
HLASM’s history is one of steady, conservative maintenance rather than reinvention:
| Phase | Era | Character |
|---|---|---|
| Predecessors | 1964–1992 | BAL → Assembler D/E/F → Assembler XF → Assembler H V2; macro facility and conditional assembly mature over nearly three decades |
| HLASM V1R1 | 1992 | Replaces Assembler H V2; upward-compatible; “high level” macro emphasis |
| Releases 2–5 | mid-1990s to mid-2000s | Track OS/390 and early z/OS; add z/Architecture and GOFF support; Toolkit Feature matures |
| Release 6 | 2008 onward | Adds Linux on IBM Z and ELF output; remains the current, serviced release line |
There is no public “Release 7”; IBM has continued to ship enhancements within the Release 6 line through service updates. As a proprietary IBM product, HLASM has no ISO, ANSI, or ECMA standard — it is defined solely by IBM’s HLASM Language Reference.
Current Relevance
As of 2026, HLASM remains the de facto standard assembler for IBM mainframes and is actively maintained as part of the z/OS, z/VM, and z/VSE toolchains. Its relevance is concentrated and durable: mainframes continue to run mission-critical workloads in banking, insurance, government, and other large enterprises, and the assembler-coded foundations of those systems — operating-system internals, exits, and performance-critical paths — still require a maintained assembler.
Modern tooling has grown up around the language as well. The Eclipse Che4z “HLASM Language Support” extension and IBM Z Open Editor implement HLASM for contemporary IDEs, bringing language-server features such as syntax checking and navigation to assembler programmers who once worked entirely in mainframe editors.
Why It Matters
HLASM matters first as the living endpoint of the System/360 assembler tradition — a continuous lineage of IBM mainframe assembly that has remained source-compatible across more than six decades of hardware, from the 1964 System/360 to today’s z/Architecture machines. Few languages can claim that kind of unbroken continuity.
It matters equally as a demonstration that an assembler’s macro layer can be a programming language in its own right. The conditional-assembly facility — typed variables, branching, subroutines, built-in functions, and code generation, all running at assembly time — is powerful enough that IBM and the SHARE community came to call the result a high level assembler. In an era when most languages keep metaprogramming at arm’s length, HLASM embeds a full, build-time programming language directly into the act of writing machine code, and it has kept the world’s mainframes assembling for over thirty years.
Timeline
Notable Uses & Legacy
Mainframe operating system internals
IBM's mainframe operating systems trace back to assembler-coded foundations; low-level components such as the supervisor, I/O handling, and the macros that expose system services have long been written in IBM assembler, with HLASM as the modern toolchain for maintaining and extending that code.
Systems programming and exits
Mainframe systems programmers write SVCs, user exits, device-level routines, and performance-critical code paths in HLASM where direct control of registers, storage, and machine instructions is required.
Legacy enterprise applications
Banking, insurance, government, and other high-throughput mainframe shops maintain large bodies of assembler application code — often decades old — that HLASM assembles and keeps running on current z/Architecture hardware.
Macro libraries and code generation
Organizations build extensive macro libraries that encode site conventions, generate boilerplate, and act as domain-specific languages layered on top of assembler, exploiting HLASM's conditional-assembly facility as a build-time code generator.
Modern mainframe tooling targets
Contemporary developer tools such as IBM Z Open Editor and the open-source Eclipse Che4z 'HLASM Language Support' LSP extension implement the HLASM language so engineers can edit and analyze assembler in modern IDEs.