HLASM Registers: General Purpose Registers, PSW, and Conventions
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.
* 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 12Standard 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:
| Register | Conventional Use |
|---|---|
| 0 | Parameter passing, return codes (caller/callee agree) |
| 1 | Address of parameter list (on entry to a called routine) |
| 2–11 | Work registers — free for program use |
| 12 | Primary base register (by convention) |
| 13 | Address of the current save area |
| 14 | Return address (address to branch to when done) |
| 15 | Entry 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:
LA 15,0 Return code 0 = success
BR 14 Return to callerRegister 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:
* 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 areaThe 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:
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 12If your program exceeds 4096 bytes, you need a second base register:
LA 11,2048(12) Reg 11 = reg 12 + 2048
USING MYPROG+2048,11 Second base covers next 4096 bytesThe 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 value | Meaning (for arithmetic) | Branch taken by |
|---|---|---|
| 0 | Result is zero | BZ (Branch if Zero) |
| 1 | Result is negative | BM (Branch if Minus) |
| 2 | Result is positive | BP (Branch if Plus) |
| 3 | Overflow | BO (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.
