HLASM Data Definition: DC, DS, and Storage Alignment

TT

HLASM Data Definition: DC, DS, and Storage Alignment

DC (Define Constant) and DS (Define Storage) are the HLASM directives for defining data. Every piece of data in an HLASM program — character strings, integers, addresses, work areas — is defined with DC or DS. This module covers all type codes, duplication factors, and alignment.

DC — Define Constant

DC allocates storage and initialises it with a value:

hlasm
GREETING DC    C'HELLO WORLD'       12-byte character constant
AMOUNT   DC    F'12345'             4-byte fullword binary integer
RATE     DC    H'250'               2-byte halfword integer
PRICE    DC    P'999.99'            Packed decimal
HEXVAL   DC    X'FF80'              2-byte hex constant
BITFLAG  DC    B'10110010'          1-byte binary constant
BIGNUM   DC    D'0'                 8-byte doubleword, value 0
ADDR     DC    A(MYTABLE)           4-byte address constant

DS — Define Storage

DS reserves storage without initialising it (contents are undefined):

hlasm
WORKAREA DS    CL80                 80-byte character work area
SAVEREGS DS    18F                  18 fullwords (save area)
COUNTER  DS    F                    One fullword
HALFVAL  DS    H                    One halfword
PACKED   DS    PL7                  7-byte packed decimal field
NAMEFLD  DS    CL25                 25-byte name field

Type Codes

TypeDescriptionAlignment
CCharacter (EBCDIC)Byte
XHexadecimalByte
BBinaryByte
FFullword (4 bytes)Fullword (4)
HHalfword (2 bytes)Halfword (2)
DDoubleword (8 bytes)Doubleword (8)
PPacked decimalByte
ZZoned decimalByte
AAddress (4 bytes)Fullword
Y2-byte addressHalfword
S2-byte base-displacementHalfword
EShort floating-pointFullword
LLong floating-pointDoubleword

Duplication Factor

A duplication factor multiplies the constant:

hlasm
SPACES   DC    CL80' '          80-byte field filled with spaces
ZEROS    DC    10F'0'           10 consecutive fullwords of zero
TABLE    DS    20CL10           20 entries, each 10 bytes (no init)
FILLER   DC    3X'00'           Three zero bytes

Length Modifier

Override the default length with Ln:

hlasm
SHORTNUM DC    FL2'100'         2-byte (halfword-sized) fullword constant
LONGPACK DC    PL8'0'           8-byte packed decimal zero
PADDED   DC    CL20'HELLO'      20 bytes: 'HELLO' padded with spaces on right

Character constants are right-padded with spaces if shorter than the specified length. Numeric constants are left-padded with zeros.

Multiple Operands

A single DC can define multiple values:

hlasm
MONTHS   DC    C'JAN',C'FEB',C'MAR',C'APR',C'MAY',C'JUN'
         DC    C'JUL',C'AUG',C'SEP',C'OCT',C'NOV',C'DEC'

Storage Alignment

The assembler automatically aligns DC/DS for the data type:

  • Halfword (H, Y, S): aligned to even address
  • Fullword (F, E, A): aligned to address divisible by 4
  • Doubleword (D, L): aligned to address divisible by 8

Misaligned data causes a specification exception (0C6 abend) for instructions that require alignment.

Force alignment with DS 0F, DS 0H, or DS 0D:

hlasm
MYDATA   DS    CL3              3 bytes (odd address possible)
         DS    0F               Force fullword alignment (pad if needed)
MYFW     DS    F                Guaranteed fullword-aligned

ORG — Redefining Storage

ORG repositions the location counter, allowing you to redefine storage:

hlasm
RECORD   DS    CL80             Define 80-byte record
         ORG   RECORD           Go back to start
RECTYPE  DS    C                Overlay: byte 0 = record type
RECSEQ   DS    CL5              Bytes 1-5 = sequence number
RECDATA  DS    CL74             Bytes 6-79 = data
         ORG   RECORD+80        Restore location counter past RECORD

Literals

A literal =type'value' is an inline constant the assembler allocates in the literal pool:

hlasm
         A     3,=F'100'        Add 100 (assembled as a fullword constant)
         CLC   FIELD(4),=C'END '  Compare with literal
         LA    4,=A(MYTABLE)    Load address of address constant

The assembler collects all literals and places them at the end of the CSECT (or at a LTORG directive).

Frequently Asked Questions

Q: When should I use DC vs a literal (=F'value')? Use a named DC when you reference the constant in multiple places (define once, reuse). Use a literal when the constant is used once and naming it would add clutter. Literals are slightly less efficient in very tight loops because the assembler generates them remotely from the instruction, potentially causing a cache miss. For performance-critical loops, define constants with DC near the code.

Q: What happens if I access a fullword at an odd address? On z/Architecture, some instructions require operands to be aligned to their natural boundary — L (Load) requires a fullword-aligned address. If the operand is not aligned, the CPU generates a specification exception (program interrupt code X'06'), causing a 0C6 abend. Always use DS 0F before fullword fields if there's any chance of misalignment after byte or character fields.

Q: What is the difference between DS CL80 and DC CL80' '? DS CL80 reserves 80 bytes but does not initialise them — the content is whatever was in memory before. DC CL80' ' reserves 80 bytes and initialises them all to EBCDIC space (X'40'). Use DC when the initial value matters (e.g., output areas that might be printed before being filled). Use DS for work areas where you'll set the content before using it, to avoid the overhead of unnecessary initialisation.


Part of HLASM Mastery Course — Module 11 of 22.