Hi David,
I used LE for a couple of reasons:
- I like the use of AUTO/STACK storage, as it is automatically
allocated, is reentrant, and works both in batch and under CICS.
- I’m now “used” to it.
How much overhead is it really? Since I’m calling it from COBOL then the LE
enclave is already set up.
That being said, I really like your idea. Someone else mentioned why don’t I
create a table with the number of rows already in it. The answer to that is
simply:
- I didn’t think of it.
- EXEC CICS LOAD gave me the length of the table, and thus (when I was
only doing it under CICS) I didn’t have cause to think about it any further.
So now I can’t decide which way to go. I’m growing rather fond of yours.
Certainly it beats my idea of using BLDL to get the length. ☺
I do have a question. Why do you use LM and STM to load the fields in to
registers and then out to memory again, rather than just using MVC for a
“memory to memory” move?
This is what I have now, and seems to work fine. (renamed a few things and
changed a few others “just because”).
*PROCESS RENT
XML1XYZ CSECT ,
XML1XYZ RMODE ANY
XML1XYZ AMODE ANY
TABLE DS 0H
ROW1 DC CL80'ROW1'
DC CL80'ROW2'
DC CL80'ROW3'
DC CL80'ROW4'
DC CL80'ROW5'
DC CL80'ROW6'
DC CL80'ROW7'
DC CL80'ROW8'
DC CL80'ROW9'
TSIZ EQU *-TABLE
RCNT EQU (TSIZ/L'ROW1)
*
MAINLINE CSECT ,
MAINLINE RMODE ANY
MAINLINE AMODE ANY
USING MAINLINE,15
USING ARGS,1
L 1,ARGS
USING ARG1,1
MVC ARG1(ARG1_L),CONSTS
SR 15,15
BR 14
CONSTS DS 2A
ORG CONSTS
_TBL@ DC A(TABLE)
_ROWCNT DC A(RCNT)
*
ARGS DSECT ,
ARG1@ DS A
*
ARG1 DSECT ,
TBL@ DS A
ROWCNT DS F
ARG1_L EQU *-ARG1
END MAINLINE
Thanks for your help! I don’t think assembler will ever come naturally for me,
but hopefully I can at least retain what I’ve learned.
Frank
From: David S. <[email protected]<mailto:[email protected]>>
To: [email protected]<mailto:[email protected]>
Sent: Thursday, December 10, 2015 7:31 AM
Subject: Re: Review My Program
I think the LE compliant Assembler wrapper is way over-the-top for this.
LE compliant Assembler is *vital* of course when *it* calls an LE-compliant
subroutine, but when Assembler is the callee and the code is *very* short
and simple, the overhead really serves no purpose.
I'd also make your assembler code a prefix to the table itself rather than
a separate module. You describe the table as "... assembler" so you can
easily add a tiny bit of code to the table itself which can then tell COBOL
everything it needs to know -> table address, length, number of rows,
length of each row, etc, whatever you like. All that information can
easily be determined at assembly time and returned to COBOL, thus not
obliging the caller to figure them out (and possibly getting them wrong!).
Now, instead of calling something else to load the table, you just call the
table itself, dynamically, which then both loads it *and* tells you
everything you need to know about it.
To accomplish what your example describes, you just need the table address
and number of rows. So, assuming those criteria, I offer the the following
simplified example which does exactly the same thing:
IDENTIFICATION DIVISION.
PROGRAM-ID. SIZETST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TABLE-DATA.
05 TABLE-ADDRESS POINTER.
05 ROWCNT PIC S9(9) COMP.
05 XML1V2K PIC X(8) VALUE 'XML1V2K'.
LINKAGE SECTION.
01 MYTAB.
05 MYROW PIC X(80)
OCCURS 1 DEPENDING ON ROWCNT INDEXED BY ROWNBR.
PROCEDURE DIVISION.
CALL XML1V2K USING TABLE-DATA
SET ADDRESS OF MYTAB TO TABLE-ADDRESS
PERFORM VARYING ROWNBR FROM 1 BY 1 UNTIL ROWNBR > ROWCNT
DISPLAY MYROW(ROWNBR)
END-PERFORM
GOBACK.
Here is a sample table of nine 80-byte rows, with that "tiny bit" of
assembler code at the end which gives COBOL needs.
XML1V2K CSECT
XML1V2K RMODE ANY
ROW1 EQU *
DC CL80'ROW1'
ROW2 EQU *
DC CL80'ROW2'
DC CL80'ROW3'
DC CL80'ROW4'
DC CL80'ROW5'
DC CL80'ROW6'
DC CL80'ROW7'
DC CL80'ROW8'
DC CL80'ROW9'
END EQU *
TSIZ EQU END-ROW1
RSIZ EQU ROW2-ROW1
INIT CSECT
INIT RMODE ANY
USING INIT,15
L 1,0(,1) R1 -> AREA TO RECEIVE TABLE ADDRESS, NBR OF ROWS
LM 15,0,TBL@ R15 = TABLE ADDRESS, R0 = NBR OF ROWS
STM 15,0,0(1) STORE IN CALLERS RECEIVE AREA
SR 15,15 SET R15 = 0
BR 14 RETURN
TBL@ DC A(ROW1) ADDRESS OF FIRST ROW (I.E. TABLE ADDRESS)
ROWS DC A(TSIZ/RSIZ) NBR OF ROWS = TABLE SIZE MINUS ROW SIZE
END INIT
Note that the END INIT statement sets the entry point to INIT, the
assembler suffix code, but the load point (start of table) remains the
same.
The information contained in this electronic communication and any document
attached hereto or transmitted herewith is confidential and intended for the
exclusive use of the individual or entity named above. If the reader of this
message is not the intended recipient or the employee or agent responsible for
delivering it to the intended recipient, you are hereby notified that any
examination, use, dissemination, distribution or copying of this communication
or any part thereof is strictly prohibited. If you have received this
communication in error, please immediately notify the sender by reply e-mail
and destroy this communication. Thank you.