What is the best way to convert a byte to it's bit representation in z/OS Assembly?
E.g. X'3A' becomes CL8'00111010', similar to the intrinsic function BIT-OF in COBOL or Rexx' X2B?
What I got going in assembly is mapping against two tables of each possible like this:
...
SR R1,R1
IC R1,BYTE
IC R1,HEXTAB(R1)
LA R1,BITTAB(R1)
MVC BITS,0(R1)
...
*
BYTE DC X'3A'
BITS DS CL8
HEXTAB DC X'0001020903110A19042112290B311A39'
DC X'05412245134D2A550C5D32651B6D3A75'
DC X'06264262237D468514804E8D2B95569D'
DC X'0D495EA533A966B11C886EB93BC176C9'
DC X'071727374353637324837E9B47AF86C7'
DC X'155181AD4FD18ED32C9096DB57D59EE3'
DC X'0E2E4A6A5F92A6BE3498AAE067DDB2EB'
DC X'1D5989B56FD7BAF33CA0C2EE77E5CAF7'
DC X'FF0810182028303840444C545C646C74'
DC X'25617C847F8C949C48A4A8B087B8C0C8'
DC X'16365272829AAEC650ACD0D28FDAD4E2'
DC X'2D6991BD97DFDCEA58B4D6F29FEDE4F6'
DC X'FE0F1F2F3F4B5B6B607B8B93A3A7B7BF'
DC X'357199C5ABCFD9E168BCDEE9B3F1ECF5'
DC X'FD1E3E5A7A8AA2B670C4CED8BBE8F0F4'
DC X'FC3D79A1C3CDE7EFFB78CCE6FACBF9F8'
BITTAB DC C'00000000100000011000001010000011'
DC C'10000100100001011000011010000111'
DC C'10001000100110001010100010111000'
DC C'11001000110110001110100011111001'
DC C'00101001001110010101100101101001'
DC C'01111001100110101001101110011101'
DC C'10011110100111111010101011101011'
DC C'01101011111011011110111011111111',C'0000000'
But this requires two obnoxiously big tables of the corresponding representations.
Is there any more efficient or less verbose way of doing this?
CodePudding user response:
Rather than have a large table with all possible bit values I used UNPK
to isolate the nibbles into a byte. This allowed me to AND
off the zone portion and then use the remaining nibble as an offset into a local array character strings that are 4 bytes long representing the binary value of the nibble. This is a first pass but it was my first thought.
If I were doing this for real I'd probably use the EX
instruction with TM
to test each bit and simply add '1' or '0' to the character bit representation. It would save another character array.
To make it more useful it can be optimized to receive 3 parameters which would be the source string, its length and a pointer to the output buffer. Make the whole thing re-entrant and there would be no need for local storage.
I think this matches your challenge.
Test String is C"123ABC"
and the output yields
F 1 F 2 F 3 C 1 C 2 C 3
1111 0001 1111 0010 1111 0011 1100 0001 1100 0010 1100 0011
PRINT NOGEN
* ------------------------------------------------------------------- *
* *
* C2B *
* *
* @author Hogstrom *
* *
* Process a set of bytes and convert to a displayable '1' and '10' *
* to represent the binary value. *
* *
* ------------------------------------------------------------------- *
R0 EQU 0
R1 EQU 1
R2 EQU 2
R3 EQU 3
R4 EQU 4
R5 EQU 5
R6 EQU 6
R7 EQU 7
R8 EQU 8
R9 EQU 9
R10 EQU 10
R11 EQU 11
R12 EQU 12 * Base Register
R13 EQU 13
R14 EQU 14
R15 EQU 15
*
ASMSKEL CSECT
STM R14,R12,12(R13)
LR R12,R15
USING ASMSKEL,R12
*
ST R13,SaveArea 4
LA R0,SaveArea
ST R0,8(R13)
LA R13,SaveArea
*
OPEN (SYSOUT,(OUTPUT))
*
LA R2,L'TEST1 Length of bytes to convert to binary
LA R3,TEST1 Source address of bytes to convert
LA R4,LINE Where to place the translated bits
BYTELOOP DS 0H
UNPK NIBBLE,0(2,R3) unpack two bytes, ignore the second
NC NIBBLE,=X'0F0F' Turn off zone as its not needed
SR R5,R5 Clear Bit Offset Register
IC R5,NIBBLE Grab offset
SLL R5,2 and multiply by 4
LA R6,CHARBITS
AR R6,R5 add offset to correct bits
MVC 0(4,R4),0(R6) move them
*
LA R4,5(R4) Increment to the next section
SR R5,R5 Clear Bit Offset Register
IC R5,NIBBLE 1 Grab offset
SLL R5,2 and multiply by 4
LA R6,CHARBITS
AR R6,R5 add offset to correct bits
MVC 0(4,R4),0(R6) move them
LA R4,5(R4) Increment to the next section
LA R3,1(R3) Move to next Byte
BCT R2,BYTELOOP
*
FINISH DS 0H
PUT SYSOUT,OUTREC
CLOSE SYSOUT
*
L R13,SaveArea 4
LM R14,R12,12(R13)
XR R15,R15
BR R14
*
SYSOUT DCB DSORG=PS,MACRF=(PM),DDNAME=SYSOUT, *
RECFM=FBA,LRECL=133,BLKSIZE=0
*
NIBBLE DS C' ' Second byte is ignored
*
TEST1 DC C'123ABC'
DC C' ' Filler Byte to accomodate UNPK
*
OUTREC DC 0CL133
ASA DC C' '
LINE DC CL132' '
*
SaveArea DS 18F
LTORG
CHARBITS DS 0H
DC C'0000'
DC C'0001'
DC C'0010'
DC C'0011'
DC C'0100'
DC C'0101'
DC C'0110'
DC C'0111'
DC C'1000'
DC C'1001'
DC C'1010'
DC C'1011'
DC C'1100'
DC C'1101'
DC C'1110'
DC C'1111'
END