Jump to content

IBM Basic assembly language and successors

From Alfawiki
IBM Basic Assembly Language (BAL)
IndustryComputer software
Founded1964
Headquarters
Armonk
,
United States
ProductsAssembly languages and assemblers for IBM mainframes
ParentIBM

The IBM Basic Assembly Language and its descendants represent a collection of assembly languages and corresponding assemblers created for the IBM System/360 mainframe series and its subsequent platforms, including the IBM Z family.

Introduced in 1964, the original iteration called Basic Assembly Language (BAL) was a highly constrained assembly language tailored for System/360 machines equipped with minimal memory (8 KB) and limited input/output devices such as card readers, punches, and printers. This version was part of IBM Basic Programming Support (BPS/360) and was also incorporated within Basic Operating System/360 (BOS/360).

Subsequently, more sophisticated assembly languages were developed for the System/360 environment, enhancing usability and incorporating macro processing capabilities. This evolution continued through System/370 and later architectures, progressively extending the BAL syntax. While industry professionals sometimes refer to these collectively as "Basic Assembly Language" or simply "BAL," IBM officially designated them as "System/360 Assembler Language" or by the assembler name specific to each operating system or platform. Distinct assembler versions were identified by memory size suffixes such as Assembler E, F, H, among others, indicating their intended use cases. Programmers often group these under the acronym ALC (Assembly Language Coding) or refer to them generically as "the assembler."

The latest version in this lineage is the IBM High-Level Assembler (HLASM), which introduces advanced macro features and supports contemporary IBM mainframe operating systems.

General characteristics

As a form of assembly language, BAL directly utilizes the native instruction set architecture of IBM mainframes it operates on, including System/360, System/370, System/370-XA, ESA/370, ESA/390, and z/Architecture. Its successors similarly target their respective IBM mainframe instruction sets.

Source code written in assembler typically occupies significantly more lines than equivalent programs crafted in higher-level languages such as COBOL or Fortran. Traditionally, hand-written assembler code delivered superior execution speed; however, improvements in optimizing compilers and languages like C have diminished this advantage. Despite this, IBM continues to develop assembler tools that remain essential when utmost performance or precise hardware control is necessary. All IBM assemblers succeeding BAL incorporate powerful macro capabilities that allow for more concise source code.

Another important business rationale for employing assembler lies in accessing operating system functions that are not exposed through high-level languages. IBM mainframe operating system APIs are typically defined as assembly macros that trigger Supervisor Call (SVC) or Diagnose (DIAG) instructions to invoke OS services. High-level language programs frequently depend on assembler routines to interface with these system functions.

Assembler statement format

