HLASM Compare Instructions: CLC, CLI, CR, C and Condition Codes

TT

HLASM Compare Instructions: CLC, CLI, CR, C and Condition Codes

Compare instructions set the condition code without modifying any operands. They are the foundation of all conditional logic in HLASM. This module covers every major compare instruction with practical examples.

C — Compare (register vs fullword storage)

C reg,storage compares a 32-bit register with a fullword in storage using signed arithmetic:

hlasm
         L     3,AMOUNT
         C     3,LIMIT
         BH    TOOLARGE        Branch if AMOUNT > LIMIT
         BL    TOOSMALL        Branch if AMOUNT < LIMIT
         BE    EXACT           Branch if AMOUNT == LIMIT
LIMIT    DC    F'1000'

CR — Compare Register

CR reg1,reg2 compares two registers (signed):

hlasm
         CR    3,4             Compare reg 3 with reg 4
         BNE   DIFFER          Branch if not equal

CH — Compare Halfword

CH reg,storage compares a 32-bit register with a sign-extended 16-bit halfword:

hlasm
         LH    3,SHORTVAL
         CH    3,=H'255'
         BL    UNDER256
SHORTVAL DC    H'300'

CL — Compare Logical (unsigned)

CL reg,storage compares as unsigned 32-bit values. Use CL instead of C when working with addresses or bit patterns:

hlasm
         L     3,ADDRESS1
         CL    3,ADDRESS2      Unsigned compare of two addresses
         BH    ADDR1HIGHER

CLR — Compare Logical Register (unsigned)

hlasm
         CLR   3,4             Unsigned compare of two registers

CLC — Compare Logical Characters (storage to storage)

CLC field1(length),field2 compares up to 256 bytes of storage, left to right, as unsigned bytes:

hlasm
         CLC   NAME1(20),NAME2     Compare two 20-byte name fields
         BE    SAMENAME            Branch if identical
         BL    NAME1BEFORE         NAME1 sorts before NAME2
         BH    NAME1AFTER          NAME1 sorts after NAME2
NAME1    DS    CL20
NAME2    DS    CL20

CLC stops at the first differing byte and sets the condition code based on that byte comparison. If all bytes are equal, CC=0.

CLC for Field Validation

hlasm
* Check if an 8-byte field is all spaces
         CLC   FIELD(8),=CL8' '
         BE    ISBLANK
         B     NOTBLANK
FIELD    DS    CL8

CLI — Compare Logical Immediate (single byte)

CLI storage,immediate compares one byte of storage with an immediate byte value:

hlasm
         CLI   RECTYPE,C'A'        Is record type 'A'?
         BE    TYPEA
         CLI   RECTYPE,C'B'
         BE    TYPEB
         B     UNKNOWN
RECTYPE  DS    C

Testing EBCDIC Ranges

hlasm
* Check if byte contains EBCDIC digit (X'F0' to X'F9')
         CLI   MYCHAR,X'F0'
         BL    NOTDIGIT
         CLI   MYCHAR,X'F9'
         BH    NOTDIGIT
ISDIGIT  DS    0H
MYCHAR   DS    C

CLCL — Compare Logical Characters Long

CLCL compares fields longer than 256 bytes using register pairs:

hlasm
         LA    2,FIELD1        Address of field 1
         LA    3,500           Length of field 1
         LA    4,FIELD2        Address of field 2
         ICM   5,8,=X'40'      Length + pad char (space) in high byte
         LA    5,400           Length of field 2 (shorter)
         CLCL  2,4             Compare: pad shorter field with spaces

Comparing Packed Decimal Fields

For packed decimal comparison, use CP:

hlasm
         CP    AMOUNT,LIMIT    Compare packed fields
         BH    EXCEEDS         Branch if AMOUNT > LIMIT (signed)
AMOUNT   DC    P'12345'
LIMIT    DC    P'10000'

Practical: Record Selection Loop

hlasm
* Read records, process only type 'D' with amount > 100
RECLOOP  DS    0H
         GET   INFILE,INREC        Read next record
         CLI   INREC,C'D'          Check record type
         BNE   RECLOOP             Skip non-D records
         CP    INREC+10(5),=P'100' Compare amount field (packed, 5 bytes)
         BNH   RECLOOP             Skip if amount <= 100
*        ... process qualifying record ...
         B     RECLOOP
INREC    DS    CL80

Frequently Asked Questions

Q: When should I use C (signed) vs CL (unsigned) compare? Use C and CR for signed integer comparison — counts, financial amounts, loop indices. Use CL, CLR, and CLC for unsigned comparison — addresses, byte values, character strings. Addresses are always unsigned (you don't have negative addresses). For character fields, CLC compares byte-by-byte as unsigned EBCDIC values, which gives correct alphabetic ordering for standard EBCDIC.

Q: Does CLC work correctly for EBCDIC alphabetic sorting? For standard EBCDIC characters (A-Z, 0-9, space), CLC gives correct results for sorting because the EBCDIC code points are in the right order within each group. However, EBCDIC alphabetic order is not the same as ASCII alphabetic order — for example, lowercase letters have lower EBCDIC values than uppercase, and digits have higher values than letters. For international characters or locale-aware sorting, more complex comparison tables are needed.

Q: What is the performance difference between CLI and CLC for a one-byte compare? CLI is a single SI-format instruction that compares one byte of storage to an immediate constant — it's slightly smaller and faster than CLC for single-byte comparison. Use CLI when comparing one byte to a known constant. Use CLC when comparing variable-length fields, comparing storage to storage, or when the comparison length varies at runtime.


Part of HLASM Mastery Course — Module 10 of 22.