IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

how should commarea be defined in an assembler pgm?


IBM Mainframe Forums -> PL/I & Assembler
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
jepson

New User


Joined: 24 Oct 2008
Posts: 7
Location: India

PostPosted: Wed Oct 12, 2011 3:14 pm
Reply with quote

How does this worK -

Code:
MPGMCOMM   DS   0D
PAPDSECT                   DS   0D
* i/O ACCESS PARAMETERS
PGMKEY      DS   0CL22
PGMA      DS   CL6
PGMB      DS   CL12
PGMC      DS   CL4
PGMREQ      DS   CL3   
PGMTYP      DS   CL1
PGMRC      DS   CL2
PGMADDR      DS   A
...
..


After some validation ,i have

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 ..
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Wed Oct 12, 2011 3:24 pm
Reply with quote

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.
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Wed Oct 12, 2011 4:31 pm
Reply with quote

You can define it in the LINKED program under a DSECT with a length equate -

Code:

DFHCOMMA DSECT
         USING *,R7                   INFORM ASSEMBLER
MPGMCOMM DS 0D
PAPDSECT DS 0D
* i/O ACCESS PARAMETERS
PGMKEY DS 0CL22
PGMA DS CL6
PGMB DS CL12
PGMC DS CL4
PGMREQ DS CL3
PGMTYP DS CL1
PGMRC DS CL2
PGMADDR DS A
MPGMCOML EQU *-MPGMCOMM
* VALIDATE COMMAREA
         LH    R1,EIBCALEN
         CHI  R1,MPGMCOML
         BL    CICSRETN               RETURN TO CICS
         L      R7,DFHEICAP           COMMAREA-ADDRESSABILITY


Check in your LINKING program as LENGTH in the LINK might be generated by the translator as a Y(L'MPGMCOMM). So, adjustments would be necessary.

Passing addresses can be done, but shouldn't.

Mr. Bill
Back to top
View user's profile Send private message
jepson

New User


Joined: 24 Oct 2008
Posts: 7
Location: India

PostPosted: Wed Oct 12, 2011 5:36 pm
Reply with quote

Thank you Mr Bill and Mr Bill Woodger for your response.
i'm trying to relate this to cobol - in cobol i would have-
Code:

01 MPGMCOMM.
     05 PGMKEY pic x(22).
     05 PGMREQ pic x(03).
     05 PGMTYP pic X(01).
     05 PGMRC pic X(02).
     05 PGMADDR USAGE IS POINTER.
      ....
01 other variables ..

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 ?
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8696
Location: Dubuque, Iowa, USA

PostPosted: Wed Oct 12, 2011 5:45 pm
Reply with quote

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'.
and set up your called program as
Code:
01  DFHCOMMAREA.
     05  CALL-X PIC X(08).
     05  CALL-Y PIC X(04).
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.
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Wed Oct 12, 2011 5:48 pm
Reply with quote

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.... icon_wink.gif

Mr. Bill
Back to top
View user's profile Send private message
jepson

New User


Joined: 24 Oct 2008
Posts: 7
Location: India

PostPosted: Thu Oct 13, 2011 12:32 am
Reply with quote

@ 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..
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Thu Oct 13, 2011 1:11 am
Reply with quote

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. icon_eek.gif

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.

YMMV....

Mr. Bill
Back to top
View user's profile Send private message
Pedro

Global Moderator


Joined: 01 Sep 2006
Posts: 2547
Location: Silicon Valley

PostPosted: Thu Oct 13, 2011 5:26 am
Reply with quote

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.
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Thu Oct 13, 2011 5:46 am
Reply with quote

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
Back to top
View user's profile Send private message
jepson

New User


Joined: 24 Oct 2008
Posts: 7
Location: India

PostPosted: Sat Oct 15, 2011 12:17 am
Reply with quote

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.
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Sat Oct 15, 2011 12:34 am
Reply with quote

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.

HTH....

Mr. Bill
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> PL/I & Assembler

 


Similar Topics
Topic Forum Replies
No new posts Build dataset list with properties us... PL/I & Assembler 4
No new posts Finding Assembler programs PL/I & Assembler 5
No new posts How Can I Recall a Migrated Data Set ... PL/I & Assembler 3
No new posts step by step trace 4 ISPF dialog call... TSO/ISPF 17
No new posts CICS COMMAREA CICS 3
Search our Forums:

Back to Top