在 z/OS 汇编程序中将字节转换为位串?
Convert byte to string of bits in z/OS Assembler?
在 z/OS 程序集中将字节转换为其位表示的最佳方法是什么?
例如X'3A'变成CL8'00111010',类似于COBOL中的内在函数BIT-OF或者Rexx'X2B?
我在汇编中要做的是映射到每个可能的两个表,如下所示:
...
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'
但这需要两个非常大的对应表示表。
有没有更有效或更简洁的方法来做到这一点?
我没有使用包含所有可能位值的大 table,而是使用 UNPK
将半字节隔离为一个字节。这允许我 AND
关闭区域部分,然后使用剩余的半字节作为本地数组字符串的偏移量,该字符串长度为 4 个字节,表示半字节的二进制值。这是第一次通过,但这是我的第一个想法。
如果我真的这样做,我可能会使用 EX
指令和 TM
来测试每个位,并简单地将“1”或“0”添加到字符位表示中。它将保存另一个字符数组。
为了使其更有用,可以对其进行优化以接收 3 个参数,即源字符串、其长度和指向输出缓冲区的指针。制作整个东西 re-entrant 就不需要本地存储了。
我认为这符合您的挑战。
测试字符串是 C"123ABC"
,输出结果是
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
在 z/OS 程序集中将字节转换为其位表示的最佳方法是什么?
例如X'3A'变成CL8'00111010',类似于COBOL中的内在函数BIT-OF或者Rexx'X2B?
我在汇编中要做的是映射到每个可能的两个表,如下所示:
...
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'
但这需要两个非常大的对应表示表。
有没有更有效或更简洁的方法来做到这一点?
我没有使用包含所有可能位值的大 table,而是使用 UNPK
将半字节隔离为一个字节。这允许我 AND
关闭区域部分,然后使用剩余的半字节作为本地数组字符串的偏移量,该字符串长度为 4 个字节,表示半字节的二进制值。这是第一次通过,但这是我的第一个想法。
如果我真的这样做,我可能会使用 EX
指令和 TM
来测试每个位,并简单地将“1”或“0”添加到字符位表示中。它将保存另一个字符数组。
为了使其更有用,可以对其进行优化以接收 3 个参数,即源字符串、其长度和指向输出缓冲区的指针。制作整个东西 re-entrant 就不需要本地存储了。
我认为这符合您的挑战。
测试字符串是 C"123ABC"
,输出结果是
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