IBM/3x0 Assembler
The assembly language of IBM's System/360, System/370 and System/390 mainframes: one upward-compatible language, defined in 1964, whose base registers, packed decimal and macro-driven system interface are still read by IBM's assembler today.
Created by IBM
IBM/3x0 Assembler is the name used here for the assembly language of IBM’s System/360 mainframe and its two direct successors, System/370 and System/390. “3x0” is an informal shorthand, not an IBM product name. It fits because the three architectures were built to be compatible: a program written for a System/360 in 1965 could, with few exceptions, be assembled and run on a System/370 in 1975 and a System/390 in 1995. Across those three decades the language kept one syntax, one register model and one way of reaching the operating system, through IBM-supplied macros.
The language was defined in 1964, the year IBM announced System/360. IBM sold several assemblers for it, sized to how much memory a customer had. Programmers called them by letter (Assembler D, E, F, H, XF), and some still called the language as a whole “BAL”, after the Basic Assembly Language of the smallest machines, even though that name strictly belongs to the restricted 1964 subset. Today it lives on in IBM High Level Assembler (HLASM), which still accepts source written in the 1960s. This page covers the language as a whole. The System/370 and S/390 generations and HLASM each have their own pages: Assembler (System/370), Assembler (S/390) and IBM HLASM Macro.
History & Origins
One architecture for every customer
Before 1964 IBM sold several incompatible lines of computers. Business customers used the 1401 family, scientific customers used the 7090 and 7094, and moving to a bigger machine often meant rewriting programs. System/360, announced on 7 April 1964, replaced them with a single architecture across a range of models. IBM’s history of the project names Gene Amdahl as chief architect and Fred Brooks as project leader. IBM says the name was meant to suggest one machine for all types of users.
For assembler programmers, the shared architecture meant a shared language. System/360 defined:
- Sixteen 32-bit general registers, numbered 0 to 15, and four floating-point registers
- Base-plus-displacement addressing, where an address is a register value plus a 12-bit displacement (0 to 4,095), optionally plus an index register
- 24-bit addresses, for at most 16 MB of storage
- Packed decimal instructions for business data, alongside binary integer and hexadecimal floating-point arithmetic
- EBCDIC characters, and instructions of 2, 4 or 6 bytes
The first models shipped in mid-1965.
The first manuals (1964)
IBM published the language before the hardware shipped. Two 1964 manuals define it.
The Basic Assembler Language manual describes the assembler for Basic Programming Support, IBM’s minimal software package. The copy that survives is a February 1965 “major revision” of an earlier edition, and it carries a 1964 copyright. The Basic Assembler would run on a System/360 with “8,192 bytes of storage”, the standard instruction set and a card reader-punch. It was very restricted. IBM’s own comparison chart shows it had no literals, no extended branch mnemonics, no macros, a single control section, symbols of at most six characters and expressions of at most three terms.
The Operating System/360 Assembler Language manual describes the full language. The surviving copy is an April 1965 minor revision, again with a 1964 copyright. Its first page sets out the aim: the language “enables the programmer to use all IBM System/360 machine functions, as if he were coding in System/360 machine language”. It allowed eight-character symbols, literals such as =F'1', multiple control sections and dummy sections, and a second part of the book is given over to the macro language.
Compatibility ran upward from the start. The 1965 manual says that OS/360 assemblers accept programs written for the Basic Assembler and for the 7090/7094 Support Package. That package included a cross-assembler, run on the older IBM 7090 and 7094, that let customers prepare System/360 programs before their new machines arrived.
A ladder of assemblers
IBM’s operating systems for the 360 ran on machines with very different amounts of memory, so IBM wrote several assemblers for the one language:
| Assembler | Ran under | Notes |
|---|---|---|
| Basic Assembler | Basic Programming Support | 8 KB machine; no macros |
| BOS assemblers | Basic Operating System/360 | Tape and disk versions, 16 KB |
| Assembler D | DOS/360 | Small DOS systems |
| Assembler E | OS/360 | 32 KB systems (guide C28-6595-1, 1966) |
| Assembler F | OS/360, DOS/360 | The standard OS/360 assembler; reportedly needed about 44 KB of a 64 KB machine |
The letters followed IBM’s memory-size designations of the time. They became the names programmers used for the products, and later assemblers kept the pattern: Assembler H, the faster program product of the early 1970s, and Assembler XF, the System/370 successor to F. Two System/360 models had their own variants. The Model 20 was not fully compatible and had its own assemblers, and the Model 44 assembler handled a “selected subset” of the language.
System/370 and System/390
System/370, announced on 30 June 1970, ran System/360 programs unchanged and added instructions to the language, including MVCL (move long), CLCL (compare logical long) and SRP (shift and round decimal). Virtual storage followed in 1972. System/370 Extended Architecture widened addresses from 24 to 31 bits, and Assembler H Version 2, generally available on 31 March 1983, added the AMODE and RMODE directives that let a program state which addressing mode it ran in and where it could be loaded.
System/390, introduced on 5 September 1990, was the last generation with a “3x0” name. The language carried on unchanged in form. IBM High Level Assembler reached general availability on 26 June 1992 and replaced Assembler H Version 2, which was withdrawn on 9 August 1994. When the 64-bit z/Architecture arrived in 2000, HLASM followed it, and the “3x0” era of naming ended, though not the language.
Design Philosophy
Assembler as the system language
On System/360 the assembler was not a last resort for speed. It was the language in which IBM wrote its operating systems and through which it published them. Operating system services were defined as assembler macro instructions such as GET, PUT, OPEN and GETMAIN. Each macro expanded into a parameter list and a Supervisor Call (SVC) instruction. High-level languages could reach only the services their compilers or libraries wrapped, so anything else had to be written as an assembler subroutine. Installations that wanted to change how the operating system behaved wrote exits, user routines that had to be coded in assembler.
The programmer manages addressing
There is no program-counter-relative addressing in System/360 and System/370. Every storage reference names a base register and a displacement. The USING statement tells the assembler what a register will contain at run time, and the assembler then works out base and displacement for each symbol. Keeping that promise true is the programmer’s job, and a wrong USING produces code that assembles cleanly and then reads the wrong storage.
Storage-to-storage operations
The instruction set is CISC. Many instructions work directly on memory. MVC copies up to 256 bytes from one place to another, AP adds one packed decimal field to another, and ED turns a packed number into a printable field with leading-zero suppression and punctuation, all as single instructions. The language was designed to make this kind of business record processing direct.
Key Features
Statement format
The format follows the 80-column punched card. A label starts in column 1, the operation code and operands follow, and comments come after the operands. Column 72 marks a continuation in the full language, and columns 73 to 80 hold sequence numbers so that a dropped card deck could be put back in order. An asterisk in column 1 makes a comment line.
Basic Assembler versus the full language
The difference between the two 1964 languages shows in small programs. The Basic Assembler had no literals and no extended mnemonics, so constants were declared by name and conditional branches were written with a numeric mask:
| |
The OS/360 assembler accepted the same program and added conveniences on top:
| |
Data definitions
The language has no data types in the high-level sense. Storage is declared with DC (define constant) and DS (define storage), and the type letter tells the assembler how to build the constant and what length and alignment to give it:
| |
Packed decimal
Business programs did their arithmetic in packed decimal, two digits per byte with a sign in the last half-byte. It gives exact decimal results for money:
| |
Macros and conditional assembly
The full language includes a macro facility that runs at assembly time. Macros take positional and keyword parameters and use typed variables (SETA for arithmetic, SETB for true/false, SETC for character strings), with AIF and AGO to branch inside the macro. The 1965 manual already describes keyword and mixed-mode macros and the system variables &SYSNDX, &SYSECT and &SYSLIST:
| |
A call such as INCR COUNT,BY=5 expands into the load, add and store at assembly time.
Hello, World
Under OS/VS1 or MVS, the classic first program writes to the operator’s console with the WTO (write to operator) macro. Most of the program is the standard linkage that saves and restores the caller’s registers:
| |
Evolution
The language grew mostly by adding instructions as the hardware grew, while existing programs stayed valid.
| Period | Change | Effect on the language |
|---|---|---|
| 1964 | System/360 | Basic Assembler and the full OS/360 language with macros |
| 1966 | Assembler E and F | Assembler F becomes the standard OS/360 assembler |
| 1970 | System/370 | New instructions such as MVCL, CLCL, SRP |
| 1972 | Virtual storage | New privileged instructions for system code |
| 1983 | 31-bit addressing (XA) | AMODE and RMODE in Assembler H Version 2 |
| 1990 | System/390 | Last “3x0” generation; source unchanged |
| 1992 | HLASM | One maintained assembler replaces Assembler H V2 |
Some things did change at the edges. Symbol names grew from six characters to eight and later to much longer names. The Basic Assembler’s alternate card format, with source starting in column 25, was dropped. Assembler H’s macro language was not fully compatible with Assembler F’s. Code that kept flags in the unused top byte of a 24-bit address had to be fixed for 31-bit addressing. But a working System/360 program written in the full language would, in most cases, still assemble.
Not everyone wanted to write assembler directly. Niklaus Wirth’s PL360 (1968) was designed as a machine-oriented language for System/360, with statements that map closely onto 360 instructions. IBM itself later rewrote much of its operating system code in PL/S, a systems language whose compiler it refused for decades to release to customers, apart from a short trial. Only much later did IBM offer current versions of PL/S to selected software vendors.
Current Relevance
No System/360, System/370 or System/390 is sold today, which is why the encyclopedia lists this language as historical. The code is another matter. IBM’s current mainframes run z/Architecture, which keeps the older instructions, and IBM High Level Assembler V1R6, generally available since 26 September 2008, is still supported by IBM on its current mainframe operating systems. A great deal of 1970s and 1980s assembler code is widely reported to still run in banks, insurers and government agencies, and HLASM can be told through its OPTABLE option to accept only an older instruction set when that code is maintained.
For people without a mainframe, the language is reachable through emulators. Hercules, begun by Roger Bowler in 1999, runs System/370, ESA/390 and z/Architecture software on personal computers, and freely available old operating system releases such as MVS 3.8j include an assembler. z390, written in Java by Don Higgins, assembles and runs mainframe assembler programs directly, and the public-domain ASSIST is still available for teaching.
Why It Matters
This was the language in which IBM’s mainframe software was first written. OS/360 and DOS/360 were originally written in it, as was VM’s Control Program, and MVS was written in it alongside PL/S. The interfaces of all of them were defined as its macros. That decision shaped how a generation of commercial programmers worked, and because the code was never thrown away, it still shapes the systems that run much of the world’s banking and transaction processing.
It is also a rare case of an assembly language that stayed stable for decades. Most instruction sets of 1964 are long gone. Programs in this one, written for machines with 8 KB or 64 KB of memory, can still be assembled with IBM’s current assembler. The base registers, USING statements and packed decimal fields that a programmer learned for a System/360 are recognisably the same ones in mainframe code being maintained today.
Timeline
Notable Uses & Legacy
OS/360 and DOS/360
IBM's System/360 operating systems were originally written in assembler, and their services were published as assembler macro definitions rather than as calls from high-level languages. Installation exits, the user routines that altered OS behaviour, also had to be coded in assembler. OS/360 Release 1 (available 31 March 1966) had about 400,000 source statements in 1,152 modules, according to a release history preserved on bitsavers.
MVS and VM/370
In the System/370 era the VM/370 Control Program was written in this assembler language. MVS (OS/VS2 Release 2, 1974) mixed assembler with IBM's internal systems language PL/S, but its system services were still published as assembler macros. Descendants of this code still run inside z/OS and z/VM.
Teaching machine organization with ASSIST
Penn State's ASSIST assembled and then interpreted student programs, reporting the last instructions executed instead of printing a storage dump. It was free to universities and was reportedly used at around 300 institutions, which made this the assembly language many computer science students learned first.
Plug-compatible and workalike mainframes
Because the instruction set was published in IBM's Principles of Operation, other manufacturers built machines that ran the same code. Amdahl's plug-compatible mainframes ran IBM's own operating systems, and the UNIVAC Series 90/60, 90/70 and 90/80, which descended from RCA's 360-compatible Spectra 70 line, were reportedly designed to accept IBM-format assembler source.
Emulation and hobbyist use
The open-source Hercules emulator and Don Higgins's z390, a Java assembler and emulator, let people assemble and run this language without a mainframe. Freely available old releases such as MVS 3.8j, run under Hercules, are how many people learn it today.