Assembler (S/390)
IBM High Level Assembler (HLASM) for the S/390 architecture — the most feature-rich assembler in the IBM mainframe lineage, powering the financial services infrastructure that processes trillions of dollars in daily transactions.
Created by IBM; John R. Ehrman (lead developer and champion); key community contributions from Greg Mushial (Stanford Linear Accelerator Center) and the SHARE Assembler Committee
Assembler (S/390) refers to IBM’s assembly language for the Enterprise Systems Architecture/390 (ESA/390) instruction set — and in practice, to IBM’s High Level Assembler (HLASM), the definitive IBM mainframe assembler first released in June 1992 that remains actively maintained today. HLASM is the culmination of a 28-year assembler development lineage stretching back to the original System/360 in 1964, and its introduction was an unusual story for a large corporation: it was driven not by IBM’s own roadmap but by a grassroots user community, external developers, and one determined IBM champion. Today, HLASM runs on z/OS, z/VM, z/VSE, z/TPF, and Linux on IBM Z — processing the transactions of the global financial system on hardware that maintains direct instruction-set compatibility with IBM’s 1964 mainframes.
History & Origins
The System/360 Lineage (1964)
To understand S/390 assembler, one must begin not in 1990 but in 1964. IBM announced the System/360 on April 7, 1964 — a watershed moment in computing history that established a single, unified instruction set architecture spanning a range of machine sizes from small commercial systems to large scientific processors. The S/360’s principal architect was Gene Amdahl, with Fred Brooks serving as software project lead.
The original S/360 assembler, Basic Assembly Language (BAL), provided the fundamental syntax that all subsequent IBM mainframe assemblers would inherit: mnemonic operation codes, symbolic labels, base-register addressing with displacement offsets, and a macro facility for defining reusable code blocks. Assembler F followed as the standard production assembler for OS/360, introducing a proper macro language with local and global variable symbols, conditional assembly, and structured macro definitions.
The defining architectural characteristics that carry forward into S/390 assembler include:
- 16 general-purpose 32-bit registers (R0–R15)
- Base-register + displacement addressing: memory addresses are formed as a base register value plus a 12-bit displacement (0–4095), requiring careful register management in assembler code
- Packed decimal arithmetic: BCD-encoded data in variable-length fields, essential for business data processing
- EBCDIC character encoding (rather than ASCII)
- Big-endian byte ordering
S/370 and Extended Architecture (1970–1983)
IBM System/370, announced June 30, 1970, maintained full backward compatibility with S/360 while adding virtual memory, channel-to-channel adapters, and improved hardware. Assembler H Version 1 (reportedly released around 1970, with programmer’s guide documentation dated June 1972) introduced a two-pass design with better performance and capabilities than Assembler F.
In early 1983, IBM extended S/370 to S/370-XA (Extended Architecture), expanding address registers from 24-bit (16 MB addressable) to 31-bit (2 GB addressable). Assembler H Version 2 (announced October 1981, general availability March 1983) introduced the critical AMODE and RMODE directives:
AMODE 24— legacy 24-bit addressingAMODE 31— 31-bit addressing for the expanded address spaceRMODE 24— program must reside below the 16 MB lineRMODE ANY/RMODE 31— may reside above the 16 MB line
These directives, which allow a single binary to specify its compatibility requirements, persist unchanged through z/Architecture today.
Community Innovation: The SLAC Modifications (1981)
The story of HLASM’s creation is inseparable from the work of Greg Mushial at the Stanford Linear Accelerator Center (SLAC). Around 1981, Mushial independently developed approximately 60 enhancements to Assembler H to address long-standing usability gaps — chief among them labeled (named) USING statements. In standard Assembler H, the programmer could establish multiple base registers with USING statements, but distinguishing between them in the listing required careful manual tracking. Mushial’s named USINGs made base register management explicit and readable.
Other SLAC enhancements included a USING report at the top of each listing page (showing which base registers were currently active), improved cross-reference output (indicating whether a symbol was read or written), and numerous diagnostic improvements.
Bill Winters and David B. Andrews (of A. Duda and Sons) were key advocates for getting IBM to adopt the SLAC modifications, organizing pressure through the SHARE Assembler Committee and working to keep the community enhancements alive. According to CBT Tape historical accounts, the effort involved manually re-applying the patches — over 6,000 lines of source code from microfiche — with each IBM PTF update, for nearly eight years until IBM’s own product could incorporate them.
At a SHARE conference in the mid-1980s, when an IBM executive dismissed assembler as an obsolete language, the assembled user community pushed back forcefully — catalyzing formal advocacy through the SHARE Assembler Committee.
The Creation of HLASM (1989–1992)
John R. Ehrman was the critical figure who turned community demand into an IBM product. Ehrman had worked at SLAC from 1966 to 1983, teaching assembler programming at Stanford and providing computing support for physicists — giving him firsthand knowledge of Mushial’s enhancements. In March 1983, he joined IBM.
Around 1989, after an Assembler planning manager retired, Ehrman discovered hundreds of unaddressed user requirements in IBM’s internal requirements database accumulated over years of SHARE advocacy. He compiled these into a formal proposal and — in a feat of organizational persistence — secured development funding. IBM had previously characterized some of the community’s most-requested features as “technically impossible”; the HLASM development team proved otherwise.
IBM officially announced High Level Assembler (HLASM) via announcement letter dated May 5, 1992, and released it for general availability on June 26, 1992. HLASM replaced Assembler H Version 2 and formally incorporated the SLAC-derived enhancements that users had been applying manually for over a decade.
Ehrman is credited in IBM and SHARE community documentation as the “father of High Level Assembler.” He served as lead developer and primary spokesman for HLASM for most of his IBM career. He passed away on February 20, 2018.
ESA/390 Architecture Context (1990)
The hardware architecture that HLASM was introduced to support — ESA/390 — was announced in 1990 with the Enterprise System/9000 (ES/9000) family, alongside the MVS/ESA, VM/ESA, and VSE/ESA operating systems. ESA/390 built on ESA/370 (announced February 15, 1988) and added:
- ESCON fiber-optic channel architecture
- New instruction formats: RI (Register-Immediate), RIL (Register-Immediate Long), and RSI (Register-and-Storage-Immediate) supporting relative branch instructions with larger offsets
- IEEE 754 binary floating-point operations alongside the legacy hexadecimal floating-point (expanded to 16 floating-point registers on S/390 G5 hardware in 1998)
ESA/390 is a Complex Instruction Set Computer (CISC) architecture. Unlike RISC architectures with uniform instruction sizes, S/390 instructions range from 2 to 6 bytes, allowing compact encoding of common operations and complex operations (like block memory moves) in single instructions.
Design Philosophy
HLASM’s design reflects two parallel philosophies: architectural continuity and developer productivity.
Architectural Continuity
The S/390 instruction set is directly backward-compatible with System/360 code from 1964. An assembler program written for MVS/360 in the late 1960s can generally be assembled by HLASM and run on a z17 mainframe in 2025. This extraordinary backward compatibility is not accidental — IBM explicitly designed each architectural generation (S/370, S/370-XA, ESA/370, ESA/390, z/Architecture) to execute all valid predecessor code without modification. The result is that the S/390 assembler programmer inherits six decades of instruction set design, including both its strengths (packed decimal arithmetic, powerful string operations, block I/O) and its constraints (base-displacement addressing model, 16-register architecture).
Developer Productivity
The “High Level” in HLASM does not mean the language compiles to high-level abstractions. It means that HLASM provides significantly richer tooling than its predecessors:
- Named USINGs for readable base register management
- Comprehensive listings with a USING report on every page
- Enhanced cross-reference showing whether each symbol was read or written
- Mixed-case symbol names up to 63 characters long
- RSECT directive allowing the assembler to verify reentrancy on a per-section basis
- Dynamic macro handling and unbounded variable arrays in macros
- User-defined external functions callable from macro code
The optional Toolkit Feature adds structured programming macros (IF/ELSE/ENDIF, DO/ENDDO, CASENTRY/ENDCASE), an interactive source-level debugger, a disassembler, and enhanced comparison and cross-reference tools.
Key Features
Base-Displacement Addressing
S/390 assembler uses base-register plus displacement addressing rather than absolute or program-counter-relative addressing (as used in most modern architectures). Every memory reference specifies:
- A base register (one of R0–R15, where R0 indicates no base register)
- A displacement (12-bit value, 0–4095)
- An optional index register for some instruction formats
The assembler’s USING statement informs the assembler which register holds a base address, allowing it to calculate displacements automatically:
USING WORKAREA,R12 Establish R12 as base for WORKAREA
L R3,COUNT Load COUNT (R12 + displacement)
A R3,=F'1' Add literal 1 to R3
ST R3,COUNT Store back to COUNT
HLASM’s labeled USINGs (a key SLAC innovation) allow multiple base registers to be named and explicitly referenced:
USING *,R12 Base register for current CSECT
USING AREA1,R10 LABEL1 Named USING for AREA1
USING AREA2,R11 LABEL2 Named USING for AREA2
L R5,LABEL1.FIELD1 Explicitly using LABEL1's base
L R6,LABEL2.FIELD1 Explicitly using LABEL2's base
AMODE and RMODE Directives
These directives specify the addressing mode and residency mode for each program control section, allowing a single assembler source file to produce modules targeting different memory configurations:
MYPROG CSECT
AMODE 31 Program runs in 31-bit addressing mode
RMODE ANY May be loaded above or below the 16 MB line
With z/Architecture support (HLASM Release 4 onwards):
MYPROG64 CSECT
AMODE 64 64-bit addressing mode
RMODE 64 May reside anywhere in 64-bit virtual storage
Packed Decimal Instructions
A defining feature of the IBM mainframe architecture is its native support for packed decimal (binary-coded decimal) arithmetic. Business data is often stored and processed in packed decimal format rather than binary, avoiding the precision issues of binary floating-point for monetary calculations. Key packed decimal instructions:
| Mnemonic | Full Name | Operation |
|---|---|---|
AP | Add Packed | Add two packed decimal fields |
SP | Subtract Packed | Subtract packed decimal |
MP | Multiply Packed | Multiply packed decimal |
DP | Divide Packed | Divide packed decimal |
CP | Compare Packed | Compare packed decimal values |
ZAP | Zero and Add Packed | Move packed decimal value |
ED | Edit | Format packed decimal for output |
EDMK | Edit and Mark | Format with significance marker |
Packed decimal fields are variable-length (1–16 bytes), with each byte holding two decimal digits and the final nibble holding the sign. The ED instruction’s power to format packed decimal directly into printable output with currency symbols, commas, and decimal points in a single instruction is a notable S/390 capability.
Macro Language
HLASM’s macro facility is a complete conditional assembly language capable of generating arbitrary assembler code at assembly time. Macros use typed variable symbols:
&NAME SETA expr— arithmetic (integer) variable&NAME SETB expr— boolean variable (0 or 1)&NAME SETC 'string'— character variable
Control flow in macros uses:
AIF (condition).label— conditional branch within macroAGO .label— unconditional branch within macroACTR count— set iteration counter to prevent infinite loops
Example macro generating a loop:
MACRO
&LABEL COUNTTO &LIMIT
&LABEL LA R3,0 Initialize counter
LA R4,&LIMIT Load limit
LOOP&SYSNDX A R3,=F'1' Increment (unique label via &SYSNDX)
CR R3,R4 Compare to limit
BL LOOP&SYSNDX Branch if less
MEND
Structured Programming Macros (Toolkit Feature)
The HLASM Toolkit Feature’s structured programming macros replace explicit branch instructions with higher-level constructs, enforcing structured programming discipline:
IF (C,R3,LT,R4) IF R3 < R4
LA R5,1 Set result = 1
ELSEIF (C,R3,EQ,R4) ELSE IF R3 = R4
LA R5,0 Set result = 0
ELSE ELSE
LA R5,-1 Set result = -1
ENDIF END IF
DO WHILE=(C,R6,LT,R7) DO WHILE R6 < R7
A R6,=F'1' Increment R6
ENDDO END DO
OPTABLE Directive
HLASM’s OPTABLE assembler option selects which processor’s instruction set is recognized. This allows the same assembler to target different generations of hardware:
ACONTROL OPTABLE(ZOP) Target z900/z800 (first z/Architecture generation; alias: ZS)
ACONTROL OPTABLE(Z17) Target IBM z17 (2025) instruction set
ACONTROL OPTABLE(DOS) Target legacy DOS/360 instruction set
This is particularly useful for system software that must run on a specific hardware level.
Evolution
From Assembler H to HLASM (1992)
The transition from Assembler H Version 2 to HLASM in 1992 was not just a feature addition — it was a philosophical shift. Assembler H had been maintained conservatively, with user enhancement requests accumulating for years without action. HLASM represented IBM’s acknowledgment that assembler language was not disappearing and deserved serious investment. The SLAC community enhancements, formally incorporated into HLASM, had proven their value through years of informal adoption.
z/Architecture Support (2000)
HLASM Release 4 (September 2000) added support for z/Architecture, introduced with the IBM z900 hardware. z/Architecture extended the ISA to 64-bit registers and addresses while maintaining complete backward compatibility with ESA/390. From an assembler perspective, z/Architecture added:
AMODE 64addressing mode- 64-bit register operations (new mnemonics:
LG,STG,AG,SG, etc.) - 64-bit multiply and divide
- Long displacement facility (increasing the addressable displacement from 4,095 to approximately 524,287 bytes)
- Additional floating-point instructions
The naming convention S/390 assembler thus became somewhat historical after 2000 — technically, modern HLASM targets z/Architecture — but the instruction set remains a strict superset of ESA/390, and the assembler syntax and conventions are essentially unchanged.
Linux on IBM Z (2008)
HLASM Release 6 (September 26, 2008) was a significant expansion, adding the ability to produce ELF32 object files for Linux on IBM Z (then called Linux on zSeries). This allows HLASM to be used for Linux application and system programming on IBM Z hardware, not just for traditional mainframe OS environments. A later APAR added ELF64 support. The Linux on IBM Z variant is packaged as an RPM (asma90) rather than requiring traditional mainframe installation.
Modern IDE Tooling (2020)
IBM Z Open Editor 1.0 (released June 12, 2020) brought HLASM language server support to Visual Studio Code, providing a modern development experience for assembler programming. Features include:
- Code completion across over a thousand HLASM instructions and directives
- Hover documentation for instructions
- Go-to-definition for labels and macros
- Copybook resolution and navigation
- Program outline view
- Real-time syntax checking
This represented IBM’s acknowledgment that mainframe assembler development — while niche — warrants modern tooling investment.
Continuous Maintenance Through New Hardware Generations
HLASM Release 1.6.0 continues to receive IBM APARs for each new processor generation. Support for IBM z16 instructions was added via APAR PH39324, and z17 processor instruction support was added via APAR PH62834 (documented as modified April 2025), followed by refinements in PH66872. The IBM z17 mainframe was announced on April 8, 2025, with general availability on June 18, 2025 — and HLASM already supported its instruction set before GA.
Current Relevance
HLASM Release 1.6.0 is IBM’s current and only actively maintained HLASM release as of 2026. It runs on:
- z/OS — the primary IBM mainframe OS (successor to OS/390, MVS/ESA, MVS)
- z/VM — IBM’s virtual machine operating system
- z/VSE — the VSE-lineage OS (descendant of DOS/360)
- z/TPF — IBM Transaction Processing Facility
- Linux on IBM Z — via RPM package
The reasons for HLASM’s continued relevance are structural rather than merely historical:
OS Interface Requirement: IBM mainframe OS services are exposed through assembler macro invocations (SVCs — Supervisor Call instructions and their wrappers). Some z/OS services are accessible exclusively through assembler macro interfaces, making HLASM a required tool for system-level programming regardless of what higher-level language an application otherwise uses.
Performance-Critical Code: The z/OS I/O Supervisor, OS Dispatcher, and other performance-sensitive OS components are documented as written in assembler — the architecture’s CISC instruction set allows complex operations in single instructions that would require multiple RISC instructions to replicate.
Installed Base: Financial services, insurance, and government organizations maintain enormous portfolios of production assembler code, some dating to the S/360 era. The architecture’s backward compatibility makes replacement unnecessary as long as the business logic remains valid.
New Hardware Support: Each z-series processor generation introduces new instructions — HLASM immediately supports these through IBM’s APAR maintenance process, keeping assembler competitive with other mainframe languages for system programming.
Why It Matters
The S/390 assembler — HLASM — represents a singular achievement in computing history: an instruction set that has maintained unbroken backward compatibility for over six decades, an assembler that incorporated community-developed innovations that IBM initially called “technically impossible,” and a language that continues to power a substantial fraction of the world’s financial infrastructure.
The architecture’s design philosophy of extreme backward compatibility has had profound consequences. A COBOL program compiled for OS/360 in 1968 can run on a z17 mainframe; an assembler program written to call OS/360 SVC interfaces may require minor adjustment for modern OS services, but the instruction set itself is unchanged. This continuity is qualitatively different from anything offered by other mainstream architectures — no other platform in widespread production use maintains compatibility across anything approaching this timespan.
HLASM’s origin story carries its own lesson. The language’s defining features — named USINGs, enhanced cross-reference, the entire Toolkit Feature — were not invented by IBM’s product organization. They were invented by users (Greg Mushial at SLAC), kept alive and advocated by dedicated practitioners (Bill Winters and David B. Andrews) and community organizations (SHARE), and ultimately championed by a single IBM employee (John Ehrman) who understood their value from personal experience. Large organizations resist change; HLASM happened because the community built the proof of value first and IBM was eventually persuaded.
Today, as IBM Z hardware runs AI inference workloads alongside traditional transaction processing, HLASM assembler code written in the 1990s continues to execute in the same address space — a testament to both the rigidity and the resilience of the S/390 architectural legacy.
Timeline
Notable Uses & Legacy
z/OS Operating System Internals
The MVS core (direct predecessor of z/OS) was documented as being almost entirely written in IBM assembler, including the I/O Supervisor and OS Dispatcher which remained in assembler due to performance requirements. This tradition continues in z/OS, where assembler is required for system-level programming — some OS services are accessible only through assembler macro invocations.
Financial Services Transaction Processing
IBM mainframes running z/OS process the majority of the world's high-volume financial transactions. CICS (Customer Information Control System) — which handles ATM withdrawals, account debits/credits, and fund transfers for major banks — uses assembler for its performance-critical exits, modules, and internals. IBM documents Fortune 500 financial institutions as major IBM Z users.
CICS and IMS Middleware Development
CICS and IMS (Information Management System) are transaction and database middleware systems where assembler is used for exits, user-written modules, and critical-path code. Many production CICS and IMS installations include assembler modules that have been in continuous use since the S/370 or S/390 era.
z/TPF Airline Reservation Systems
IBM z/Transaction Processing Facility (z/TPF), used historically in airline reservation and similar ultra-high-volume transaction environments, is a platform where assembler is a core development language due to its extreme performance requirements.
Legacy Business Application Maintenance
Large financial, insurance, and government organizations maintain substantial portfolios of assembler code written originally for System/360, S/370, or S/390 systems. This code continues to run unchanged on z/Architecture hardware due to the architecture's unbroken backward compatibility spanning over six decades.