Language reference

Assembly / HLASM

The layer everything else on the mainframe ultimately compiles down to.

History & foundation

Origin

IBM's Basic Assembly Language (BAL) arrived in 1964 as part of Basic Programming Support for the System/360, deliberately restricted to run on machines with as little as 8 KB of memory and only a card reader, card punch, and printer for input and output. It had no macro support at all. Assembler D followed in 1966 for DOS/360 and introduced macros, and the language kept splitting and recombining across OS/360's Assembler E and F, System/370's Assembler H in 1981, and Assembler XF, before IBM unified the whole line into High Level Assembler (HLASM) in June 1992, replacing Assembler H Version 2.

Design goals

Assembler was never meant to be comfortable. It gives a program direct, unmediated control over registers, storage addresses, and the exact machine instructions the CPU executes, in exchange for none of the safety nets higher-level languages provide. That trade is precisely why it still exists: when a system needs to do something no higher-level language on the platform exposes, or needs the last possible bit of performance, HLASM is still the layer everything else on z/OS ultimately compiles down to.

Standards timeline

  1. 1964 · BAL

    Basic Assembly Language ships with System/360, no macro support, built for 8 KB machines.

  2. 1966 · Assembler D

    First IBM assembler with macro support, for DOS/360 systems with 16 KB minimum memory.

  3. 1970s · Assembler E and F

    E required 32 KB minimum storage; F ran on 64 KB machines and became a standard OS/360 component.

  4. 1981 · Assembler H

    Version 2 announced supporting Extended Architecture (XA); IBM withdrew it from marketing in 1994.

  5. 1992 · HLASM

    High Level Assembler ships in June, replacing Assembler H Version 2 as IBM's current assembler.

  6. ongoing · HLASM today

    Still IBM's assembler for z/OS, z/VSE, z/VM, and z/TPF; Release 6 and later also run on Linux on IBM Z.

$47 to $76 per hour

Reported pay range for mainframe assembler contract roles as of May 2026.

ZipRecruiter: Mainframe Assembler Jobs

15% Gen Z, up from 1%

Share of surveyed mainframe technologists who are Generation Z, up from 1% seven years earlier, alongside millennials rising to just over half of respondents.

ACM CareerNews, September 2025

Assembly / HLASM history and figures compiled from public sources, cited above. Corrections welcome.

Abend & completion codes

View all 47
Abend S0C1z/OS · HLASM

Condition

The CPU tried to execute an invalid operation code, most classically because execution fell through from the last real instruction straight into a data area (a DC or literal pool) and started trying to interpret raw data bytes as machine instructions.

Fix

Check that every code path ends in an explicit branch back to the caller (typically BR 14) before any DC or literal declarations follow it. This is the single most common first-program mistake in assembler, catching even careful beginners who copy a working example and add code after it without an exit branch.

Abend S0C2z/OS · HLASM

Condition

The program attempted to execute an instruction, or issue a supervisor call, that is restricted to an authorized state the program does not have.

Fix

Check whether the instruction or SVC actually requires APF authorization, and confirm the load module is running from an APF-authorized library if it genuinely needs that access. Most application-level assembler code should never need privileged instructions at all, so this often points to a mistaken opcode rather than a missing authorization.

Abend S0C4z/OS · HLASM

Condition

Protection exception (reason code 4) is the classic case, but the official manual lists S0C4 as covering several other, quite different exceptions identified only by their SDWA reason code: segment-translation (10), page-translation (11), ASTE-validity (2B), ASCE-type (38), and Region-First/Second/Third (39, 3A, 3B) exceptions. The protection case is what most assembler programmers know it as: the key of the storage area referenced doesn't match the key the program is running under, most often from a base register that got overwritten by ordinary code so USING no longer matches what the register actually holds, from a module link-edited as reentrant without actually following reentrancy rules, or from trying to execute instructions out of storage that was obtained with EXECUTABLE=NO. The translation-exception reason codes instead point at storage that was never actually GETMAINed, or that was paged out while a disabled program tried to reference it.

Fix

