Assembler (System/370)
IBM's assembly language for the System/370 mainframe architecture — the language in which MVS, VM/370, and a generation of transaction processing systems were written, and whose instruction set still executes on IBM Z hardware today.
Created by IBM
Assembler (System/370) is IBM’s assembly language for the System/370 mainframe architecture, announced on June 30, 1970 as the backward-compatible successor to System/360. It is less a single product than a family of assemblers — Assembler F carried forward from S/360, then Assembler XF and Assembler H — sharing one syntax and one instruction set. In this language IBM wrote MVS, VM/370, and the supervisors and transaction monitors on which corporate and government data processing ran for two decades. The architecture was formally replaced by System/390 on September 5, 1990, which is why the language is best described as dormant: nobody starts new S/370 assembler projects. But the code did not stop running. IBM’s unbroken compatibility chain means a System/370 assembler program can still be assembled by IBM High Level Assembler and executed on current IBM Z hardware, and a great deal of it is.
History & Origins
Inheritance from System/360
System/370 assembler is not a new language so much as an extension of the one IBM introduced with System/360 on April 7, 1964. The S/360 established, and S/370 inherited without modification:
- Sixteen general-purpose 32-bit registers (R0–R15), plus four floating-point registers
- Base-register plus displacement addressing: every storage reference is a base register value plus a 12-bit displacement (0–4095), optionally plus an index register
- Packed decimal arithmetic on variable-length BCD fields, sized for business data processing
- EBCDIC character encoding and big-endian byte order
- A macro assembler with conditional assembly, added in Assembler D and matured in Assembler F
By 1970 the assembler product line already had several rungs, sized to the memory available on the target machine: BAL (1964) for minimal 8 KB systems with no macro support at all; Assembler D (1966) for 16 KB DOS/360 systems, the first with macros; Assembler E (1966) for 32 KB OS/360 systems; and Assembler F (1966), the standard OS/360 assembler, which reportedly needed roughly 44 KB of a 64 KB machine to run.
What System/370 Added (1970)
System/370 was announced on June 30, 1970 with the Models 155 and 165, joined by the Model 145 on September 23. Crucially, the announcement was of hardware, not of a new programming language: S/370 executed valid S/360 code unchanged. For the assembler programmer, the architecture added thirteen new instructions. Three mattered disproportionately:
| Mnemonic | Instruction | Why it mattered |
|---|---|---|
MVCL | Move Long | Moved up to 16 MB in one instruction, versus the 256-byte ceiling of MVC |
CLCL | Compare Logical Long | Compared arbitrarily long storage areas without a hand-coded loop |
SRP | Shift and Round Decimal | Scaled packed decimal values by powers of ten with rounding — a single instruction for a common financial operation |
Optional 128-bit (extended precision) hexadecimal floating-point, a time-of-day clock (STCK), and block multiplexer channels rounded out the initial delta, along with instructions such as ICM, STCM, and LCTL. Not every model offered every optional feature.
Virtual Storage and the 1972 Turning Point
The System/370 that programmers actually remember arrived on August 2, 1972, when IBM announced “System/370 Advanced Function”: Dynamic Address Translation (DAT) hardware, delivered on the new Models 158 and 168 and retrofittable to some earlier machines, along with an entire generation of operating systems — DOS/VS, OS/VS1, OS/VS2, and VM/370.
Virtual storage transformed what assembler programmers had to know. Storage addresses were now virtual, translated through segment and page tables; privileged instructions for manipulating those tables and the translation lookaside buffer entered the language; and system programmers acquired a new class of problem — page faults, real versus virtual addresses, page fixing for I/O — that had no S/360 equivalent.
Assembler XF and Assembler H
Two assemblers defined the System/370 era, and the distinction is worth keeping straight.
Assembler XF (module name IFOX) was the compatible successor to Assembler F and the workhorse: it recognized the System/370 instruction set, reorganized Assembler F’s processing passes, and shipped as the common assembler across OS/VS, DOS/VS, and VM systems. It reportedly required a minimum partition of about 64 KB of virtual storage, with more recommended for larger assemblies. Assembler XF is the assembler in which IBM wrote MVS.
Assembler H was the premium, separately-priced program product, marketed on improved throughput for large assemblies and on more capable macro and diagnostic facilities. IBM did not publish the comparison as a reproducible benchmark — no baseline configuration, source size, or measurement methodology accompanies the claim — so it is best read as a product positioning statement rather than a measured result. Its documentation dates from the early 1970s (the OS Assembler H Programmer’s Guide, SC26-3759, is dated June 1972). Assembler H Version 2, announced in late 1981 with general availability in 1983, is the one that introduced the AMODE and RMODE directives for the coming Extended Architecture. It was later withdrawn from marketing and service, by which time HLASM had replaced it.
ASSIST and a Generation of Students
System/370 assembler is one of the few machine languages that a large fraction of computer science graduates once learned formally, and that is largely down to ASSIST — the Assembler System for Student Instruction and Systems Teaching — developed at Penn State University by Graham Campbell and John Mashey with student assistants and first released on August 1, 1972.
ASSIST assembled and then interpreted S/370 code, which let it do something the production assemblers could not: when a student program failed, ASSIST reported the instructions most recently executed instead of dumping raw storage. It was designed for low overhead on student-sized programs, it was free to universities, and it was reportedly implemented at roughly 300 institutions. On March 1, 1998, Penn State declared ASSIST no longer copyrighted, placing it in the public domain.
Extended Architecture and the End of the Line
S/370-XA shipped in early 1983 on the 3081 and 3083 processors, widening virtual addressing from 24 bits (16 MB) to 31 bits (2 GB) and rebuilding the I/O architecture around subchannels and the SSCH/TSCH instruction family. The 24-bit-to-31-bit transition dominated assembler practice for years, because existing code routinely stored flags or data in the unused high-order byte of a 32-bit address word — a trick that silently corrupted addresses once that byte became significant.
ESA/370, announced February 1988 for enhanced 3090 and 4381 models, added sixteen 32-bit access registers and data spaces, letting a single program address multiple 2 GB address spaces concurrently.
On September 5, 1990, IBM replaced System/370 with System/390 and the ESA/390 architecture. The instruction set continued forward; only the name changed.
Design Philosophy
System/370 assembler was designed on the assumption that assembler is where serious systems work happens, and it shows in three commitments.
Compatibility above all. Every architectural generation from S/360 forward executes its predecessor’s valid code. This was a commercial decision — customers with large assembler investments would not have upgraded otherwise — but it produced an engineering discipline almost unique in the industry, and it is the reason S/370-era code still runs.
Storage-to-storage operation. Unlike load/store RISC designs, S/370 operates directly on memory: MVC moves storage to storage, AP adds a packed decimal field in memory to another, ED formats a packed decimal number into a printable line with currency symbols and separators. A single S/370 instruction frequently does what several RISC instructions must accomplish together. Instructions are variable-length (2, 4, or 6 bytes) — the architecture is thoroughly CISC.
The macro assembler as a programming language. The S/370 macro facility is a full conditional-assembly language with typed variables, iteration, and branching, executed at assembly time. IBM used it to define the operating system interface itself: services were invoked not by documented calling conventions but by IBM-supplied macros (GETMAIN, OPEN, WAIT, ATTACH) that expanded into the correct parameter lists and Supervisor Call instructions. Learning S/370 assembler meant learning the macro library as much as the instruction set.
Key Features
Base-Displacement Addressing and USING
There is no program-counter-relative addressing in System/370. Every storage reference resolves through a base register, and the programmer is responsible for establishing and maintaining base registers. The USING directive is a promise to the assembler about what a register contains:
MYPROG CSECT
STM R14,R12,12(R13) Save caller's registers
LR R12,R15 Copy entry point address
USING MYPROG,R12 Tell assembler R12 addresses MYPROG
*
L R3,COUNT Assembler computes base+displacement
A R3,=F'1' Add literal one
ST R3,COUNT Store it back
*
COUNT DC F'0' Fullword counter
Because a displacement is only 12 bits, one base register covers just 4,096 bytes. Large control sections require multiple base registers, chained with successive USING statements — one of the era’s characteristic sources of complexity and of the ADDRESSABILITY ERROR diagnostic.
AMODE and RMODE
Introduced with Assembler H Version 2 for S/370-XA, these directives let a module declare how it expects to be addressed and where it may be loaded:
MYPROG CSECT
AMODE 31 Execute in 31-bit addressing mode
RMODE ANY May load above or below the 16 MB line
AMODE 24 / RMODE 24 preserved the old behavior for code that could not tolerate a significant high-order address byte. These two directives carried forward unchanged into ESA/390 and z/Architecture, which merely added AMODE 64.
Packed Decimal Arithmetic
Business computing on System/370 ran on packed decimal, not binary floating-point — each byte holds two decimal digits with the low-order nibble carrying the sign, and fields are 1 to 16 bytes long. This gives exact decimal arithmetic for money.
ZAP TOTAL,=P'0' Zero and add packed: clear TOTAL
AP TOTAL,AMOUNT Add AMOUNT to TOTAL
CP TOTAL,LIMIT Compare against LIMIT
BH OVERLMT Branch if high
ED OUTLINE,TOTAL Format for printing
*
TOTAL DS PL8 8-byte packed field, 15 digits + sign
AMOUNT DS PL5
LIMIT DC PL8'1000000'
The ED (Edit) instruction deserves particular note: driven by a pattern byte string, it converts a packed decimal field into printable characters with digit suppression, floating currency symbols, commas, and decimal points — in one instruction. SRP, one of the thirteen instructions new to S/370, scaled these values with rounding.
Long Move and Compare
MVCL and CLCL freed programmers from the 256-byte limit of MVC and CLC. They operate on even/odd register pairs holding address and length:
LA R2,TARGET R2 = destination address
L R3,TGTLEN R3 = destination length
LA R4,SOURCE R4 = source address
L R5,SRCLEN R5 = source length
MVCL R2,R4 Move up to 16 MB, pad if source shorter
The Macro and Conditional Assembly Language
Macro definitions use typed set symbols — SETA (arithmetic), SETB (boolean), SETC (character) — with AIF and AGO for control flow and &SYSNDX supplying a unique index per macro expansion so generated labels do not collide:
MACRO
&LABEL CLEAR &AREA,&LEN=256
LCLA &N
&N SETA &LEN
&LABEL DS 0H Anchor the caller's label
AIF (&N GT 256).LONG
XC &AREA(&N),&AREA Short form: single XC
AGO .DONE
.LONG ANOP
LA R0,&AREA Long form: R0/R1 = target, length
L R1,=A(&N)
SR R14,R14 R14/R15 = zero-length source,
SR R15,R15 so MVCL pads with X'00'
MVCL R0,R14
.DONE MEND
Supervisor Calls
Operating system services are reached through the SVC instruction, almost always via an IBM-supplied macro that builds the parameter list first:
GETMAIN R,LV=4096 Obtain 4 KB of storage (expands to SVC 10)
LR R9,R1 Address of obtained storage
...
FREEMAIN R,LV=4096,A=(R9) Release it (SVC 10 as well)
This macro-mediated interface is the reason assembler remained mandatory for system programming: for a number of services, the macro was the only published interface, with no equivalent available from COBOL or PL/I.
Evolution
The System/370 assembler’s evolution is mostly the story of the architecture beneath it, since the language deliberately never broke compatibility.
| Period | Architecture change | Assembler consequence |
|---|---|---|
| 1970 | S/370 base | Thirteen new instructions; MVCL, CLCL, SRP |
| 1972 | DAT / virtual storage | Privileged translation instructions; page-fault-aware system programming |
| 1983 | S/370-XA (31-bit) | AMODE/RMODE; the “16 MB line”; high-order byte cleanup |
| 1988 | ESA/370 | Access registers, data spaces, cross-memory services |
| 1990 | Replaced by S/390 | Instruction set continues; source stays valid |
| 1992 | HLASM ships | S/370 source assembles under a modern, maintained assembler |
The assemblers themselves consolidated rather than diversified: Assembler F gave way to Assembler XF, Assembler H Version 1 to Version 2, and both lines converged on HLASM in 1992. HLASM’s OPTABLE option can still restrict the recognized instruction set to earlier architecture levels — useful when maintaining code that must not accidentally acquire instructions the target machine lacks.
Current Relevance
System/370 as a hardware line ended in 1990, and no vendor sells an S/370 machine today. What remains is substantial nonetheless.
The source code still assembles. IBM High Level Assembler accepts System/370-era source, and z/Architecture executes the S/370 instruction set as a subset. Financial, insurance, and government installations continue to run assembler modules originally written in the 1970s and 1980s, often maintained by people who were not born when the code was authored. This is a documented consequence of IBM’s compatibility policy rather than an accident.
Emulation made it accessible. The Hercules emulator implements System/370, ESA/390, and z/Architecture in software; according to the project’s own documentation it runs on Linux, Windows, and macOS, with builds reported for other Unix-like systems. Paired with MVS 3.8j — a circa-1980 MVS release that is generally treated as freely redistributable — and packaged in community “turnkey” distributions, it gives anyone with a laptop a working System/370 with its assembler, JCL, TSO, and utilities. This is how most people who learn S/370 assembler today learn it.
The teaching tools survived. ASSIST entered the public domain in 1998 and remains available, including in Windows-hosted forms, and the z390 portable mainframe assembler and emulator — a Java implementation begun by Don Higgins, with roots in his MMS/370 product from around 1980 and the mid-1980s PC/370 — assembles and runs mainframe assembler on ordinary PCs, with optional ASSIST compatibility support.
The honest characterization is dormant, not dead: an enormous installed base of running code, a small maintenance community, active hobbyist and educational use, and essentially zero greenfield development.
Why It Matters
System/370 assembler matters for three reasons that outlast the hardware.
It is the ancestor of a still-living instruction set. The registers, addressing model, packed decimal instructions, and macro conventions a programmer learned for a 3033 in 1975 remain recognizable in HLASM code written for IBM Z in 2026. Very little else in computing offers that continuity, and studying S/370 assembler is the most direct way to understand why the modern mainframe looks the way it does.
It was the implementation language of an era’s infrastructure. MVS, VM/370, ACP/TPF, and large parts of CICS were written in it. The design decisions embedded in those systems — the SVC interface, the macro-defined OS API, control blocks as the public data model — shaped how a generation of enterprises built software, and their descendants still process a large share of the world’s banking, insurance, and airline transactions.
It taught machine organization to a generation. Through ASSIST and its imitators, System/370 assembler was the vehicle by which several hundred universities explained registers, addressing, and instruction execution. Many practitioners’ first encounter with what a computer actually does was an S/370 USING statement and a base register that had to be right.
The architecture was superseded, the name retired in 1990, and the assemblers replaced. The code, the instruction set, and the habits of thought are all still with us.
Timeline
Notable Uses & Legacy
MVS and the OS/VS Operating Systems
The MVS core (OS/VS2 Release 2, 1974) is documented as being written almost entirely in Assembler XF, with only a few modules in PL/S. OS/VS1, DOS/VS, and their supervisors, I/O supervisors, and dispatchers were likewise assembler code. Much of this lineage survives structurally in today's z/OS.
VM/370 Control Program
VM/370, announced with the 1972 virtual storage function, implemented its Control Program (CP) — the hypervisor that gave each user a simulated System/370 — in System/370 assembler, along with much of the CMS single-user operating system that ran inside those virtual machines.
Airline Reservation Systems (PARS/ACP/TPF)
IBM's Airlines Control Program and its Transaction Processing Facility successor, which ran (and in z/TPF form still run) reservation systems for major carriers, were built as assembler-language environments where applications themselves were commonly written in S/370 assembler to meet extreme transaction-rate requirements.
CICS Transaction Processing
CICS, the transaction monitor behind ATM networks, banking terminals, and order-entry systems, was substantially assembler-implemented during the System/370 era, and installations wrote assembler exits and performance-critical application modules against its macro-level interface. Many such modules remain in production decades later.
University Assembler Instruction via ASSIST
ASSIST, developed at Penn State and released in 1972, gave several hundred universities a fast S/370 assembler and interpreter with student-friendly diagnostics. For a generation of computer science graduates, System/370 assembler was the language in which machine organization was taught.
Hercules Emulator and the MVS 3.8j Hobbyist Community
Hercules, an open-source emulator of System/370, ESA/390, and z/Architecture, runs the MVS 3.8j release, which is generally treated as freely redistributable. Turnkey distributions bundle the OS with its assembler, letting hobbyists and students assemble and run genuine System/370 code on ordinary desktop machines.