HLASM Registers: General Purpose Registers, PSW, and Conventions

TT

HLASM Registers: General Purpose Registers, PSW, and Conventions

Registers are the fastest storage on the z/Architecture processor. Understanding which registers exist, what they contain, and how they are used by convention is fundamental to writing correct HLASM programs.

General-Purpose Registers

IBM Z has 16 general-purpose registers (GPRs), numbered 0 through 15. In 31-bit mode (AMODE 31), each register holds 32 bits. In 64-bit mode (AMODE 64), each register holds 64 bits.

hlasm
* Registers are referenced by number in HLASM:
         L     3,MYDATA        Load register 3 from storage
         AR    5,6             Add register 6 to register 5
         LR    12,15           Copy register 15 to register 12

Standard Register Usage Conventions

IBM defines a standard usage convention for mainframe programs. Following it ensures your code interoperates with COBOL, PL/I, and system services:

RegisterConventional Use
0Parameter passing, return codes (caller/callee agree)
1Address of parameter list (on entry to a called routine)
2–11Work registers — free for program use
12Primary base register (by convention)
13Address of the current save area
14Return address (address to branch to when done)
15Entry point address (on entry); return code (on exit)

These conventions apply to programs using the Standard Linkage Convention. Your code must preserve registers 2–12 across calls — whatever values you receive in those registers, you must restore before returning.

Registers 14 and 15: Entry and Exit

When a program is called (via CALL in COBOL or BALR/BASR in assembler):

  • Register 14 contains the return address — the address to branch to when done
  • Register 15 contains the entry point address of the called program

On exit, load your return code into register 15:

hlasm
         LA    15,0            Return code 0 = success
         BR    14              Return to caller

Register 13: The Save Area

Register 13 always points to an 18-fullword (72-byte) save area. This is the key to the register save chain that links all active programs:

hlasm
* Standard entry sequence:
MYPROG   CSECT
         STM   14,12,12(13)    Save caller's regs 14-12 into caller's save area
         LR    12,15           Set up base register
         USING MYPROG,12
         LA    11,SAVEAREA     Address our own save area
         ST    13,4(11)        Store caller's save area address in our save area +4
         ST    11,8(13)        Store our save area address in caller's save area +8
         LR    13,11           Register 13 now points to our save area

The save area layout:

  • Word 1 (offset 0): Reserved
  • Word 2 (offset 4): Address of previous (caller's) save area
  • Word 3 (offset 8): Address of next (called routine's) save area
  • Words 4–18 (offset 12–68): Saved registers 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12

Setting Up a Base Register

Every HLASM program needs a base register for the assembler to generate correct addresses. The standard pattern:

hlasm
MYPROG   CSECT
         STM   14,12,12(13)    Save registers
         LR    12,15           Load entry point address into reg 12
         USING MYPROG,12       Tell assembler: reg 12 = address of MYPROG
* Now all labels within 4096 bytes of MYPROG can be addressed via reg 12

If your program exceeds 4096 bytes, you need a second base register:

hlasm
         LA    11,2048(12)     Reg 11 = reg 12 + 2048
         USING MYPROG+2048,11  Second base covers next 4096 bytes

The Program Status Word (PSW)

The PSW is a 16-byte control register (not one of the 16 GPRs) that contains:

  • Instruction address — the address of the next instruction to execute
  • Condition code (CC) — 2-bit field set by arithmetic, compare, and test instructions
  • AMODE bit — 31-bit or 64-bit addressing mode
  • Problem/Supervisor state bit — user or kernel mode

The condition code takes one of four values (0, 1, 2, 3) and determines which branch is taken:

CC valueMeaning (for arithmetic)Branch taken by
0Result is zeroBZ (Branch if Zero)
1Result is negativeBM (Branch if Minus)
2Result is positiveBP (Branch if Plus)
3OverflowBO (Branch if Overflow)

Floating-Point and Access Registers

z/Architecture also has:

  • 16 floating-point registers (FPR0–FPR15) for floating-point arithmetic
  • 16 access registers (AR0–AR15) for AR mode addressing (rarely used in application code)
  • 16 vector registers (V0–V31, 128-bit each) for SIMD operations

These are used in specialised applications. Most HLASM programs only use the 16 GPRs.

Frequently Asked Questions

Q: Why does STM 14,12,12(13) save registers 14 through 12 instead of 14 through 15? The STM (Store Multiple) instruction saves a range of registers wrapping around if necessary. STM 14,12 saves registers 14, 15, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 — that's 15 registers total. Register 13 is not saved because it is the save area pointer itself (its old value is preserved by the chain mechanism). This is the standard entry sequence used in virtually every HLASM routine.

Q: What happens if I don't restore registers before returning? If your routine modifies registers 2–12 and doesn't restore them, the caller receives corrupted register values. Since the caller may be using those registers for its own computation, the results are unpredictable — typically an abend (abnormal end) or incorrect results. Always use STM on entry to save registers and LM on exit to restore them.

Q: What is the difference between LA and L for loading values? LA reg,value (Load Address) loads a 12-bit immediate value (0–4095) directly into a register without accessing storage. It's fast and doesn't require a defined constant. L reg,label loads a 32-bit fullword from storage at the given address into the register. Use LA for small constants and addresses; use L for larger values stored in DC constants.


Part of HLASM Mastery Course — Module 4 of 22.