HLASM Fixed-Point Arithmetic: L, ST, A, S, M, D Instructions

TT

HLASM Fixed-Point Arithmetic: L, ST, A, S, M, D Instructions

Fixed-point arithmetic in HLASM operates on binary integers in general-purpose registers. The instructions are compact and fast — each performs exactly one operation on register-sized values. This module covers the most important arithmetic instructions with practical examples.

Loading Data into Registers

Before performing arithmetic, you need to load values into registers.

L — Load (fullword)

hlasm
         L     3,MYDATA        Load 4-byte fullword from MYDATA into reg 3
MYDATA   DC    F'12345'

LH — Load Halfword (sign-extended)

hlasm
         LH    3,MYHALFWD      Load 2-byte halfword, sign-extend to 32 bits
MYHALFWD DC    H'100'

LA — Load Address (immediate 0–4095)

hlasm
         LA    3,42            Load immediate value 42 into reg 3 (no storage access)
         LA    4,MYTABLE       Load address of MYTABLE into reg 4

LR — Load Register

hlasm
         LR    5,3             Copy register 3 to register 5

LM — Load Multiple

hlasm
         LM    2,6,SAVEAREA+20   Load registers 2–6 from consecutive fullwords

Storing Registers to Storage

ST — Store (fullword)

hlasm
         ST    3,RESULT        Store register 3 as 4-byte fullword at RESULT
RESULT   DS    F

STH — Store Halfword

hlasm
         STH   3,HALFRESULT    Store low 2 bytes of reg 3 at HALFRESULT
HALFRESULT DS  H

STM — Store Multiple

hlasm
         STM   14,12,12(13)    Store regs 14–12 into save area

Addition and Subtraction

A — Add (register + fullword storage)

hlasm
         L     3,VALUE1        Load first value
         A     3,VALUE2        Add fullword from storage: reg3 = reg3 + VALUE2
VALUE1   DC    F'100'
VALUE2   DC    F'250'
* reg 3 now contains 350

AR — Add Register

hlasm
         AR    3,4             reg3 = reg3 + reg4

AH — Add Halfword

hlasm
         AH    3,HALFVAL       reg3 = reg3 + sign-extended halfword
HALFVAL  DC    H'50'

S — Subtract (register - fullword storage)

hlasm
         L     3,TOTAL         Load total
         S     3,DISCOUNT      Subtract discount: reg3 = reg3 - DISCOUNT

SR — Subtract Register

hlasm
         SR    3,4             reg3 = reg3 - reg4

Multiplication

Multiplication uses an even-odd register pair. The instruction specifies the even register:

M — Multiply (fullword)

hlasm
         L     3,ZERO          Clear reg 3 (high-order of pair)
         L     4,QUANTITY      Load quantity into reg 4 (low-order)
* M uses even register (2, 4, 6, etc.) as base of even-odd pair:
         M     2,=F'0'         Wrong — need even reg
         L     2,ZERO
         L     3,QUANTITY
         M     2,PRICE         reg 2-3 pair = reg3 * PRICE (64-bit result in regs 2,3)
QUANTITY DC    F'150'
PRICE    DC    F'25'
ZERO     DC    F'0'
* After M: reg2 contains high-order 32 bits, reg3 contains low-order 32 bits
* For most practical multiplications, reg2 = 0

MH — Multiply Halfword (single register, no pair needed)

hlasm
         L     3,QUANTITY
         MH    3,RATE          reg3 = reg3 * halfword(RATE)
RATE     DC    H'12'
* MH result fits in 32 bits — use when result won't overflow

MR — Multiply Register (even-odd pair)

hlasm
         SR    2,2             Clear high register
         L     3,QUANTITY
         MR    2,5             regs 2-3 = reg3 * reg5

Division

Division also uses an even-odd register pair — the dividend is in the pair, quotient in odd register, remainder in even register:

D — Divide

hlasm
         L     2,ZERO          High-order of dividend (usually 0)
         L     3,TOTALAMT      Low-order of dividend
         D     2,DIVISOR       reg3 = quotient, reg2 = remainder
TOTALAMT DC    F'1000'
DIVISOR  DC    F'7'
ZERO     DC    F'0'
* After D: reg3 = 142 (quotient), reg2 = 6 (remainder)

DR — Divide Register

hlasm
         SR    2,2
         L     3,DIVIDEND
         DR    2,5             reg3 = reg3 / reg5, reg2 = remainder

Practical Example: Computing an Average

hlasm
* Compute average of three values
AVERAGE  CSECT
         STM   14,12,12(13)
         LR    12,15
         USING AVERAGE,12
         LA    13,SAVEAREA
*
         L     3,VAL1          Load first value
         A     3,VAL2          Add second
         A     3,VAL3          Add third (sum in reg 3)
         SR    2,2             Clear high register for divide
         D     2,=F'3'         Divide by 3: reg3 = average
         ST    3,RESULT        Store result
*
         L     14,12(13)
         LM    0,12,20(13)
         BR    14
*
VAL1     DC    F'90'
VAL2     DC    F'85'
VAL3     DC    F'95'
RESULT   DS    F
SAVEAREA DS    18F
         END   AVERAGE

Frequently Asked Questions

Q: What is the condition code set by arithmetic instructions? Add and subtract instructions set the condition code: CC=0 (result is zero), CC=1 (result is negative), CC=2 (result is positive), CC=3 (overflow). Multiply and divide do not set the condition code. After an arithmetic instruction, use branch mnemonics BZ, BM, BP, BO to test the result.

Q: Why do M and D use even-odd register pairs? Multiplication of two 32-bit values can produce a 64-bit result. IBM Z stores the 64-bit result across two 32-bit registers — the even register holds the high-order 32 bits, the odd register holds the low-order 32 bits. Division reverses this: the 64-bit dividend is in the even-odd pair, and the results (quotient and remainder) fit in separate 32-bit registers.

Q: How do I handle overflow in addition? After an A or AR instruction, CC=3 indicates fixed-point overflow. Use BO (Branch on Overflow) to detect it. Many production programs use SPM (Set Program Mask) to enable the Fixed-point Overflow Program Check interrupt, which generates a 0C8 abend on overflow instead of silently wrapping. For financial calculations, always validate that operands and results stay within bounds.


Part of HLASM Mastery Course — Module 6 of 22.