MODULE 13 · MAINFRAME INTERNALS AND CAPSTONE · 1/10

EBCDIC, ASCII and sort order

12 min10 XPQuiz

Every byte on a z/OS mainframe is interpreted with EBCDIC (Extended Binary Coded Decimal Interchange Code), not ASCII. Your COBOL source, your datasets and your PIC X fields are all EBCDIC. The characters look the same on screen, but the bytes underneath are different, and so is the order they sort in.

Character EBCDIC (code page 037) ASCII
space X'40' X'20'
ai X'81'X'89' X'61'X'69'
AI X'C1'X'C9' X'41'X'49'
JR X'D1'X'D9' X'4A'X'52'
SZ X'E2'X'E9' X'53'X'5A'
09 X'F0'X'F9' X'30'X'39'

EBCDIC descends from punched cards, which is why the letters come in three blocks with gaps between them. Two consequences matter every day:

  • Sort order. EBCDIC: space < lower case < upper case < digits. ASCII: space < digits < upper case < lower case. The same file sorts differently on the two platforms.
  • Ranges. IF WS-CHAR >= "A" AND <= "Z" is also true for some non-letter bytes in the EBCDIC gaps. Use the class test ALPHABETIC instead.

Seeing the difference

This course runs GnuCOBOL on an ASCII machine. Run this:

       IDENTIFICATION DIVISION.
       PROGRAM-ID. COLLATE.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  WS-CODE-1    PIC X(4) VALUE "A100".
       01  WS-CODE-2    PIC X(4) VALUE "1000".
       01  WS-CODE-3    PIC X(4) VALUE "a100".
       PROCEDURE DIVISION.
           IF WS-CODE-2 < WS-CODE-1
               DISPLAY "DIGITS SORT BEFORE LETTERS"
           ELSE
               DISPLAY "LETTERS SORT BEFORE DIGITS"
           END-IF
           IF WS-CODE-1 < WS-CODE-3
               DISPLAY "UPPER CASE SORTS BEFORE LOWER CASE"
           ELSE
               DISPLAY "LOWER CASE SORTS BEFORE UPPER CASE"
           END-IF
           DISPLAY "A IS X'" FUNCTION HEX-OF(WS-CODE-1(1:1)) "'"
           STOP RUN.
DIGITS SORT BEFORE LETTERS
UPPER CASE SORTS BEFORE LOWER CASE
A IS X'41'

On z/OS the first two lines would be the opposite, and A would be X'C1'. You can make GnuCOBOL compare the mainframe way by adding this before the DATA DIVISION:

       ENVIRONMENT DIVISION.
       CONFIGURATION SECTION.
       OBJECT-COMPUTER. IBM-Z
           PROGRAM COLLATING SEQUENCE IS MAINFRAME.
       SPECIAL-NAMES.
           ALPHABET MAINFRAME IS EBCDIC.

Now it prints LETTERS SORT BEFORE DIGITS and LOWER CASE SORTS BEFORE UPPER CASE. The bytes are still ASCII (X'41'); only comparisons change. The job simulator's SORT compares ASCII bytes, so its results are the ASCII order.

Where this bites

  • Migrations and downloads. A report checked on a PC shows records in a different order from the mainframe original. Nothing is broken; the collating sequence changed.
  • SEARCH ALL and control breaks assume the file is in key order. Sort on one platform and process on the other, and the order check fails.
  • HIGH-VALUES / LOW-VALUES are X'FF' and X'00' on both, so they still sort last and first.
  • File transfer. FTP in ASCII mode translates each byte. That is right for pure text and wrong for any record containing packed or binary fields, which must go in binary mode.

On the job

When a test comparison fails "for no reason" after data moved between z/OS and a distributed system, check three things first: code page, sort order, and whether numeric fields were translated as if they were text. In ISPF, HEX ON shows you the real bytes in seconds.

Check your understanding

1. On z/OS, which of these keys comes FIRST in an ascending sort?
2. A file sorted on the mainframe by customer code is downloaded and re-sorted on a Linux server. Codes A7 and 77 swap places. Why?
3. What is the letter C in EBCDIC?
4. Why must a file with COMP-3 fields NOT be transferred with an ASCII text conversion?