EXEC CICS LINK PROGRAM('REQMYPGM') COMMAREA(MPGMCOMM)
can you please tell me if all the fields defined below MPGMCOMM be passed in the commarea ? or is it the address that is passed ?
well, i quite sure that all the parameters below MPGMCOMM should passed to the sub-pgm for it to work. but how is it just using MPGMCOMM and passing all the parameters. can DS 0D be similar to a 01 level in cobol ? but even then there is another 0D and 0CL22 ..
Joined: 09 Mar 2011 Posts: 7309 Location: Inside the Matrix
It is, as with all types of transfer-of-control-to-another-program, an address that is passed. Fields themselves are never passed. It is up to the transferred-to program to define the fields it is going to use and, obviously, it is a good idea if they match with those in the transfer-from program.
and in the sub-program,i would have the same structure (01 MPGMCOMM) declared in linkage DFHCOMMAREA...
In my assembler program - the commarea is MPGMCOMM (a double word). how can having only this storage variable in commarea pass the list of storage items defined below it . ? is it like a 01 level in cobol ?
Bill O'Boyle wrote:
Check in your LINKING program as LENGTH in the LINK might be generated by the translator as a Y(L'MPGMCOMM).
Yes , the translator has the length as Y(L'MPGMCOMM), But what would be its value ? only 8 or 8+8+22+3+1+2+4 ?
Joined: 06 Jun 2008 Posts: 8696 Location: Dubuque, Iowa, USA
Jepson: COBOL and Assembler work in a similar manner (although you can change COBOL behavior by changing the CALL statement, for example). The ADDRESS -- which is a 4-byte hexadecimal value -- is what is passed between programs. It is up to the programmer of the calling and called programs to ensure that the data looks and is handled the same. It is quite easy to prove only the address is passed. Set up a test program that has
Code:
01 WS-COMMAREA.
05 WS-CA1 PIC X(04) VALUE 'TEST'.
05 WS-CA2 PIC X(08) VALUE 'ABCDEFGH'.
If only the address is passed, CALL-X will contain TESTABCD and CALL-Y will contain EFGH in the called program. If the data is passed explicitly, CALL-X would have TEST followed by 4 spaces and CALL-Y would have ABCD.
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
Because MPGMCOMM is a doubleword, Y(L'MPGMCOMM) would be 8. Look in your LTORG in the program listing.
If you need to pass all the fields you have posted, then you'll need the length equate in the LINKING program. For the LENGTH keyword, specify it as LENGTH(=Y(L'MPGMCOMM)). You can also look in your LTORG and verify it has been generated for the correct value.
Yes, it looks like you have the correct COBOL layout.
But, a word of warning. Try to avoid SYNC definitions in COBOL, which resolve to aligned H, F and D (Halfwords, Fullwords and Doublewords) in Assembler, as future maintenance could be a little dicey down the road if someone doesn't understand the subtleties.
Aligned Halfwords, Fullwords and Doublewords (in WS) are a necessity in Assembler, but I don't see their benefit in COBOL anymore. But, not to say, they can't be used.
Ensure all your commarea data is UNALIGNED (as yours is) and you'll sleep better....
@ Robert, Bill Woodker,
Totally agree that the commarea itself is passed as an address(for which CICS does the getmain and freemain ..).
i'm trying to figure how is it that by passing a singe storage variable in the commarea my linked sub-program is able to access all the fields defined in DSECT.
Mr Bill,
yes, LTORG shows 8. and i don't have the length equate in my code. (i'll have to find out how LENGTH(=Y(L'MPGMCOMM)) would help pass all the fields, i'll get back to you on this one .. )
nd Sry abt the unaligned code, i'm actually keying in the code again here.... otherwise its usually as it shld be :-)
I still don't get how my program does a "EXEC CICS LINK PROGRAM('REQMYPGM') COMMAREA(MPGMCOMM)", and the Linked sub-program is able to access all the fields defined in the DSECT that follow MPGMCOMM DS 0D .
I think i need to run thru my program once again to see if i'm missing something... i'm quite new to assembler, so it kindda takes me some time to check even the simplest of things..
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
For your commarea length equate, take a look at -
Code:
MPGMCOML EQU *-MPGMCOMM
which I had included in a previous post.
Then, to use it as the commarea length hword in the LINK (or XCTL) API, specify LENGTH(=Y(MPGMCOML)) or LENGTH(=AL2(MPGMCOML)).
The AL2 might be better, because it generates an unaligned binary-hword, whereas, the Y generates an aligned binary-hword.
I use the AL2 because when you're working with Assembler, saving base-register addressability is always a good thing, because you never know when you're going to need it.
But, passing an address could bite you if someone decides to define the sub-program remotely (as in another region). Then the address you're passing cannot be used in that remote region and you could stomp on a key piece of storage being used by another task in that remote region or raise a S0C4 Protection Exception.
Basically, addresses can be used if you're in the same region only. But, IBM has always discouraged this, regardless.
Joined: 01 Sep 2006 Posts: 2547 Location: Silicon Valley
Quote:
i'm trying to figure how is it that by passing a singe storage variable in the commarea my linked sub-program is able to access all the fields defined in DSECT.
Say for example, that the getmain'ed area is 100 bytes long. The 100 bytes are in contiguous storage.
You are passing the address of the first byte. The first byte and the other 99 bytes still remain in their original location, regardless of who refers to them. So you can refer to the rest of the storage because they are contiguous to the location you know.
Ideally, you would define your data structures in one member that is included by the programs that use it, so that the names and lengths are always in synch. Because two languages are involved, you have to maintain two structures manually.
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
Pedro,
Commareas are GETMAINED (internally, based upon EIBCALEN) and then copied to the GETMAIN storage-area, regardless of the language. This is done to ensure addressability between the two programs, such as an AMODE difference (AMODE 31 program linking to an AMODE 24 program).
If you pass an outright AMODE 31 address in a commarea to an AMODE 24 program and it attempts establishing addressability, the high-order byte will be truncated and you'll have an invalid address, followed by an ensuing S0C4.
With that, how would passing an address work in a DPL (Distributed Program Link) to a remote region?
He would need to pass the entire commarea of 32-Bytes.
Mr Bill,
"specify LENGTH(=Y(MPGMCOML) - " in this case i understand the commarea size is given by MPGMCOML . nd this should be fine.
but i my case, the length parameter is not mentioned in the CICS LINK,
Code:
EXEC CICS LINK PROGRAM('REQMYPGM') COMMAREA(MPGMCOMM)
DFHECALL =X'something...',(CHA8,=CL8'REQMYPGM'),(_____
F,MPGMCOMM),(FB_2,=Y(L'MPGMCOMM))
though there is the length calculation done similarly as you have shown, but it is not used in the CICS LINK. without mentioning the length of commarea how will CICS know how many fields in the DSECT should be addressable.. ?
(well, these program have been running in prod for a long time.. i'm trying to understand how they work..)
or is it like- In the invoked program when we say
L R5,DFHEICAP
USING PGMCOM,R5
(where PGMCOM - is the DSECT)
the addressability is established for the first storage location MPGMCOMM in the DSECT.==>in effect assign the address of MPGMCOMM declared in invoking program to the DSECT in the invoked program.
If this is the case then and what ever follows the first variable will also have addresses corresponding to that defined in the invoking program's commarea. I really think this is very unlikely ...(- given that CICS does the getmain and freemain for the commarea.) but not very sure if i'm missing some print.
Joined: 14 Jan 2008 Posts: 2501 Location: Atlanta, Georgia, USA
If you don't specify the LENGTH keyword in the LINK API, the translator will generator a halfword, based upon the length of the label specified in the COMMAREA keyword.
In your example, it does exactly what it's supposed to, but not what you needed.
Therefore, because you need to pass the entire 32-Bytes, you must specify, in your LINK API -
Code:
LENGTH(=Y(MPGMCOML))
which is the length equate previously posted and it will resolve as a H'32' (X'0020').
If you allow the translator to default and build the halfword length, you'll wind up with (as you've posted) -
Code:
LENGTH(=Y(L'MPGMCOMM))
which will resolve as a H'8', because "MPGMCOMM" is a doubleword, which is 8-Bytes long.
If you use the length equate method, that will be correct.
Remember, commareas are COPIED (regardless of the language) and the address of the commarea specified in the LINKING program (the address of MPGMCOMM) will be different when the LINKER is invoked.
As an exercise, walk the transaction through via CEDF and note the commarea-address (on the right side of the screen - hit <F2> for HEX) before the LINK and when the LINKER gets invoked, note the commarea-address will be different.