I've been looking into calling an Assembler module from REXX using LINKMVS, and this works fine. But, I'd like to pass a field that is longer than the max 32,767 bytes that can be passed by LINKMVS. Looking through the IBM manual (TSO/E REXX Reference) I've found reference to SHVBLOCK which looks like it allows me to access REXX variables from an Assembler module.
I haven't tried to use this yet, and have a few queries before I begin:
- Is this what I should be looking at to allow me to reference REXX variables in an Assembler module called by the REXX ?
- Can I alter REXX variables in the Assembler module ?
- As I imagine it'll take me a while to get my head around this, is it possible to write dumps from the Assembler routine so I can see what the control blocks look like ? I've added a dump and get the PSW/Registers written to the log, but I don't know how to write a dump.
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
The "official" routine to obtain Rexx (or CLIST) variables at least in a TSO environment is IKJCT441.
IKJCT441 can create as well as alter Rexx or CLIST variables.
I have one near production module that uses IKJCT441. It was done 10 years ago. I used it off and on with no known problems, but as it happens I have little use for it as I developed other means to replace the TSO command used in Rexx/CLIST code. Send me a PM with your E-mail and I'll send you the code that uses IKJCT441. At well over 500 lines it is far too large to include in a response.
Writing code to create dump style output is not too terribly difficult. I never developed a general module for the purpose but always wrote a custom dumper for each use when I felt the need. It generates lines like this -
hhhh ddddd represent the relative offset of the data in the line in hex and decimal. hhhhhhhh is 8 hex digits for 4 bytes of binary data; ttttttttttttttt is translated text for the data in the line. This displays quite well on a 80 byte 3270 display. Just a few thoughts.
Define an output line using statements like these -
GENTAB DC AL2(00,DWORD1-DL+0,DTEXT-DL+01)
DC AL2(01,DWORD1-DL+2,DTEXT-DL+02)
DC AL2(02,DWORD1-DL+4,DTEXT-DL+03)
DC AL2(03,DWORD1-DL+6,DTEXT-DL+04)
DC AL2(04,DWORD2-DL+0,DTEXT-DL+05)
DC AL2(05,DWORD2-DL+2,DTEXT-DL+06)
DC AL2(06,DWORD2-DL+4,DTEXT-DL+07)
DC AL2(07,DWORD2-DL+6,DTEXT-DL+08)
DC AL2(08,DWORD3-DL+0,DTEXT-DL+09)
DC AL2(09,DWORD3-DL+2,DTEXT-DL+10)
DC AL2(10,DWORD3-DL+4,DTEXT-DL+11)
DC AL2(11,DWORD3-DL+6,DTEXT-DL+12)
DC AL2(12,DWORD4-DL+0,DTEXT-DL+13)
DC AL2(13,DWORD4-DL+2,DTEXT-DL+14)
DC AL2(14,DWORD4-DL+4,DTEXT-DL+15)
DC AL2(15,DWORD4-DL+6,DTEXT-DL+16)
GENTABN EQU (*-GENTAB)/6
Each entry in the table defines how to construct an output line. The first two bytes represent the offset in 16 bytes for each byte in the 16 bytes, followed by 2 bytes that define the offset of the byte in the hex area that is translated to 2 hex digits, followed by 2 bytes that define the offset in the output line for the text data for the byte.
Define a translate table like this to convert non-printable bytes to . This table allows lower case letters, upper case letters and numbers to print -
Code:
LCA EQU C'A'-X'40'
LCJ EQU C'J'-X'40'
LCS EQU C'S'-X'40'
TRTAB DC 0CL256' ',(C' ')C'.',C' ',(LCA-(*-TRTAB))C'.'
DC 9AL1(*-TRTAB),(LCJ-(*-TRTAB))C'.'
DC 9AL1(*-TRTAB),(LCS-(*-TRTAB))C'.'
DC 8AL1(*-TRTAB),(C'A'-(*-TRTAB))C'.'
DC 9AL1(*-TRTAB),(C'J'-(*-TRTAB))C'.'
DC 9AL1(*-TRTAB),(C'S'-(*-TRTAB))C'.'
DC 8AL1(*-TRTAB),(C'0'-(*-TRTAB))C'.'
DC 10AL1(*-TRTAB),(256-(*-TRTAB))C'.'
There is a lot of Assembler trickery in this table. It won't work with the Assist Assembler if you have that. I built these tables from memory, but I think they will assemble correctly.
Regarding writing a dump from the Assembler module, your post got me thinking. What I've done is to write what I am looking for to a dataset. Not as straightforward as just sticking in a H'00' and looking at the SYSUDUMP, but better than just the registers printed to the Log. And once I get me head around your suggestions for printing the storage in dump format (many thanks for that) and written the code, I'll be able to re-use at a later date.
I've another question you may be able to help with. I've attempted to run my REXX in batch but am hitting problems (most likely because I've not set up the environment correctly). But, if I do get it set up and make the Assembler module dump, will this write a dump to SYSUDUMP ? I'm just wondering if it's worth persevering with this , or to spend my time writing my own code to dump out the storage.
Joined: 30 Nov 2013 Posts: 917 Location: The Universe
Personal opinion. For data described in a DSECT something like the little dumper I outlined is better than SYSUDUMP or SNAP. Lots better. An offset is much easier than deal with than trying to convert a storage address to the offset in a DSECT. Finding storage in a printed dump is a pain in the you no where.
You can add, update and delete REXX variables from an assembler program. I find IRXEXCOM to be the easyest interface. The program must be started as a REXX function, i.e. rval=MyPgm(options).
You can find a set of macros for REXX variable access here: