HLASM Logical Operations: AND, OR, XOR, and Shift Instructions

TT

HLASM Logical Operations: AND, OR, XOR, and Shift Instructions

Logical and shift instructions manipulate individual bits in registers and storage. They are used for bit masking, flag testing, data packing, and fast multiplication by powers of two. This module covers AND, OR, XOR, and the four shift instructions.

AND Instructions

AND produces a 1 bit only where both operands have 1:

N — AND Register with Storage (fullword)

hlasm
         L     3,FLAGS         Load flags word
         N     3,MASK          Zero out all bits not in MASK
MASK     DC    X'0000000F'     Keep only low 4 bits

NR — AND Register with Register

hlasm
         NR    3,4             reg3 = reg3 AND reg4

NI — AND Immediate (single byte)

hlasm
         NI    FLAGS,X'FE'     Clear bit 0 (lowest bit) of FLAGS byte
FLAGS    DS    X

NC — AND Character (storage to storage)

hlasm
         NC    FIELD1(4),FIELD2   AND 4 bytes of FIELD1 with FIELD2

OR Instructions

OR produces a 1 bit where either operand has 1:

O — OR Register with Storage

hlasm
         L     3,STATUSWD      Load status word
         O     3,=X'00000001'  Set bit 0 (enable flag)
         ST    3,STATUSWD

OI — OR Immediate (single byte)

hlasm
         OI    FLAGS,X'80'     Set the high bit of FLAGS

OC — OR Character (storage to storage)

hlasm
         OC    FIELD(4),ORBITS OR 4-byte field with bit pattern

XOR Instructions

XOR produces 1 where operands differ, 0 where they are the same:

X — XOR Register with Storage

hlasm
         L     3,DATAWORD
         X     3,=X'FFFFFFFF'  Invert all bits (ones complement)

XI — XOR Immediate

hlasm
         XI    FLAGBYTE,X'01'  Toggle bit 0 (flip it)
FLAGBYTE DC    X'00'

XR — XOR Register with Register

hlasm
         XR    3,3             Fast way to zero register 3 (x XOR x = 0)

Shift Instructions

Shifts move bits left or right within a register:

SLL — Shift Left Logical

hlasm
         L     3,VALUE
         SLL   3,2             Shift left 2 bits = multiply by 4
* SLL n is equivalent to multiplying by 2^n (for positive values)

SRL — Shift Right Logical

hlasm
         L     3,VALUE
         SRL   3,1             Shift right 1 bit = divide by 2 (unsigned)
* Zeros are shifted in from the left

SLA — Shift Left Arithmetic

hlasm
         L     3,SIGNEDVAL
         SLA   3,1             Multiply signed value by 2, preserve sign
* Bits shifted out must match the sign bit, else overflow

SRA — Shift Right Arithmetic

hlasm
         L     3,SIGNEDVAL
         SRA   3,2             Divide signed value by 4, preserve sign
* Sign bit is propagated (sign extension)

SLDL/SRDL — Shift Long (double register)

hlasm
         SRDL  2,4             Shift 64-bit value in regs 2-3 right by 4 bits
         SLDL  2,8             Shift 64-bit value in regs 2-3 left by 8 bits

Practical Examples

Extracting a Bit Field

hlasm
* Extract bits 4-7 (second nibble) from a byte
         IC    3,DATABYTE      Insert character (load byte) into reg 3
         SRL   3,4             Shift right 4 to bring bits 4-7 to position 0-3
         N     3,=F'15'        AND with 0x0F to clear upper bits
* reg 3 now contains the second nibble value (0-15)
DATABYTE DC    X'A5'           Example: nibble 2 = A = 10

Setting and Testing Flags

hlasm
STATUS   DC    X'00'

* Set flag bits using OI
         OI    STATUS,X'80'    Set bit 7 (high bit = "initialized")
         OI    STATUS,X'40'    Set bit 6 ("data loaded")

* Test a flag using TM (Test under Mask)
         TM    STATUS,X'80'    Test bit 7
         BZ    NOTINIT         Branch if bit 7 = 0 (not initialized)
         BO    ISINIT          Branch if bit 7 = 1 (all mask bits set)

* Clear a flag using NI
         NI    STATUS,X'7F'    Clear bit 7 (AND with 01111111)

Fast Multiplication by Power of 2

hlasm
* Multiply by 8 = shift left 3
         L     3,COUNT
         SLL   3,3             reg3 = COUNT * 8 (faster than M instruction)

* Compute array offset: index * 12 bytes per element
         L     3,INDEX
         LR    4,3
         SLL   4,3             index * 8
         SLL   3,2             index * 4 (original index in reg 3)
         AR    3,4             index * 4 + index * 8 = index * 12

Frequently Asked Questions

Q: What is the difference between SRL and SRA? SRL (Shift Right Logical) always shifts in zero bits from the left regardless of the sign. SRA (Shift Right Arithmetic) shifts in copies of the sign bit — for negative numbers, 1s are shifted in from the left, preserving the two's complement representation. Use SRL for unsigned values and bit manipulation. Use SRA for signed integer division by powers of two.

Q: When should I use XR reg,reg to zero a register? XR 3,3 is a common idiom to zero a register. It is equivalent to LA 3,0 or SR 3,3. The XOR approach has the advantage of not setting the condition code the same way — SR 3,3 sets CC=0 (zero result), which is actually useful. XR 3,3 also sets CC=0. Both are single-instruction register zeroing operations. The SR approach is slightly more readable.

Q: How does TM (Test under Mask) work and when should I use it? TM storage,mask ANDs the byte at the storage address with the mask and sets the condition code based on the result: CC=0 if all tested bits are zero, CC=1 if some bits are one and some zero, CC=3 if all tested bits are one. Use BZ to branch if the flag is clear, BO to branch if all bits are set. TM is the standard way to test flag bytes in z/OS control blocks and your own status fields.


Part of HLASM Mastery Course — Module 7 of 22.