HLASM Data Representation: EBCDIC, Binary, Hex, and Packed Decimal

TT

HLASM Data Representation: EBCDIC, Binary, Hex, and Packed Decimal

Mainframe computing uses data formats that differ significantly from PC programming. EBCDIC instead of ASCII, packed decimal for financial data, and big-endian binary integers are the norm. Understanding these formats is essential for reading storage dumps and writing correct data manipulation code.

EBCDIC Character Encoding

z/OS uses EBCDIC (Extended Binary Coded Decimal Interchange Code) — not ASCII. Every character has a different byte value than its ASCII equivalent.

Common EBCDIC values:

CharacterEBCDIC (hex)ASCII (hex)
SpaceX'40'X'20'
0–9X'F0'–X'F9'X'30'–X'39'
A–ZX'C1'–X'E9'X'41'–X'5A'
a–zX'81'–X'A9'X'61'–X'7A'

This matters for character manipulation. Checking if a byte contains a digit means comparing to X'F0'–X'F9', not X'30'–X'39'.

hlasm
* Check if a character is a digit (EBCDIC)
         CLI   MYCHAR,X'F0'    Compare to '0' (EBCDIC)
         BL    NOTDIGIT        Branch if less than '0'
         CLI   MYCHAR,X'F9'    Compare to '9' (EBCDIC)
         BH    NOTDIGIT        Branch if greater than '9'
         B     ISDIGIT         It is a digit
MYCHAR   DC    C'5'            EBCDIC '5' = X'F5'

Binary Integer Formats

z/Architecture uses big-endian byte order (most significant byte first):

Halfword (2 bytes) — type H in DC:

hlasm
MYH      DC    H'32767'        X'7FFF' — maximum positive halfword
MYNEG    DC    H'-1'           X'FFFF' — -1 in two's complement

Fullword (4 bytes) — type F in DC (most common):

hlasm
MYFW     DC    F'1000000'      X'000F4240'

Doubleword (8 bytes) — type D in DC:

hlasm
MYDW     DC    D'0'            Eight zero bytes

Arithmetic instructions work with fullwords (L/ST/A/S/M/D) and halfwords (LH/STH/AH/SH/MH).

Hexadecimal Notation

HLASM source can specify constants in hex using the X type:

hlasm
MASK     DC    X'FF000000'     32-bit mask: first byte set, rest zero
FLAG     DC    X'80'           Single byte with high bit set
SPACES   DC    X'40404040'     Four EBCDIC spaces

In assembler listings, all machine instructions and data appear in hexadecimal. Learning to read hex is essential.

Zoned Decimal Format

Zoned decimal is how COBOL DISPLAY variables are stored. Each decimal digit occupies one byte:

  • High nibble (zone): X'F' for all digits except the last
  • Low nibble (numeric): 0–9

The last byte's zone encodes the sign:

  • X'C' = positive (or unsigned)
  • X'D' = negative
  • X'F' = unsigned (positive, no sign)

For the number +123:

text
Byte 1: X'F1'   (zone F, digit 1)
Byte 2: X'F2'   (zone F, digit 2)
Byte 3: X'C3'   (zone C = positive, digit 3)
hlasm
ZONED    DC    Z'12345'        Defines 5-byte zoned decimal 12345

Packed Decimal Format

Packed decimal condenses two digits into one byte, with the sign in the last nibble:

  • Two digits per byte (except the last)
  • Last nibble: X'C' = positive, X'D' = negative, X'F' = unsigned

For the number +12345:

text
Byte 1: X'12'   (digits 1 and 2)
Byte 2: X'34'   (digits 3 and 4)
Byte 3: X'5C'   (digit 5, sign C = positive)
hlasm
PACKED   DC    P'12345'        Defines 3-byte packed decimal 12345
NEGPCK   DC    P'-99'          Defines packed -99 = X'99D'

Packed decimal requires half the storage of zoned decimal. Financial calculations use packed decimal arithmetic (AP, SP, MP, DP) which is more efficient than converting to binary.

Converting Between Formats

Zoned to PackedPACK instruction:

hlasm
ZONEFLD  DS    ZL5             5-byte zoned decimal field
PACKFLD  DS    PL3             3-byte packed decimal field
         PACK  PACKFLD,ZONEFLD Convert 5-byte zoned to 3-byte packed

Packed to ZonedUNPK instruction:

hlasm
         UNPK  ZONEFLD,PACKFLD Convert packed back to zoned

Packed to BinaryCVB (Convert to Binary):

hlasm
WORKDBL  DS    D               Doubleword work area
         PACK  WORKDBL,ZONEFLD Pack to doubleword first
         CVB   3,WORKDBL       Convert packed in doubleword to binary in reg 3

Binary to PackedCVD (Convert to Decimal):

hlasm
         CVD   3,WORKDBL       Convert binary in reg 3 to packed in doubleword
         UNPK  ZONEFLD,WORKDBL+4(4)  Unpack the low 4 bytes

Frequently Asked Questions

Q: Why does mainframe use EBCDIC instead of ASCII? EBCDIC predates ASCII on IBM systems. It was designed for punched-card machinery in the 1950s and 1960s, where the encoding reflected the physical layout of the card columns. When IBM built the System/360 in 1964, EBCDIC was used for character data. ASCII was standardised in 1963 for the broader computing industry. IBM maintained EBCDIC for backward compatibility — the same reason z/OS still uses it today.

Q: When should I use packed decimal vs binary arithmetic? Use packed decimal for financial and business data — amounts, quantities, percentages — where exact decimal representation is required. Binary (fixed-point) arithmetic rounds results to the nearest integer, which can introduce errors in financial calculations. Use binary arithmetic for loop counters, array indices, and calculations where the values are inherently integers. The packed decimal instructions (AP, SP, MP, DP) work directly on packed fields without conversion.

Q: How many digits can a packed decimal field hold? A packed decimal field of length n bytes holds up to 2n-1 digits. A 4-byte packed field holds 7 digits. A 16-byte field holds 31 digits. COBOL's PIC 9(15) COMP-3 maps to an 8-byte packed field with 15 digits. For very large financial calculations, use the maximum precision your application requires.


Part of HLASM Mastery Course — Module 5 of 22.