Check the SDWA/dump reason code first, since it tells you which of these unrelated problems actually happened. For reason code 4, check every instruction that loads a value into a register also used as a base register for a stray overwrite, and check whether the module's actual link-edit attributes (reentrant or not, storage key, executable) match how it's coded and how it's running. For the translation reason codes (10, 11, 2B, 38, 39, 3A, 3B), check that the storage being referenced was actually obtained before use, and that a program running disabled page-fixed any storage it touches instead of leaving it pageable.

Abend S0C5z/OS · HLASM

Condition

The program referenced a storage address that does not exist at all, distinct from S0C4 in that the address is invalid rather than merely off-limits.

Fix

Check for an uninitialized register used as a base or pointer, or address arithmetic that produced a value outside real storage entirely. This is less common than S0C4 in application code but shows up in the same class of base-register mistakes.

Frequently asked

What is HLASM used for today?+

HLASM (High Level Assembler) is still used where a mainframe system needs direct control over registers, storage, or performance that COBOL, PL/I, or RPG can't provide, usually in systems-level or performance-critical routines underneath higher-level applications.

Is mainframe assembler still worth learning?+

It pays well specifically because so few people maintain it: reported rates run roughly $47 to $76 an hour as of 2026. It's a specialist skill, not a general career path.

What does S0C7 mean in assembler?+

S0C7 is a data exception: an arithmetic instruction operated on data that isn't validly formatted for it, most often a packed-decimal field with invalid digits.

How many registers does z/Architecture actually give you?+

Sixteen general-purpose registers, each 64 bits wide, used as accumulators, base registers, and index registers. Every language that compiles for z/OS, not just assembler, targets this same register set. Addressing mode (AMODE 24, 31, or 64) then controls how much of a register a program can use as an address.

What actually causes an S0C4 protection exception?+

A program calculated or received an address it isn't authorized to touch. Common causes include an uncontrolled loop overwriting storage, a reference to a closed file's I/O area, mismatched Linkage Section definitions between a caller and callee, and moving data to an address under decimal 512.

Does HLASM only run on z/OS?+

No. HLASM, IBM's current assembler since June 1992, also runs on z/VSE, z/VM, and z/TPF, and Release 6 and later runs on Linux on IBM Z as well, generating ELF or GOFF object files there instead of the usual z/OS object format.

Is the mainframe workforce really retiring out?+

Not by the numbers, at least not yet. BMC's 2025 mainframe survey, its 20th and largest to date, found programmers aged 18-49 now make up roughly 80% of the mainframe workforce, up from about 53% in 2018. Whether that younger cohort is learning assembler specifically, versus COBOL or Java on Z, is a separate question the survey doesn't answer.

How much real transaction volume still runs through mainframe systems?+

A lot. CICS alone, the transaction-processing environment most mainframe applications run inside, was reported to be handling roughly 30 billion transactions per day as of 2025, per Planet Mainframe's retrospective on CICS's 55th anniversary.

From the community

Real questions from public forum threads, with credit to who asked and who answered. Our answer restates the fix and links to the matching reference page where one exists.

My first assembler program abends S0C1 right after it prints its message. What went wrong?

Asked by kingo on zMainframes forum, ongoing thread

You need a BR 14 (or whatever exit instruction the original program you copied used) to leave the program before the constant. Without it, execution runs straight off the end of your code into a DC C'TEST' data declaration and tries to execute the character data as instructions.

Robert Sample (Global Moderator)

Our answer

This is close to a rite of passage in learning assembler: without an explicit branch back to the caller, execution does not stop, it keeps reading whatever comes next in storage as instructions. If S0C1 appears right after code that looks correct, check that the very next thing in the source is data, not another instruction, and that there is a BR 14 or equivalent between them.

Full reference page →

I added a few lines to a working assembler program and now it abends. I didn't touch the logic that was already there. What's the usual cause?

Asked by common pattern, compiled from field troubleshooting on planetmvs.com, reference article

One of the most common ways to break working assembler is to reuse a register that is already serving as a base register from a USING statement. New code that loads a value into that register, without realizing it is already spoken for, corrupts every address computed from it afterward, and the abend can surface far from the actual mistake.

planetmvs.com

Our answer

Before assuming the new code itself has a logic bug, check whether it reused a register that an existing USING statement already claims as a base register. This is exactly the kind of mistake that produces an abend in code you didn't touch, because the corruption happens in the new code but the crash happens wherever the now-wrong base register is used next.

Full reference page →

More on Assembly