HLASM Branching: BC, BCR, BXH, BXLE and the Condition Code

TT

HLASM Branching: BC, BCR, BXH, BXLE and the Condition Code

Branching is how HLASM implements conditionals and loops. Unlike high-level languages with if and while, HLASM branches based on the condition code — a 2-bit field in the PSW set by most arithmetic and compare instructions. This module explains the condition code, the BC instruction, and common looping patterns.

The Condition Code

The Condition Code (CC) is a 2-bit field in the PSW. It takes values 0, 1, 2, or 3. Different instructions set it differently:

After arithmetic (A, S, AR, SR):

CCMeaning
0Result is zero
1Result is negative
2Result is positive
3Fixed-point overflow

After compare (C, CR, CH, CL, CLR):

CCMeaning
0Operand 1 = Operand 2
1Operand 1 < Operand 2
2Operand 1 > Operand 2
3Not used by compare

After Test under Mask (TM):

CCMeaning
0All tested bits are zero
1Some bits zero, some one
3All tested bits are one

The BC Instruction

BC mask,address branches to address if the condition code matches the mask. The mask is a 4-bit value where each bit corresponds to a CC value:

Mask bitCondition
Bit 0 (value 8)CC = 0
Bit 1 (value 4)CC = 1
Bit 2 (value 2)CC = 2
Bit 3 (value 1)CC = 3

So BC 8,LABEL branches if CC=0. BC 12,LABEL branches if CC=0 or CC=1 (mask = 8+4 = 12).

Extended Mnemonics

Instead of remembering mask values, use the extended mnemonics:

After arithmetic:

hlasm
         A     3,VALUE
         BZ    ISZERO          Branch if zero     (BC 8)
         BM    ISNEG           Branch if minus    (BC 4)
         BP    ISPOS           Branch if plus     (BC 2)
         BO    OVERFLOW        Branch if overflow (BC 1)
         BNZ   NOTZERO         Branch if not zero (BC 7)
         BNP   NOTPOS          Branch if not positive (BC 13)

After compare:

hlasm
         C     3,LIMIT
         BE    EQUAL           Branch if equal    (BC 8)
         BL    LESSTHAN        Branch if less     (BC 4)
         BH    GREATERTHAN     Branch if high     (BC 2)
         BNE   NOTEQUAL        Branch if not equal (BC 7)
         BNL   NOTLESS         Branch if not less (BC 11)
         BNH   NOTHIGH         Branch if not high (BC 13)

Unconditional:

hlasm
         B     ANYWHERE        Always branch (BC 15)
         NOP   *+4             No operation, never branch (BC 0)

BCR — Branch on Condition to Register

BCR mask,register branches to the address in the register:

hlasm
         BCR   15,14           Unconditional branch to reg 14 (return)
         BR    14              Same thing — extended mnemonic
         BCRE  8,14            Branch to reg 14 if CC=0

Implementing Conditionals

hlasm
* if (value > 0) goto POSITIVE
         L     3,VALUE
         C     3,=F'0'
         BH    POSITIVE
         B     NOTNEG
POSITIVE DS    0H              ...positive code here...
NOTNEG   DS    0H

* if (counter == limit) goto DONE
         C     5,LIMIT
         BE    DONE

Looping with BXH and BXLE

BXH reg1,reg2,label — Branch on indeX High:

  • Add reg2 (increment) to reg1
  • Compare reg1 to reg3 (or reg2+1 if reg2 is odd... see note)
  • Branch if reg1 > comparand

BXLE reg1,reg2,label — Branch on indeX Low or Equal:

  • Add reg2 to reg1
  • Branch if reg1 <= comparand
hlasm
* Loop from 0 to 9 using BXLE
* reg 5 = loop index (starts at 0)
* reg 6 = increment (1)
* reg 7 = limit (9)
         LA    5,0             Initialize index
         LA    6,1             Increment by 1
         LA    7,9             Loop until index > 9
MYLOOP   DS    0H
*        ... loop body using reg 5 as index ...
         BXLE  5,6,MYLOOP      Add 1 to reg5, branch back if reg5 <= 9

Simple Counted Loop

hlasm
* Process 10 elements in a table (4 bytes each)
         LA    4,TABLE         Point to start of table
         LA    5,10            Loop counter = 10
LOOP     DS    0H
         L     3,0(4)          Load current element
*        ... process reg 3 ...
         LA    4,4(4)          Advance pointer by 4 bytes
         BCT   5,LOOP          Decrement reg 5, branch if not zero
* BCT = Branch on CounT (equivalent to S reg,=F'1' then BNZ)
TABLE    DS    10F

BCT reg,label decrements the register and branches if the result is non-zero. It is the most common counted-loop instruction.

Frequently Asked Questions

Q: What is DS 0H and why is it used as a branch target? DS 0H is a zero-length halfword alignment directive. It defines a label at the current location counter without generating any data. The 0H ensures the next instruction starts on a halfword boundary (which instructions must be). Using DS 0H as a branch target is the standard way to label a point in code without labelling an instruction directly — it makes the intent clearer and handles alignment automatically.

Q: What is the difference between B (unconditional branch) and NOP? B label is BC 15,label — the mask is all ones (1111), so it always matches. It always branches. NOP is BC 0,label — the mask is all zeros (0000), so it never matches. It never branches. NOP is occasionally used as a placeholder or for debugging (you can patch a B to NOP to skip a branch temporarily).

Q: Can I nest loops in HLASM? Yes. You save the outer loop counter in a register or storage, run the inner loop, then restore the outer counter. Since you have 16 registers, simple nested loops can use different registers for each loop counter without any storage saves. For more than two or three levels of nesting, save loop state in named storage areas.


Part of HLASM Mastery Course — Module 8 of 22.