MainframeSupports
tip week 19/2011:

Sometimes I need to display the hexadecimal value of a variable. It might be in SQL, from REXX, COBOL or PLI. In order to display the hexadecimal value of a variable the variable needs to be converted. This can be done in a number of different ways. SQL and REXX has built in functions to do the trick. In COBOL and PLI it is a little more complicated.

In SQL the function is called HEX(expression) and it works exactly as you want it to work. The first byte of the result of expression is converted to two hexadecimal digits in the interval 0-F and so on.

In REXX it is just a bit more complicated, because REXX has two different functions for hexadecimal conversion. The first one is called C2X(char-expression) while the second one is called D2X(numeric-expression). For instance C2X('1') returns F1 while D2X('1') returns 01. REXX variables are typeless so you need to tell REXX how to interpret the input when converting to HEX.

With the introduction of the Enterprise PL/I compiler two functions for converting to HEX has been added. The first one is called HEX and works like SQL HEX for character strings. If you use it for numeric variables (BINARY, DECIAML or REAL) strange things happens, so please avoid this. Enterprise PL/I has a function called HEXIMAGE to cope with numeric values and it works exactly like HEX in SQL for all types of variables. On the other hand this function needs the address and the length of the variable to be converted, so this makes it a bit more complicated to use.

Last but not least there is COBOL. Here is no built in functions to help you. I have even looked into the newest release of the COBOL compiler, but COBOL does not do a good job on built in functions. An easy way to solve the problem is to call SQL HEX:

EXEC SQL
  SET :hexvalue = HEX(:cobolvariable)
END-EXEC

which is a bit annoying to do if your program does not use DB2. Then you have to code it yourself. There are lot of code slices out on the internet to use. You now very fast risk to have the same code slice in many different programs. Instead you can code a COBOL module to do the trick. A last resort is to code the conversion in assembler, which I have chosen to do. I can now use the same program from both PLI and COBOL (even though PLI can do the job) and other compiling languages on the mainframe including assembler. If you are able to compile an assembler module on your installation you can use the following piece of code:

CHR2HEX  CSECT
CHR2HEX  AMODE ANY
CHR2HEX  RMODE ANY
         BAKR  R14,0
         BASR  R12,0
         USING *,R12
         L     R2,0(R1)
         L     R3,4(R1)
         L     R3,0(R3)
         LTR   R3,R3
         BNP   CHR2HEXR
         L     R4,8(R1)
         LA    R5,16
         LA    R8,HEXTABLE
CHR2HEXL EQU   *
         SR    R7,R7
         IC    R7,0(R2)
         SR    R6,R6
         DR    R6,R5
         LA    R9,0(R8,R7)
         MVC   0(1,R4),0(R9)
         LA    R9,0(R8,R6)
         MVC   1(1,R4),0(R9)
         LA    R4,2(R4)
         LA    R2,1(R2)
         BCT   R3,CHR2HEXL
CHR2HEXR EQU   *
         SR    R15,R15
         PR
         LTORG
HEXTABLE DC CL16'0123456789ABCDEF'
         YREGS
         END

This program is invoked from COBOL like this:

01 to-be-converted pic x(10).
01 tbc-length pic s9(9) binary.
01 hex-format pic x(20).
...
move length of to-be-converted to tbc-length
call 'CHR2HEX' using to-be-converted tbc-length hex-format

The variable to-be-converted can be any kind of variable or structure. The most important thing is that the variable hex-format (or whatever you choose to call it) is at least twice the size as to-be-converted. If you do not do this you risk to make unpleasant storage overwrites.

Real assemblemer programmers will probably laugh at my CHR2HEX program as it does not use a clever assembler trick for the conversion. I am not good at assembler so the above program is my best attempt.

Previous tip in english        Sidste danske tip        Tip list