The structure of assembler statements mirrors the design of an 80-column punched card, although modern implementations have eased many original constraints:

  • An optional statement label starts at column 1 with an alphabetic character; later iterations expanded permissible characters to include (@, #, $, _) and extended label lengths from six characters to nearly unlimited.
  • The operation code or "mnemonic" follows the label after a space; initially restricted to machine instructions with 1–4 letters, this was later broadened to support mnemonics of eight or more characters.
  • The operand field comes after the operation code, separated by spaces; it may contain one or multiple operands and can be omitted depending on the instruction.
  • Optional comments are placed to the right of operands, separated by at least one blank space.
  • Basic Assembly Language did not permit statement continuation; subsequent versions indicate continuation lines by placing any non-blank character in column 72. In contrast, BAL required column 72 to remain blank.
  • Entire-card comments are denoted by an asterisk (*) positioned in column 1.
  • Columns 73 through 80 serve as the identification-sequence field, commonly used for sequence numbers facilitating punched card deck reordering.

Additionally, Basic Assembly provided an alternative format where statements began at column 25 so that assembled instructions could be punched into columns 1–24 on the same card; this feature was removed in later releases.

Types of instructions

Assembler source code primarily contains three categories of instructions.

Assembler instructions

Also known as directives or pseudo-operations, assembler instructions instruct the assembler on how to process the source code during assembly. For instance, CSECT initiates a code section; DSECT declares data structures without producing executable code; and DC defines constants embedded in the object code.

One essential directive is USING, which facilitates base-displacement addressing on the S/360 platform. It informs the assembler about which base register and offset to apply for relative addressing. An example syntax is:

<syntaxhighlight lang="text">

        USING base,reg-1,...,reg-n

</syntaxhighlight>

S/360 machine instructions encode a displacement value (ranging from 0 to 4095 bytes) relative to a base register's contents. Although newer systems introduced relative addressing modes, older formats are still widely used. The USING directive streamlines base register specification, yet programmers remain responsible for loading the base address into registers explicitly. The complementary DROP directive removes a previously established USING association.

Machine instructions (mnemonic)

Machine instructions correspond directly to mnemonics detailed in the Principles of Operation documentation. Examples include:

<syntaxhighlight lang="text">

      L     3,ZIGGY        Load fullword integer from 'ZIGGY' into register 3
      SLA   4,5            Shift register 4 left by 5 bits
      MVC   TARGET,SOURCE  Copy characters from 'SOURCE' to 'TARGET'
      AP    COUNT,=P'1'    Add packed decimal value 1 to 'COUNT'
      B     NEXT           Branch unconditionally to 'NEXT'
HERE  EQU   *               Define label at current location
      CLC   TARGET,=C'ADDRESS' Compare string at 'TARGET' with 'ADDRESS'
      BE    THERE          Branch if equal to label 'THERE'

</syntaxhighlight>

To improve clarity and facilitate register management, register mnemonics are often assigned through EQU statements rather than reserved keywords:

<syntaxhighlight lang="text">

R3    EQU  3
      ...
      L    R3,ZIGGY

</syntaxhighlight>

Prominent mnemonics include BALR (Branch And Link Register), which performs subroutine calls by saving return addresses; SVC (Supervisor Call); DIAG (Diagnose); and ZAP (Zero and Add Packed Decimal). Over time, many functions originally handled by BALR and SVC have been superseded by newer instructions such as BASR and specialized program call operations.

System/360 machine instructions vary in length from two to six bytes (equivalent to one to three halfwords). Initially, four instruction formats were defined; later architectures like z/Architecture expanded this set with additional formats.

Macros and conditional assembly

The original Basic Programming Support assembler did not support macros. With the introduction of Assembler D, developers gained the ability to encapsulate sequences of instructions into macros stored in libraries and invoked with parameters—functionality comparable to C language preprocessors. These macros incorporate conditional assembler directives such as AIF, allowing selective code generation based on macro parameters and greatly enhancing flexibility. Unlike C macros, assembler macros can extend over hundreds of lines.

Operating system macros

Applications frequently depend on operating system functions, which are accessed through standard macros similar to Unix system calls. For instance, within MVS (later known as z/OS), the STORAGE macro combined with OBTAIN dynamically allocates memory, whereas GET is used to fetch records from files.

These macros vary according to the operating system; IBM mainframe assembly languages do not provide OS-agnostic instructions or libraries for managing memory allocation or input/output operations. At the system service level, different IBM mainframe operating systems are incompatible—for example, the method for writing sequential files differs between z/OS and z/VSE.

Examples

The code snippet below demonstrates the logic "If SEX equals 'M', increase MALES; otherwise, increase FEMALES" using assembler instructions:

<syntaxhighlight lang="text">

         CLI   SEX,C'M'       Check if male
         BNE   IS_FEM         Branch if not male
         L     7,MALES        Load MALES counter into register 7
         LA    7,1(7)        Increment by 1
         ST    7,MALES        Store updated count
         B     GO_ON          Proceed further
IS_FEM   EQU   *              Label for female case
         L     7,FEMALES      Load FEMALES counter into register 7
         LA    7,1(7)         Increment by 1
         ST    7,FEMALES      Store updated count
GO_ON    EQU   *              Continue execution
*
MALES    DC    F'0'           Initialize MALES counter to zero
FEMALES  DC    F'0'           Initialize FEMALES counter to zero

</syntaxhighlight>

Below is a traditional "Hello, World!" program designed for IBM operating systems such as OS/VS1 or MVS, which outputs 'Hello, World!' on the operator console:

<syntaxhighlight lang="text">

HELLO    CSECT               Program named 'HELLO'
         STM   14,12,12(13)  Save registers 14 through 12
         LR    12,15         Load base register
         USING HELLO,12      Specify base register usage
         LA    15,SAVE       Load address of save area
         ST    15,8(13)      Set forward chain pointer
         ST    13,4(15)      Set backward chain pointer
         LR    13,15         Point R13 to save area
         WTO   'Hello, World!' Write To Operator (OS macro)
         L     13,4(13)      Restore caller's save area pointer
         XC    8(4,13),8(13) Clear forward chain pointers
         LM    14,12,12(13)  Restore saved registers
         DROP  12            Release base register
         SR    15,15         Set return code to zero
         BR    14            Return control to caller
*
SAVE     DS    18F           Define save area (18 fullwords)
         END  HELLO          Mark end of program

</syntaxhighlight>

The WTO macro triggers an operating system service. The preservation and restoration of registers enable this compact program to operate as a batch job through Job Control Language (JCL):

<syntaxhighlight lang="jcl"> // EXEC PGM=HELLO </syntaxhighlight>

Alternatively, it can be invoked as a subroutine call:

<syntaxhighlight lang="text">

CALL 'HELLO'

</syntaxhighlight>

Versions

IBM assemblers maintained considerable upward compatibility except for those used with the IBM System/360 Model 20. Differences primarily involved enhancements in expression handling and macro processing capabilities. Assemblers for OS/360 were initially differentiated based on their memory consumption requirements.

Basic Programming Support assembler

The assembler associated with BPS functioned as the essential "basic assembler," intended for 8 KB System/360 models (excluding Model 20). It did not support macro instructions or extended mnemonics (such as BH used instead of BC 2). This assembler processed only a single control section, prohibited dummy sections, restricted expressions to a maximum of three terms connected by '+', '-', and '*' operators, and lacked the ability to handle parenthesized expressions.

Basic Operating System assembler

The Basic Operating System provided two assembler variants, each requiring 16 KB of memory—one designed for tape storage and the other for disk storage.

Assembler D

Assembler D catered to DOS/360 environments with 16 KB memory availability. It was offered in two forms: a 10 KB version optimized for minimal memory systems, and a 14 KB version suited for systems with 24 KB memory. Additionally, an F-level assembler existed for DOS systems equipped with 64 KB or more, delivering nearly all functionalities typical of more advanced assemblers.

Assembler E and F

Designed for OS/360 systems with at least 32 KB of main storage, Assembler E required 15 KB of memory. In contrast, Assembler F operated under either DOS/360 or OS/360 on machines featuring 64 KB memory, consuming 44 KB itself. Both assemblers were standard components within OS/360 installations, with the particular assembler selected during system generation (SYSGEN).

Assembler H

Operating on OS/360 and successors, Assembler H offered enhanced speed and capabilities compared to Assembler F; however, its macro language was not fully backward compatible. Version 2, introduced in 1981, incorporated support for Extended Architecture (XA) through the AMODE and RMODE directives. This assembler was withdrawn from the market in 1994, with support concluding in 1995, when it was superseded by the High Level Assembler.

Assembler XF

Assembler XF represents an improved and largely compatible iteration of Assembler F that integrated System/370 architecture instructions. It served as a unified assembler across OS/VS, DOS/VS, and VM platforms, easing limitations on expressions and macro processing. The minimum virtual partition size required was 64 KB, though 128 KB was recommended for optimal operation.

High Level Assembler

High Level Assembler (HLASM) debuted in June 1992 as the successor to IBM's Assembler H Version 2. It became the primary assembler for System/370 and System/390 environments, supporting MVS, VSE, and VM operating systems. As of 2023, HLASM continues as IBM's assembler for z/OS, z/VSE, z/VM, and z/TPF running on z/Architecture mainframes. From Release 6 onward, it also supports Linux on IBM Z by generating ELF or GOFF object files.

John Robert Ehrman led HLASM's development at IBM, building upon enhancements contributed by Greg Mushial to Assembler H. Ehrman is recognized as the "father of high level assembler."

Despite its designation, HLASM does not include many features commonly found in high-level assemblers; the name likely reflects its expanded macro capabilities such as user-defined functions. It closely follows the design of Assemblers H and XF while incorporating modifications from the Stanford Linear Accelerator Center (SLAC). Notable features include explicit indication of CSECT/DSECT location counters, dependent and labelled USING statements with active USING lists, read/write cross-reference flags for variables, and support for mixed-case symbol naming.

The RSECT directive (Read-only Control Section) allows reentrancy checks on a per-section basis; this feature was previously undocumented and inconsistently implemented in Assembler H.

High Level Assembler Toolkit

The High Level Assembler Toolkit is an optional, separately sold extension for the High Level Assembler. It offers:

  • Structured programming macros such as IF/ELSE/ENDIF, DO/ENDDO, STRTSRCH/ORELSE/ENDLOOP/ENDSRCH, CASENTRY/CASE/ENDCASE, and SELECT/WHEN/OTHERWISE/ENDSEL.
  • A disassembler utility.
  • A Program Understanding Tool designed for software re-engineering tasks.
  • A Source XREF tool to facilitate cross-referencing.
  • An Interactive Debug Facility.
  • SuperC with enhancements, a tool for source code comparison.

7090/7094 Support Package assembler

The IBM 7090/7094 Support Package (SUPPAK) consists of three programs that allow System/360 software to be assembled, tested, and run on IBM 709, 7090, 7094, or 7094 II machines. This cross-assembler operates on IBM 7090 or 7094 hardware and was a key component during the System/360 development phase. It accommodates both six-bit BCD and eight-bit EBCDIC character encoding schemes.

IBM System/360 Model 20 assemblers

IBM provided two assembler variants for the Model 20: the Model 20 Basic Assembler and the Model 20 DPS/TPS Assembler. Both are limited to instructions unique to the Model 20 architecture, including specific opcodes like CIO, TIO, XIOB, SPSW, BAS, BASR, and HPR.

The Basic Assembler is a simplified adaptation of the System/360 Basic Assembler with symbol names restricted to four characters. It is intended for systems with minimal memory configurations as low as 4 KB and supports only IOCS macros. Card-based implementations use a two-pass assembly process involving card I/O operations, whereas tape-based versions perform one-pass assembly using magnetic tape as intermediate storage. Programs assembled via the CPS Assembler can address memory up to 16 KB.

The DPS/TPS assembler represents a more constrained form of the System/360 BPS/BOS Assembler, adapted specifically to the limitations of the Model 20.

IBM System/360 Model 44 PS assembler

The IBM System/360 Model 44 Programming System Assembler handles a subset of OS/360 and DOS/360 assembler languages but excludes support for macros and continuation statements. Nonetheless, it offers distinctive capabilities not found in other System/360 assemblers, such as instructions that modify a card image source dataset, named common areas, and implicit declarations of SETA variables.

It lacks support for storage-to-storage (SS) instructions as well as the convert to binary (CVB), convert to decimal (CVD), read direct (RDD), and write direct (WRD) instructions. Instead, it includes four instructions exclusive to the Model 44: Change Priority Mask (CHPM), Load PSW Special (LPSX), Read Direct Word (RDDW), and Write Direct Word (WRDW). Additionally, it provides directives that allow direct updates to the source program—a task generally performed by utility programs in other environments (SKPTO, REWND, NUM, OMIT, ENDUP).

IBM System/360 TSS assembler

The assembler designed for the System/360 Model 67 Time Sharing System incorporates directives tailored to unique TSS features. The PSECT directive produces a Prototype Control Section, which contains relocatable address constants along with modifiable data utilized by programs.

Assembler G

The "Assembler G" represents a collection of enhancements developed during the 1970s by the University of Waterloo, building upon the open-source Assembler F. These improvements primarily targeted input/output operations and buffering techniques, resulting in substantially faster assembly performance. It is important to note that "Assembler G" was not produced by IBM.

Non-IBM assemblers

A variety of assemblers compatible with IBM systems have been created for specific use cases:

  • The Unisys Univac 90/60, 90/70, and 90/80 line supports IBM-style assembler code and was engineered to emulate S/360 and S/370 architectures.
  • The Fujitsu BS2000 series, also emulating System/370 and sharing heritage with Univac, continues to be operational in some European regions.
  • Dignus LLC offers Systems/ASM, an assembler compatible with HLASM that can operate natively on IBM hardware or as a cross-assembler.
  • The freeware PC/370, initially developed by Don Higgins and later acquired by Micro Focus, provides another option.
  • Don Higgins also created z390, an open-source assembler combined with a System 390 emulator written in Java.
  • Penn State University produced ASSIST, which includes both a System 370 assembler and interpreter.
  • The Tachyon Assembler Workbench from Tachyon Software LLC supports multiple platforms such as Windows, Linux/x86, Linux for S/390 and zSeries, AIX, and Solaris.
  • The GNU Assembler (gas), integrated within the GNU Compiler Collection (gcc) for Linux on OS/390 and IBM Z, utilizes a distinct syntax that differs from other IBM assemblers.

Importance

At the outset, all System/360 operating systems were crafted using assembler language, with system interfaces defined through macros. High-level languages (HLLs) had limited access to system calls beyond their intrinsic capabilities; additional system functionalities required invoking assembler subroutines from HLL programs. IBM facilitated operating system customization via Exits, which were assembler routines provided by users to extend or modify OS behavior. Subsequently, IBM transitioned OS/360 development to the systems programming language PL/S, yet the PL/S compiler was only briefly available for external use and never fully released. As a result, assembler language maintained a prominent role on IBM platforms for an extended period.

See also

External links