64-bit HLASM: z/Architecture Instructions and AMODE 64
64-bit HLASM: z/Architecture Instructions and AMODE 64
IBM z/Architecture introduced 64-bit registers and instructions in 2000 (z900). Today, most z/OS software runs in AMODE 31 or AMODE 64. This module covers the 64-bit instruction set, addressing modes, and how to write or migrate HLASM code for 64-bit operation.
64-bit Registers
In z/Architecture, all 16 general-purpose registers are 64 bits wide. The 32-bit instructions (L, ST, A, S, etc.) use only the low 32 bits. The 64-bit instructions operate on the full 64-bit register.
* 32-bit load — high 32 bits of register are sign-extended
L 3,MYFW Load 32-bit value, sign-extend to 64 bits
* 64-bit load — full 64-bit register is loaded
LG 3,MYDW Load 64-bit value from doublewordAddressing Modes
| AMODE | Max address | Instruction pointer |
|---|---|---|
| 24 | 16MB (X'FFFFFF') | 24-bit PSW |
| 31 | 2GB (X'7FFFFFFF') | 31-bit PSW |
| 64 | 16EB (X'7FFFFFFFFFFFFFFF') | 64-bit PSW |
Most z/OS applications use AMODE 31. Use AMODE 64 when:
- You need to address more than 2GB of virtual storage
- You're writing new code and want to follow modern z/OS conventions
- You're calling 64-bit system services
MYPROG CSECT
MYPROG AMODE 64
MYPROG RMODE ANY64-bit Load and Store Instructions
* Load 64-bit (G = "Gigabyte", actually meaning 64-bit)
LG 3,MYDW Load 64-bit doubleword into reg 3
LGR 3,4 Load register: reg3 = reg4 (64-bit)
LGF 3,MYFW Load 32-bit fullword, sign-extend to 64-bit
LGHI 3,42 Load halfword immediate (sign-extended to 64-bit)
* Store 64-bit
STG 3,MYDW Store 64-bit reg 3 to doubleword
MYDW DS D 8-byte doubleword64-bit Arithmetic
* Add
AGR 3,4 reg3 = reg3 + reg4 (64-bit)
AG 3,MYDW reg3 = reg3 + doubleword from storage
* Subtract
SGR 3,4 reg3 = reg3 - reg4 (64-bit)
SG 3,MYDW
* Multiply (no pair needed — result fits in 64 bits for most cases)
MSGR 3,4 reg3 = reg3 * reg4 (signed 64-bit, low 64 bits)
MSG 3,MYDW
* Multiply full (128-bit result in register pair)
MLGR 2,4 regs 2-3 = reg3 * reg4 (unsigned 128-bit)
* Divide (128-bit / 64-bit)
DLGR 2,4 reg3 = quotient, reg2 = remainder64-bit Compare
CGR 3,4 Compare 64-bit registers (signed)
CG 3,MYDW Compare reg 3 with doubleword storage
CLGR 3,4 Compare 64-bit registers (unsigned)64-bit Addressing
In AMODE 64, addresses are 64 bits. The base-displacement addressing still works the same way, but the base register holds a 64-bit address:
MYPROG CSECT
MYPROG AMODE 64
STG 14,8(13) Store 64-bit return address
LARL 12,MYPROG Load relative address into reg 12 (AMODE 64 friendly)
USING MYPROG,12LARL (Load Address Relative Long) loads an address relative to the current instruction, without needing a base register. It's the preferred way to set up a base register in AMODE 64.
STMG / LMG — 64-bit Save and Restore
* AMODE 64 standard entry
MYPROG64 CSECT
MYPROG64 AMODE 64
STMG 14,12,144(13) Save 64-bit registers 14-12 (offset 144 in save area)
LARL 12,MYPROG64
USING MYPROG64,12
LA 11,SAVEAREA
STG 13,128(11) Store caller's save area (64-bit pointer)
STG 11,136(13) Forward chain
LGR 13,11The 64-bit save area is 216 bytes (larger than the 72-byte 31-bit save area).
Migrating 31-bit Code to 64-bit
Common changes required:
| 31-bit | 64-bit equivalent |
|---|---|
L reg,addr | LG reg,addr (if pointer) |
ST reg,addr | STG reg,addr (if pointer) |
STM 14,12,12(13) | STMG 14,12,144(13) |
LM 14,12,12(13) | LMG 14,12,144(13) |
BALR 12,0 | LARL 12,label |
DC A(label) | DC AD(label) (8-byte address constant) |
DS A | DS AD |
Key principle: change storage area addresses (pointers) to 64-bit; leave data values (amounts, counts) as 32-bit unless they genuinely exceed 32-bit range.
Frequently Asked Questions
Q: Do I need to rewrite existing AMODE 31 programs for 64-bit? Not necessarily. Most AMODE 31 programs continue to run correctly on z/Architecture without change. AMODE 64 is needed when you need to address more than 2GB of virtual storage, when called by an AMODE 64 program that expects 64-bit linkage, or when using 64-bit system services. IBM recommends new programs use AMODE 64 for future-proofing, but migrating working AMODE 31 code purely for the sake of it is rarely justified.
Q: Why is the offset for STMG 144 instead of 12? The 64-bit linkage convention uses a larger save area (216 bytes vs 72 bytes). In the 64-bit save area, the register save area starts at offset 144 (not offset 12 as in 31-bit). Registers are 8 bytes each in 64-bit mode, so 14 registers (14,15,0,1,...,12) × 8 bytes = 112 bytes, stored at offset 144. Using offset 12 for STMG would overwrite the save area chain pointers — a common bug when converting code.
Q: Can a 64-bit HLASM routine call a 31-bit routine?
Yes, using BASSM 14,15 which saves and sets the addressing mode. The called routine runs in AMODE 31. On return, the mode reverts to AMODE 64. Mixed-mode calling works but requires careful management of pointer sizes — a 64-bit address passed to a 31-bit routine will have its high 33 bits ignored, potentially causing addressing errors.
Part of HLASM Mastery Course — Module 20 of 22.
