Keyboard Shortcuts
ctrl + shift + ? :
Show all keyboard shortcuts
ctrl + g :
Navigate to a group
ctrl + shift + f :
Find
ctrl + / :
Quick actions
esc to dismiss
Likes
Search
Hex dump.
Probably an OT question, if this is the case, apologies.
I've a curiosity about the faster way to code, in IFOX00 assembler, hexadecimal stream dump, for an arbitrary long string of bytes, possibly with a length not a multiple of a full 32 bit word. The best way I've seen so for, for a full 32 bit word, is this sequence of instructions: ... UNPK DB(9),FW(5) TR DB(8),TRHEXTAB ... DB DS D DB2 DS D FW DS F HEXTAB DC C'0123456789ABCDEF' TRHEXTAB EQU HEXTAB-C'0' which dump a full 32 bit word in 4 hexadecimal digits, assuming the word is stored at the FW address, basically using 2 instructions. If the stream length is not a multiple of 4, the remain, which length is in the {1,2,3} set, may be dumped using the same sequence, slightly modified, for example for 3: UNPK DB(7),FW(4) TR DB(6),TRHEXTAB Any faster way? Peppe. |
Peppe,
toggle quoted message
Show quoted text
For me today's PCs are so fast (and I'm the only user) that the speed of an individual routine seldom matters. Below is my code to expand any length of binary data into character hexadecimal format. Wally ... LM RE,RF,ISPVAR R14 @ VARIABLE, R15 HAS LENGTH LA R5,ISPOUT R5 @ WTP CHARACTER OUTPUT ISP00100 LA R6,2 R6 # HEX CHARACTERS IN A BYTE SR R1,R1 R1 WILL HAVE BYTE BEING PROCESSED ICM R1,8,0(RF) R1 HAS 2 HEX VALUES IN UPPER BYTE ISP00200 SR R0,R0 R0 WILL HAVE HEX BEING PROCESSED SLDL R0,4 R0 HAS SINGLE HEX CHARACTER STC R0,0(R0,R5) SAVE HEX IN OUTPUT AREA TR 0(1,R5),ISPTRT1 TRANSLATE X'00-0F' TO X'F0-C6' LA R5,1(R0,R5) R5 @ WTP NEXT BIT CHARACTER BCT R6,ISP00200 LOOP - PROCESSING 1 BYTE LA RE,1(R0,RE) R14 @ NEXT BYTE OF VALUE BCT RF,ISP00100 LOOP - PROCESSING ALL BYTES ... ISPTRT1 DC X'0123456789ABCDEF' USED TO CONVERT HEX CHARACTERS ... ISPVAR DS A @ INPUT BINARY VARIABLE FIELD ISPVARL DS A LENGTH OF VARIABLE ISPOUT DS A @ OUTPUT CHARACTER FIELD -----Original Message-----
From: [email protected] <[email protected]> On Behalf Of Giuseppe Vitillaro Sent: Monday, July 27, 2020 04:00 AM To: [email protected] Subject: [H390-MVS] Hex dump. Probably an OT question, if this is the case, apologies. I've a curiosity about the faster way to code, in IFOX00 assembler, hexadecimal stream dump, for an arbitrary long string of bytes, possibly with a length not a multiple of a full 32 bit word. The best way I've seen so for, for a full 32 bit word, is this sequence of instructions: ... UNPK DB(9),FW(5) TR DB(8),TRHEXTAB ... DB DS D DB2 DS D FW DS F HEXTAB DC C'0123456789ABCDEF' TRHEXTAB EQU HEXTAB-C'0' which dump a full 32 bit word in 4 hexadecimal digits, assuming the word is stored at the FW address, basically using 2 instructions. If the stream length is not a multiple of 4, the remain, which length is in the {1,2,3} set, may be dumped using the same sequence, slightly modified, for example for 3: UNPK DB(7),FW(4) TR DB(6),TRHEXTAB Any faster way? Peppe. -- This email has been checked for viruses by AVG. |
On Mon, 27 Jul 2020, Wally Mclaughlin wrote:
Peppe,Yep, that the other way I know about, going nibble by nibble, hex digit to hex digit, using ICM/TR for each nibble, along the byte stream. I bet it is slower, although I didn't benchmark them, compared to UNPK/TR which dump 4 hex digits with one UNPK instruction. Modern PC are fast, a PI3 is not so fast, it looks, from hercules emulation point of view, not far from mainframes of the eighty, 10MIPS against 200MIPS of a XEON/I7. From the other side, speaking of emulation, I guess emulating UNPK is not as fast as an ICM. On a real iron mainframe probably the game is different. Other ways? Peppe. |
Well, do it as two passes.
Use the maximum length of the UNPK instruction then the left over part. Then do the translate which has a 256 byte limit. On Mon, Jul 27, 2020 at 2:59 AM Giuseppe Vitillaro <giuseppe@...> wrote:
-- Mike A Schwab, Springfield IL USA Where do Forest Rangers go to get away from it all? |
Giuseppe Vitillaro wrote:
Probably an OT question, if this is the case, apologies.Actually, a forum DOES exist for exactly such questions. It's called "hercules-s370asm" (Forum discussing use of S/370 assembler with the Hercules emulator): /g/hercules-s370asm (Ref: ) But given how infrequently Off Topic posts are made here and to other forums (and the fact that such topics of discussion are usually quite short lived and don't drag on for days and weeks on end), I personally am of the opinion that in this specific instance such an off topic post here should be okay. :) p.s. Doesn't a system function or macro already exist to do this? It seems like such a common thing! If such a macro doesn't already exist maybe someone could write one? -- "Fish" (David B. Trout) Software Development Laboratories mail: fish@... |
On Mon, 27 Jul 2020, Mike Schwab wrote:
Well, do it as two passes.Yep, I had some thought about this way, which actually seems the faster way to go for "long streams" (which it is actually my case as I'm coding a PL/I-F small program to hex dump datasets, please I know IDCAMS may do the job under MVS3.8j, but it is a PL/I exercise from one side and I like to get UNIX like HEX/EBCDIC dump, identical to the output of "xxd -E" under UNIX). But in this case the remainder should have a variable size between 1 and 125 (maximum should be 126 bytes, 252 hex digits, executing a single UNPK/TR couple). So, it can't be coded using one routine for each value of the remainder, too long and a nightmare to modify, but it requires, I guess, to write the UNPK/TR instructions LL fields, at runtime, executing them only after their LL fields are correctly defined for current value of the remainder. Which directly lead to the "EX" instruction, if I got the correct picture, an "EX" for UNPK and an "EX" for TR. Am I on the right side of the "force"? ;-) Or there are better ways? Peppe. |
Hi Peppe,
The maximum length of a UNPK is 8 (length 1 = 8 and length 2 = 15). UNPK is SS-2 type instruction with 2 length fields rather than a SS-1 type instruction with a length field with a maximum of 255. So you can convert max 7 bytes in one time to "printable" HEX. An example is the SYCONVHX macro in the RPF source library. Cheers, Rob |
Yes, EX is used to put varying lengths into instructions.
And if you are doing 4 or 8 groups of 8 nibbles and a blank into a print line of 80 or 132, do the unpacks then translate the bytes then move the blanks. On Tue, Jul 28, 2020 at 4:00 AM Giuseppe Vitillaro <giuseppe@...> wrote:
-- Mike A Schwab, Springfield IL USA Where do Forest Rangers go to get away from it all? |
On Tue, 28 Jul 2020, Rob Prins via groups.io wrote:
Hi Peppe, Ouch, I missed this, thanks Rob! So it is actually easier, maximum 7 bytes, i.e. 14 hex digits. In any case probably the "EX" instruction is the easier way to go? Shouldn't coding unrolled 7 routines for each remainder faster? Peppe. |
On Tue, 28 Jul 2020, Mike Schwab wrote:
Yes, EX is used to put varying lengths into instructions.Yep, I think I'm converging ;-) TR/MVC instructions have an LL field which may handle up to 256 bytes, while UNPK use the LL field for both source and target, up to 7 digits. Which lead to a loop for UNPK, modulo 7, up to a complete 256 bytes buffer ready for "TR/MVC", modulo 256. This should be the faster way, probably. Lol ... more I understand of 370 arch more fun I get ;-) Peppe. |
Hi Peppe,
An EX instruction is OR'ing the low order 8 bits of the R1 (mentioned in the EX instruction) over bits 8-15 of the instruction that is OR'ed. So be careful to EX to a SS-2 type instruction. The length fields of a SS-2 type instruction does have a maximum of 16.? In the object code of the instruction the length is always minus 1. So, the If you want to pack 16 bytes the low order 8 bits of the register in the EX should contain e.g. 7F (PACK? field1(8),field2(16)) Cheers, Rob |
On Tue, 28 Jul 2020, Rob Prins via groups.io wrote:
Hi Peppe, Thanks Rob, your advices are appreciated. Currently, as an example, I'm looking to a PL/I (for the modern Z/OS PL/I compiler) assembler routine DWNSHEX (got it from CBT, I don't remember the name of the original package): * THIS SUBROUTINE SHOULD BE DECLARED AS FOLLOWS :- * DCL DWNSHEX ENTRY(BIT(*) ALIGNED) RETURNS(CHAR(???) VAR); * WHERE ??? SHOULD BE REPLACED BY ANY NUMBER SUITABLY LARGE FOR THE * PARTICULAR APPLICATION PROGRAM. * TO CALL THIS SUBROUTINE (ACTUALLY A FUNCTION) ONE SHOULD CODE * SOMETHING LIKE :- * HEX_CHARS = DWNSHEX(BIT_STRING); * OR * HEX_CHARS = DWNSHEX(UNSPEC(ANY_VARIABLE)); * * AUTHOR :- DAVID W NOON * APRIL 1990 to hex dump a BIT string. It doesn't look so different from what I'm trying to achieve, it actually use EX for TR/MVC, although in a different way, to solve a different problem (HEX function is a builtin function in modern PL/I implementations). In the line of principle it can even adapted to PL/I-F, changing the calling sequence, but I bet dumping a BIT PL/I variable (using UNSPEC on a string) would be slower than directly dumping a string. Peppe. |
Hi Peppe,
Below you will find an example for a HEXCONV. This piece of code is used in the RPF browser for load modules. HEXCONV? DS??? 0H????????????????????????????????????????????????????? ???????? ST??? R14,SAVE14HX??????????? Save register 14??????????????? ???????? LR??? R6,R1?????????????????? Save length???????????????????? ???????? MVI?? RECHEX1,X'40'?????????? Blank the?????????????????????? ???????? MVC?? RECHEX1+1(L'RECHEX1-1),RECHEX1?? records??????????????? ???????? MVC?? RECHEX2,RECHEX1???????????????????????? first?????????? ???????? LA??? R3,RECORD+10??????????? Point to record with data?????? ???????? LA??? R4,RECHEX1+10?????????? Point to record with hi nibbles ???????? LA??? R5,RECHEX2+10?????????? Point to record with lo nibbles HEXC005? DS??? 0H????????????????????????????????????????????????????? ???????? MVC?? RHEXINP,0(R3)?????????? Input character from record???? ???????? SYCONVHX IN=RHEXINP,OUT=RHEXOUT,L=1 convert to printable hex? ???????? MVC?? 0(1,R4),RHEXOUT???????? Move 1st nibble in 1st record?? ???????? MVC?? 0(1,R5),RHEXOUT+1?????? Move 2nd nibble in 2nd record?? ???????? LA??? R3,1(,R3)?????????????? Next pos. input rec with chars? ???????? LA??? R4,1(,R4)?????????????? Next pos. record with hi nibbles ???????? LA??? R5,1(,R5)?????????????? Next pos. record with lo nibbles ???????? BCT?? R6,HEXC005????????????? Loop until all done???????????? ???????? MVC?? RECORD,RECHEX1????????? Move record with high nibbles?? ???????? PUT?? RPFPRT2,OUTAREA???????? Write record??????????????????? ???????? MVC?? RECORD,RECHEX2????????? Move record with low? nibbles?? ???????? PUT?? RPFPRT2,OUTAREA???????? Write record??????????????????? ???????? L???? R14,SAVE14HX??????????? Restore register 14???????????? ???????? BR??? R14 I start here at offset 10 (see the loadmodule browse of RPF 1.8.3). Length is in register 1. Cheers, Rob ??????????????????????????????? |
to navigate to use esc to dismiss