COBOLPRIMER
Run COBOL

Part 3 of 3

On the mainframe

What production COBOL looks like in practice: how numbers sit in memory, how records are laid out, how files and jobs run, and what it means when they crash.

USAGE: how a number is actually stored

A PIC clause says what a value looks like. The USAGE clause says how it's laid out in bytes. Same number, three very different footprints.

USAGE DISPLAY (default)

aka zoned decimal

One byte per digit, human-readable in a file dump. On z/OS each digit is an EBCDIC character (F0F9) and the sign rides in the zone half of the last byte.

COMP-3 / PACKED-DECIMAL

two digits per byte

Each digit takes a 4-bit nibble; the final nibble is the sign (C positive, D negative, F unsigned). IBM Z has hardware instructions for this format, which is why money fields almost always use it.

COMP / BINARY

halfword, fullword, doubleword

Two's-complement integers sized by digit count: up to 4 digits in 2 bytes, 5–9 in 4 bytes, 10–18 in 8 bytes. Ideal for counters and subscripts, awkward for decimal money.

Byte encoder: one value, three USAGEs

Hex as it would appear in a z/OS storage dump
Why this matters: the S0C7 abend. If a COMP-3 field contains anything that isn't a valid digit/sign nibble pattern, such as spaces (40 40 40) from an uninitialized record, the first arithmetic instruction that touches it raises a data exception. It's the most famous COBOL crash, and you now know exactly what it looks like in memory.

Copybooks & record layouts

Real records are hierarchies built from level numbers. Shared layouts live in copybooks, pulled in with COPY CUSTREC., so every program reading a file agrees on where each byte lives.

01

Record or top-level item. Starts in Area A.

05–49

Nested fields. An item with no PIC is a group: its size is the sum of its children.

88

Condition name. Takes no storage; gives a value of the parent field a readable name.

OCCURS / REDEFINES

Repeat a field (a table), or lay a second view over the same bytes.

Copybook offset calculator

Edit the layout or paste your own. Offsets update as you type.
Supports PIC, COMP/COMP-3/COMP-1/COMP-2, OCCURS, REDEFINES, 88-levels.
LRECL: 0
Field Picture / usage Start Len End

Start and End are 1-based byte positions, the way mainframe file tools (and your DFSORT cards) count them. Fields inside an OCCURS show the first occurrence.

File processing: the heart of batch COBOL

Most production COBOL reads a file, processes each record, and writes another file. Learn this one loop and you can read half the batch code in existence.

CUSTRPT.cbl (excerpt) The standard read loop
      * ENVIRONMENT DIVISION: tie a logical file to a DD name
       SELECT CUST-FILE ASSIGN TO CUSTIN
           ORGANIZATION IS SEQUENTIAL
           FILE STATUS IS WS-FS.

      * WORKING-STORAGE
       01  WS-FS              PIC XX.
       01  WS-EOF-FLAG        PIC X VALUE 'N'.
           88  WS-EOF         VALUE 'Y'.

      * PROCEDURE DIVISION
       0000-MAIN.
           OPEN INPUT CUST-FILE
           IF WS-FS NOT = "00"
               DISPLAY "OPEN FAILED, STATUS " WS-FS
               MOVE 16 TO RETURN-CODE
               STOP RUN
           END-IF
           PERFORM UNTIL WS-EOF
               READ CUST-FILE
                   AT END     SET WS-EOF TO TRUE
                   NOT AT END PERFORM 2000-PROCESS-RECORD
               END-READ
           END-PERFORM
           CLOSE CUST-FILE
           STOP RUN.

Three file organizations

SEQUENTIAL
Read front to back. Flat files, tapes, most batch input. On z/OS, a QSAM dataset.
INDEXED
Keyed random or sequential access. On z/OS, a VSAM KSDS. Think of it as a single-table key-value store.
RELATIVE
Access by record number (slot 1, 2, 3...). VSAM RRDS. The least common of the three.

Always declare FILE STATUS

Without it, many I/O errors simply abend the program. With it, every OPEN, READ, WRITE, and CLOSE sets a two-character code you can check and handle.

