steve-myers
Active Member
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
|
|
|
|
Just for my amusement I was reviewing some very old topics in Assembler language and came across this one. The "solution" is incorrect, because its author ignored something important: the solution damaged characters that are not upper case characters.
In EBCDIC, lower case characters are in the range X'81' to X'89'. X'91 to X'99', and X'A2 to X'A9'. The upper case characters are in the range X'C1' to X'C9', X'D1' to X'D9', and X'E2' to X'E9'. The classic solution in EBCDIC to translate lower case characters to upper case is to OR X'40' into the character, so lower case a, X'81' becomes X'C1', upper case A. This does not damage a blank (X'40') or the punctuation characters. The solution in the earlier article performed an AND of B'10111111'. This will convert A to a, but a blank will become X'00', and the punctuation characters will be hopelessly damaged.
The "correct" solution uses the TR instruction and a translate table -
Code: |
TR STRING,TRTAB
...
TRTAB DC 0XL256'0'
DC (C'A')AL1(*-TRTAB)
DC C'abcdefghi',(C'J'-(*-TRTAB))AL1(*-TRTAB)
DC C'jklmnopqr',(C'S'-(*-TRTAB))AL1(*-TRTAB)
DC C'stuvwxyz',(256-(*-TRTAB))AL1(*-TRTAB)
...
STRING DC C'THIS MESSAGE CONTAINS LOWER CASE CHARACTERS' |
There are many ways to code this translate table. (C'A')AL1(*-TRTAB) inserts text to translate a character from X'00' to X'BF' to itself, which takes care of blank and the punctuation characters. The remainder of the table I leave to the reader to interpret. Many programmers might choose this -
Code: |
TRTAB DC 256AL1(*-TRTAB)
ORG TRTAB+C'A'
DC C'abcdefghi'
ORG TRTAB+C'J'
DC C'jklmnopqr'
ORG TRTAB+C'S'
DC c'stuvwxyz'
ORG , |
|
|