FILE STATUS lookup

Code Class Meaning and usual cause

The ecosystem around the language

On a mainframe, COBOL rarely runs alone. These are the neighbors you'll meet on day one of a real job.

JCL

Job Control Language

The script that runs a batch job: which program, which datasets, how much space. The rough modern analogy is a shell script plus a Kubernetes Job spec.

CICS

Online transaction server

Runs short interactive transactions, like a balance inquiry, thousands per second. COBOL calls it with EXEC CICS ... END-EXEC blocks. Think of it as the app server.

Db2

Relational database

SQL embedded directly in COBOL source. A precompiler turns EXEC SQL blocks into calls; host variables are prefixed with a colon.

VSAM & datasets

Storage

No directories in the Unix sense: named datasets like PROD.PAYROLL.MASTER, fixed-length records, and VSAM for keyed files.

PAYRUN.jcl Nightly batch job
//PAYRUN   JOB (ACCT),'NIGHTLY PAYROLL',CLASS=A,MSGCLASS=X
//STEP01   EXEC PGM=PAYROLL
//STEPLIB  DD   DSN=PROD.PAYROLL.LOADLIB,DISP=SHR
//EMPIN    DD   DSN=PROD.EMPLOYEE.MASTER,DISP=SHR
//PAYOUT   DD   DSN=PROD.PAYROLL.OUT(+1),
//            DISP=(NEW,CATLG,DELETE),
//            SPACE=(CYL,(10,5),RLSE),
//            DCB=(RECFM=FB,LRECL=200)
//SYSOUT   DD   SYSOUT=*
The link to COBOL is the DD name. SELECT EMP-FILE ASSIGN TO EMPIN in the program means "whatever dataset the job's EMPIN DD points to." Swap the DSN and the same compiled program reads test data instead of production.
Embedded Db2 SQL
EXEC SQL
    SELECT CUST_NAME, BALANCE
      INTO :WS-CUST-NAME, :WS-BALANCE
      FROM CUSTOMER
     WHERE CUST_ID = :WS-CUST-ID
END-EXEC
EVALUATE SQLCODE
    WHEN 0    PERFORM 3000-SHOW-CUSTOMER
    WHEN 100  DISPLAY "CUSTOMER NOT FOUND"
    WHEN OTHER PERFORM 9999-SQL-ERROR
END-EVALUATE
CICS screen send
EXEC CICS SEND MAP('ACCTMAP')
               MAPSET('ACCTSET')
               ERASE
END-EXEC

Abend decoder

An abend (abnormal end) is how a mainframe job crashes. These are the codes you'll see most. Click one to see what usually caused it.

Reality check: the contrarian view

Most COBOL marketing, including the opening of this primer, leans on a few dramatic claims. Here's the case against taking them at face value.

The famous numbers are folklore

"95% of ATM swipes," "220 billion lines," and "$3 trillion a day" mostly trace back to a single 2017 Reuters graphic that cited older industry estimates. Nobody has published a fresh, auditable count. Treat them as order-of-magnitude signals, not facts.

The language is the easy part

A working programmer can read COBOL within a week. The hard, valuable part is JCL, CICS, Db2, and decades of undocumented business rules. COBOL alone won't get you hired; the platform knowledge will.

Exact decimals aren't unique

Java's BigDecimal, Python's Decimal, C#'s decimal, and SQL's DECIMAL all do exact money math. COBOL's real edge is that decimal is the default and IBM Z runs it in hardware, not that other languages can't.

The "talent crisis" is uneven

Demand is real but concentrated in banks, insurers, and government, and much maintenance is outsourced. AI-assisted translation tools are explicitly aimed at shrinking the need for COBOL specialists.

The counterpoint to the counterpoint: large-scale COBOL rewrites have a long history of running over budget or being abandoned, and mainframes remain very good at high-volume transaction processing. The likeliest future isn't COBOL disappearing but COBOL shrinking slowly while the remaining systems become more critical, and harder to staff.

Check your understanding

Four questions on storage, files, and jobs.

Question 1 of 4 Score: 0