You can imagine my immediate frustration when I went off into the EXCP world (by accident). Then I cheated a little bit and had a peek at George Struble's _Assembler Language Programming for The IBM System/370 Family_. The 3rd edition printed 1984, 1st in 1964.
Then I found myself in the QSAM arena, and after that it was quite easy. Here is my PGM and the two biggest problems I had:
COPYFILE START 0
YREGS
COPYFILE CSECT ,
COPYFILE AMODE 24
COPYFILE RMODE 24
DS 0H
BAKR R14,0 Save caller's ARs and GPRs
LR R12,R15 Set up 1st base register
USING COPYFILE,R12 and inform assembler
OPEN (DCBIN1,(INPUT),DCBOUT1,(OUTPUT))
LOOP DS 0H
GET DCBIN1,INOUTBUF
PUT DCBOUT1,INOUTBUF
B LOOP
EOF DS 0H no more records
CLOSE (DCBIN1,,DCBOUT1)
XR 15,15
PR ,
DCBIN1 DCB BLKSIZE=80,DDNAME=INPUT,RECFM=FB,LRECL=80,DSORG=PS, X
EODAD=EOF,MACRF=GM
DCBOUT1 DCB BLKSIZE=80,DDNAME=OUTPUT,RECFM=FB,LRECL=80,DSORG=PS, X
MACRF=PM
INOUTBUF DS CL80 Input/Output Storage Area
END ,
Notes:
1. That EODAD is nice. As a matter of fact, this looks strangely a lot like a Cobol program. I can almost see where Grace got her inspiration.
2. Those horrible S0C4's. First one was a S0C4-10, unknown module, and happened on the OPEN. How could I have debugged this? The problem that I found from reading (yes reading the docs, I do) the docs carefully, was that DCB's have to be in 24 bit mode storage. Whoops. Where (and what kind of) in the dump would show that information?
3. A S0C4-11 because I coded an MVC incorrectly. I coded this:
MVC INOUTBUF(80),=C'Test record'
INOUTBUF DS CL80
A change to MVC INOUTBUF(11),='Test record' works just fine.
I cheated on this one, too. I wasn't able to tell the problem in the dump. The dump told me it was the MVC instruction that was wrong, so I just guessed that it was because the MVC wasn't correct.
4. The MACRF options need to be correct, but the assembler warned me about those. The docs showed all the options, not just QSAM, so I got them mixed up a little. And I still need to know what MF=T means. The book just says "watch this one." I guess in 1969, that was enough.
here is some more
>> 2. Those horrible S0C4's. First one was a S0C4-10, unknown module,
>> and happened on the OPEN. How could I have debugged this? The
>> problem that I found from reading (yes reading the docs, I do) the
>> docs carefully, was that DCB's have to be in 24 bit mode storage.
>> Whoops. Where (and what kind of) in the dump would show that
>> information?
If you look at the expansion of the DCB macro...you will see that EODAD
is stored in a 3 byte fields. I know that the VSE LNKEDT does tell you
that the module you try to link with an attribute of RMODE ANY/31 does
have addresses that use only 3 bytes. I have no clue why the BINDER
does not behave the same...wait, it could be that you had RMODE in the
control-information for the LNKEDT/binder in which case the
system determines...if s/he demands it...no need to complain - (he
knows what he is doing).
>> 3. A S0C4-11 because I coded an MVC incorrectly. I coded this:
MVC INOUTBUF(80),=C'Test record'
You did realy want the machine to move everything starting at the
location where "Test record" is in a length of 80 to INOUTBUF?
Apparently you crossed a page boundary between used and not used storage
(very likely in this case- very unlikely usualy)... this is
where the hardware kicks in....with those S0C4
>> A change to MVC INOUTBUF(11),='Test record' works just fine.
And MVC INOUTBUF,=CL(L'INOUTBUF)='Test record' would have worked as
well.
Much better solution is what (ITIR) Ed J. uses ... a MACRO called
MVCSL (or so) which means MVC in sender length.
--
Martin
Pi_cap_CPU - all you ever need around MWLC/SCRT/CMT in z/VSE
more at http://www.picapcpu.de
I don't know what specifically caused the S0C4, you say it was the EODAD address?
Part of the causes of my problems are most likely due to the overly pedantic way that I go about learning something new. First I got the OPEN to work. Then CLOSE, then a test PUT. Then the GET/PUT loop. When I couldn't figure out where the problem was I put an ABEND one statement after the other until I figured out what line caused the problem.
This is in my ASM code:
COPYFILE CSECT ,
COPYFILE AMODE 24
COPYFILE RMODE 24
And this is what I told the LKED:
//LKED EXEC PGM=IEWL,REGION=2M,COND=(0,NE),
// PARM='LIST,XREF,MAP,RENT,REUS,REFR,NCAL'
//SYSPRINT DD SYSOUT=*
//SYSUT1 DD UNIT=(DISK,SEP=(SYSLIN,SYSLMOD)),SPACE=(CYL,(1,1))
//SYSLMOD DD DISP=SHR,DSN=IBMUSER.LINDY.LOAD
//SYSLIN DD DISP=(OLD,PASS),DSN=&&OBJ1
// DD *
ENTRY COPYFILE
NAME COPYFILE(R)
/*EOF
>> I don't know what specifically caused the S0C4, you say it was the
>> EODAD address?
No- You moved 80 bytes but had only 11 ...if it is the very end of your
program (likely) this will overlap into something where the hardware
can limit (disallow to see/not there= SOC4)
------Original Message------
From: Martin Truebner
Sender: IBM Mainframe Assembler List
To: ASSEMBL...@LISTSERV.UGA.EDU
ReplyTo: IBM Mainframe Assembler List
Subject: Re: ASM Program to copy a file
I'm surprised you remember this! It was something I accidentally left in a
sample code fragment in a SHARE presentation years ago.
We call the macro MVC2: MVC using the length of the second operand.
We also have MVCX: generate as many MVCs as needed to copy variables of any
length without using MVCL. (Yes, I realize MVCX is the name of a millicode
mnemonic, but I think the chances of that instruction being exposed to 'normal'
code is unlikely.) We also have XCX, OCX, and others.
I just realized we are missing MVC2X! Lol!
--
Edward E Jaffe
Phoenix Software International, Inc
831 Parkview Drive North
El Segundo, CA 90245
310-338-0400 x318
edj...@phoenixsoftware.com
http://www.phoenixsoftware.com/
The /*EOF is useless and meaningless
Why are you using RENT, REUS, REFR as binder parms?
Your program is not reentrant nor refreshable; guess it
might be reusable, but that's usually reserved for
subroutines.
>
>
> -----Original Message-----
> From: IBM Mainframe Assembler List [mailto:ASSEMBL...@LISTSERV.UGA.EDU] On Behalf Of Martin Truebner
> Sent: Thursday, December 08, 2011 6:15 PM
> To: ASSEMBL...@LISTSERV.UGA.EDU
> Subject: Re: ASM Program to copy a file
>
> Lindy,
>
> here is some more
>
>>> 2. Those horrible S0C4's. First one was a S0C4-10, unknown module,
>>> and happened on the OPEN. How could I have debugged this? The
>>> problem that I found from reading (yes reading the docs, I do) the
>>> docs carefully, was that DCB's have to be in 24 bit mode storage.
>>> Whoops. Where (and what kind of) in the dump would show that
>>> information?
>
> If you look at the expansion of the DCB macro...you will see that EODAD is stored in a 3 byte fields. I know that the VSE LNKEDT does tell you that the module you try to link with an attribute of RMODE ANY/31 does have addresses that use only 3 bytes. I have no clue why the BINDER does not behave the same...wait, it could be that you had RMODE in the control-information for the LNKEDT/binder in which case the system determines...if s/he demands it...no need to complain - (he knows what he is doing).
>
--
Kind regards,
-Steve Comstock
The Trainer's Friend, Inc.
303-355-2752
http://www.trainersfriend.com
* To get a good Return on your Investment, first make an investment!
+ Training your people is an excellent investment
* Try our tool for calculating your Return On Investment
for training dollars at
http://www.trainersfriend.com/ROI/roi.html
:>>> A change to MVC INOUTBUF(11),='Test record' works just fine.
:>And MVC INOUTBUF,=CL(L'INOUTBUF)='Test record' would have worked as
:>well.
Unless INOUTBUF is longer than the literal and the literal is near the end of
a page.
--
Binyamin Dissen <bdi...@dissensoftware.com>
http://www.dissensoftware.com
Director, Dissen Software, Bar & Grill - Israel
Should you use the mailblocks package and expect a response from me,
you should preauthorize the dissensoftware.com domain.
I very rarely bother responding to challenge/response systems,
especially those from irresponsible companies.
Omit the START statement; the CSECT statement does
the same thing.
> DS 0H
Don't need the above; your program is guaranteed to be
loaded at an address on a doubleword boundary at the
least
> BAKR R14,0 Save caller's ARs and GPRs
Why do you care about the caller's ARs? First, you are
a main program so the caller is z/OS. Overkill. Why not
use standard save area chaining?
> LR R12,R15 Set up 1st base register
> USING COPYFILE,R12 and inform assembler
> OPEN (DCBIN1,(INPUT),DCBOUT1,(OUTPUT))
> LOOP DS 0H
> GET DCBIN1,INOUTBUF
> PUT DCBOUT1,INOUTBUF
> B LOOP
> EOF DS 0H no more records
> CLOSE (DCBIN1,,DCBOUT1)
> XR 15,15
> PR ,
>
> DCBIN1 DCB BLKSIZE=80,DDNAME=INPUT,RECFM=FB,LRECL=80,DSORG=PS, X
> EODAD=EOF,MACRF=GM
For input files, if the file is standard labeled tape or disk,
or even SYSIN, you don't need BLKSIZE, RECFM, or LRECL
> DCBOUT1 DCB BLKSIZE=80,DDNAME=OUTPUT,RECFM=FB,LRECL=80,DSORG=PS, X
> MACRF=PM
You code RECFM=FB, so you should block your records up for
performance; set BLKSIZE as some multiple of LRECL up to
32760
Although if you are writing to SYSOUT, unblocked is fine
since JES will block it for you anyway; in that case, probably
better to code RECFM=F
> INOUTBUF DS CL80 Input/Output Storage Area
> END ,
>
>
> Notes:
> 1. That EODAD is nice. As a matter of fact, this looks strangely a lot like a Cobol program.
> I can almost see where Grace got her inspiration.
> 2. Those horrible S0C4's. First one was a S0C4-10, unknown module, and happened
> on the OPEN. How could I have debugged this? The problem that I found from
> reading (yes reading the docs, I do) the docs carefully, was that DCB's have
> to be in 24 bit mode storage. Whoops.
> Where (and what kind of) in the dump would show that information?
Not clear here. The dump will not show you that DCBs have to be in
24-bit storage. That piece of information comes from the docs:
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/Shelves/EZ2ZO213
DFSMS Using Data Sets SC26-7410-11 (the z/OS 1.13 version)
[ I love this quote, from the PDF version, p. 326 [logical
page number, 348 physical page number]]:
"It is not the intent of IBM to require extensive education
to use assembly language programming."
around this place in the doc, there is an extensive discussion
with samples
DFSMS Macro Instructions for Data Sets SC26-7408-10 (the z/OS 1.13 version)
starting in Chapter 5, non-VSAM data sets
The dump will show where your module is loaded, and since your
DCBs are coded in your module, your DCBs will be there; it the
load address of your module starts with x'00' or x'80', you
are in 24-bit storage; otherwise, you are in 31-bit storage.
> 3. A S0C4-11 because I coded an MVC incorrectly. I coded this:
> MVC INOUTBUF(80),=C'Test record'
> INOUTBUF DS CL80
> A change to MVC INOUTBUF(11),='Test record' works just fine.
> I cheated on this one, too. I wasn't able to tell the problem in the dump.
> The dump told me it was the MVC instruction that was wrong, so I just
> guessed that it was because the MVC wasn't correct.
Right. The default length for MVC is the length of the first
operand, the target. So you were moving 80 bytes from your
literal pool, but the literal is only 11 bytes; apparently
somewhere after the 11 byte literal your load module ended near
a page boundary, and when you tried to access the bytes on the
next page the hardware found that page was not assigned to you.
> 4. The MACRF options need to be correct, but the assembler warned me
> about those. The docs showed all the options, not just QSAM, so
> I got them mixed up a little.
The Macro instruction doc provides separate DCB parameter lists
for each organization (BDAM, BISAM, BPAM, BSAM, QISAM, QSAM) so
you have to pay attention there, and also to realize that you are
using QSAM. So the doc assumes a lot already, on the part of the
reader.
> And I still need to know what MF=T means. The book just says "watch this one."
Well, the IBM book doesn't mention that parameter at all.
> I guess in 1969, that was enough.
>
There are other resources available.
When I started, how many JCL decks I copied only changing the name of my program and DD names. What a waste, but that is what we did there in that small group, at that time. With very little or no training. (A state job. )
So, most surely the person I copied /*EOF from, had a good idea why he put it there.
Why are those binder parms there? I don't know, really. Should they be something different? Queries like these make me go to the docs and try to understand things better.
Lindy
BAKR R14,0 is a standard entry linkage approach. (At least, it has been since
the advent of ESA/390.) R13 should then be set to point to an F1SA.
> <snip>...[ I love this quote, from the PDF version, p. 326 [logical
> page number, 348 physical page number]]:
>
> "It is not the intent of IBM to require extensive education
> to use assembly language programming."--...<snip>
Good one Steve.
It may not be IBM's intent, but the fact is things have ended up that way...
Mike Shaw
MVS/QuickRef Support Group
Chicago-Soft, Ltd.
DCBIN1 DCB DDNAME=INPUT,EODAD=EOF,MACRF=GM,DSORG=PS
===
Why do I care about the caller's AR's? I copied the preamble from a properly written program that went briefly into supervisor mode. Otherwise, I normally don't.
I've so far made it a habit of starting and ending like this. One day I'll learn macro, though at this point in my life it feels like James Joyce.
BAKR 14,0
LR my-base-whatever,R15
USING etc
... ... ...
PR ,
===
Block size, etc, I didn't care about, because the idea of this exercise came from a comment about an interview of a potential assembler programmer: Write an assembly program on the white board there to copy one file to the next. I wrote a few Rexx functions, but never any standard print/punch IO. QSAM, or anything else.
===
I of course do know that the docs have to assume a certain level of knowledge, otherwise where to start? That's only fair. At my level, since I have to create my own challenges, I cannot expect anything other than to learn it all myself, and of course with help from my friends. And even with no friends, I can still learn on my own.
Back when I started, I remember, I was so excited when I found out there was documentation! They kept it on a table in the room near where the "older" smokers sat, so I didn't go in there very often. And in the middle of a pile of printouts I didn't notice such stuff. When I asked specifically about such-and-such doc I was told, documentation is expensive.
Mostly at first I learned 80+�% from reading existing code, and about 15% from a more senior person. In my case a great guy who didn't know a lot about facts, but could really get the job done. He was a good consultant. Oh, and he got good and stoned during lunch every day. This was about 1988 or so.
Unnecessary crap where it shouldn't be is/was one thing that tripped me up quite often. How many times I copied subroutines that I didn't use. Lots.
===
DFSMS, Chapter 5 - Been in front of me the whole day. :-)
===
AH! It was where my program was loaded that was the problem with the DCB's. Ok, that makes sense. I was wondering, how can I put my DCB's into 24 bit storage, but have my program run in 31 or 64 bit...
I am assuming here based on my limited knowledge, and most of what I read today: I would somehow put just the DCB's below, one way, perhaps, by using STORAGE OBTAIN LOC=BELOW and then using the DCB MF=L macro format. There is some more wizardry there I think, perhaps using USING's or some such.
Now, that is just from my head. And only because I looked at it for a long time today.
===
Perhaps someone will know more why it should be watched, but this I see in the docs:
T
requests the user totaling function. If this function is requested, EXLST should specify the address of an exit list that includes a totaling entry. T cannot be specified for a SYSIN or SYSOUT data set.
User totaling can be specified for only sequential data sets that are not extended format data sets. If specified for a partitioned data set, a PDSE, an extended format data set, or a UNIX file, user totaling is ignored.
Gerorge S. Says:
T (watch this one) substitute mode.
===
Thanks so much as always, Steve.
Lindy
-----Original Message-----
From: IBM Mainframe Assembler List [mailto:ASSEMBL...@LISTSERV.UGA.EDU] On Behalf Of Steve Comstock
Sent: Thursday, December 08, 2011 7:57 PM
To: ASSEMBL...@LISTSERV.UGA.EDU
Subject: Re: ASM Program to copy a file
> ===
>
> I of course do know that the docs have to assume a certain level of knowledge, otherwise where to start? That's only fair. At my level, since I have to create my own challenges, I cannot expect anything other than to learn it all myself, and of course with help from my friends. And even with no friends, I can still learn on my own.
>
> Back when I started, I remember, I was so excited when I found out there was documentation! They kept it on a table in the room near where the "older" smokers sat, so I didn't go in there very often. And in the middle of a pile of printouts I didn't notice such stuff. When I asked specifically about such-and-such doc I was told, documentation is expensive.
>
> Mostly at first I learned 80+�% from reading existing code, and about 15% from a more senior person. In my case a great guy who didn't know a lot about facts, but could really get the job done. He was a good consultant. Oh, and he got good and stoned during lunch every day. This was about 1988 or so.
>
> Unnecessary crap where it shouldn't be is/was one thing that tripped me up quite often. How many times I copied subroutines that I didn't use. Lots.
>
> ===
>
> DFSMS, Chapter 5 - Been in front of me the whole day. :-)
>
> ===
>
> AH! It was where my program was loaded that was the problem with the DCB's. Ok, that makes sense. I was wondering, how can I put my DCB's into 24 bit storage, but have my program run in 31 or 64 bit...
http://www.trainersfriend.com/General_content/Book_site.htm#Assembler-3
>
> I am assuming here based on my limited knowledge, and most of what I read today: I would somehow put just the DCB's below, one way, perhaps, by using STORAGE OBTAIN LOC=BELOW and then using the DCB MF=L macro format. There is some more wizardry there I think, perhaps using USING's or some such.
>
> Now, that is just from my head. And only because I looked at it for a long time today.
>
> ===
And as far as coding reentrantly:
http://www.trainersfriend.com/General_content/Book_site.htm#Assembler-2
>
> Perhaps someone will know more why it should be watched, but this I see in the docs:
>
> T
> requests the user totaling function. If this function is requested, EXLST should specify the address of an exit list that includes a totaling entry. T cannot be specified for a SYSIN or SYSOUT data set.
>
> User totaling can be specified for only sequential data sets that are not extended format data sets. If specified for a partitioned data set, a PDSE, an extended format data set, or a UNIX file, user totaling is ignored.
>
> Gerorge S. Says:
>
> T (watch this one) substitute mode.
Ah, but that is specified as OPTCD=T, your post said MF=T and I couldn't
find that.
>
> ===
>
> Thanks so much as always, Steve.
You're welcome.
I meant MACRF=GM vs GT. Stuble says "watch this one" next to the T. This text was probably written in 1969 or so.
Wonderful how a book last updated in 1984 is still valid today. How many MicSoft books and software I've thrown in the trash over the years. How much money.
What I tried to say, was to think a what if I wanted to code my program in 31 or 64 bit mode, but keep the DCB's below the line. From all what I've read, it appears to me, appears only, that I could just STORAGE OBTAIN LOC=BELOW and put the DCB's there. That I think there is a MF=L option to some macros that allow you to move the storage to wherever. That was the magic part. But I got it wrong.
Doc says:
You can assemble the DCB macro into a program that resides above the 16 MB line, but the program must move it below the line before using it. Except for the DCBE, all areas that the DCB refers to, such as EXLST and EODAD, must be below the 16 MB line
(Lindy)
P.S. Happy Birthday Sibelius. He was so young, about 35 or so when he wrote Finlandia.
http://www.youtube.com/watch?v=ci3RPAOFok4
-----Original Message-----
From: IBM Mainframe Assembler List [mailto:ASSEMBL...@LISTSERV.UGA.EDU] On Behalf Of Steve Comstock
Sent: Thursday, December 08, 2011 9:25 PM
To: ASSEMBL...@LISTSERV.UGA.EDU
Subject: Re: ASM Program to copy a file
> From: Lindy Mayfield <Lindy.M...@sas.com>
> ... This text was probably written in 1969 or so.
>
> Wonderful how a book last updated in 1984 is still valid today. How
> many MicSoft books and software I've thrown in the trash over the
> years. How much money.
when you don't get paid maint fee, you have to make your money somehow.
When I worked for Legent, we wondered how a business model of making
software for *nix and M$W would work w/o maint fees - it didn't.
Vision is always a problem when your head is in the wrong place.
-----------------------------------------
The information contained in this communication (including any
attachments hereto) is confidential and is intended solely for the
personal and confidential use of the individual or entity to whom
it is addressed. If the reader of this message is not the intended
recipient or an agent responsible for delivering it to the intended
recipient, you are hereby notified that you have received this
communication in error and that any review, dissemination, copying,
or unauthorized use of this information, or the taking of any
action in reliance on the contents of this information is strictly
prohibited. If you have received this communication in error,
please notify us immediately by e-mail, and delete the original
message. Thank you
During my years as computer lab manager at the college, that particular
issue was the cause of many an S0C4 in assignments. The better students
would catch on immediately, the good students understood when I told
them why, the bad students made the same mistake over and over again.
--
M. Ray Mullins
Roseville, CA, USA
http://www.catherdersoftware.com/
German is essentially a form of assembly language consisting entirely of
far calls heavily accented with throaty guttural sounds. ---ilvi
French is essentially German with messed-up pronunciation and spelling.
--Robert B Wilson
English is essentially French converted to 7-bit ASCII. ---Christophe
Pierret [for Alain LaBont�]
Hey, that's a neat trick. I wish the folks who taught me assembler
back in 1981 had shown me that one. But for some odd reason they were
against using literals in ANY way shape or form. We were taught to
write all items in static storage with a label.
>>> :>And MVC INOUTBUF,=CL(L'INOUTBUF)='Test record' would have worked as
>>> :>well.
> Hey, that's a neat trick. I wish the folks who taught me assembler
> back in 1981 had shown me that one. But for some odd reason they were
> against using literals in ANY way shape or form. We were taught to
> write all items in static storage with a label.
Yes, very neat trick. It helps to avoid redundant constants in the
code.Since I try such things immediately, I guess Martin does not use
it as often as he should (the second "=" should not be there... )
Rob
PS I recently used something like IC R0,=C'0123456789ABCDEF'(R1)
and was pleased to see that it actually works...
I felt bad about posting it...it does waste storage under a
baseregister (which is still in most cases 4K)
Much better is the MACRO-way by Ed.J (and some extra code)
like this:
MVI OUTBUF,C' '
MVC OUTBUF+1(L'OUTBUF),OUTBUF
MVC2 OUTBUF,=C'this is a sample'
Wastes instructions (but we are not into this any more), and space in
"procedure division" - (not covered by a base anyway).
>> ... Martin does not use it as often as he should (the second "=" should not be
there... )
For the quick and dirty I do - but the ones to be shown use either
above technique or use a next available byte point (with appropriate
clearing if required).
Clem
-----Original Message-----
From: IBM Mainframe Assembler List [mailto:ASSEMBL...@LISTSERV.UGA.EDU]
On Behalf Of Martin Truebner
Sent: Friday, December 09, 2011 4:50 AM
To: ASSEMBL...@LISTSERV.UGA.EDU
Subject: Re: ASM Program to copy a file
Hey, you obviously should not use this when the output field is
seriously larger than the string. I would only do this when I
otherwise had padded the string with blanks myself (or maybe still).
When you put an 8-byte string into a 80 byte record, I'm tempted to
see initialization as something separate.
If someone changes the size of the output field a year later, I'd
appreciate an assembler error more than weird problems at runtime.
Rob
>> -1 missing
Could I say "it ways a test"
Yes, as mentioned in this thread.
Why not just code the literal move "MVC OUTBUF,
> =(L'OUTBUF)'this is a sample'" like it's been done for the past 40 years?
That method creates large literals, and wastes addressability.
My usual method is to have an output subroutine, and if called
with the common output line, clear that after printing. Reduces
needed literal size, and makes code generally simpler.
Gerhard Postpischil
Bradford, VT
Your EODAD routine looks like a potential problem. The access method calls
your EODAD inside the get. Here you would normally set a flag to say EOD
occured and return to operating system (BR14), and test this flag after
each GET.
If your routine works, I guess you are 'getting away with it' because you
use BAKR/PR and not save areas. No doubt there could be debate out this,
as if it works, you way is more efficient than testing a flag after every
get. Your way looks very like sas eof= :)
Further suggestions you could try
read the input dataset names, either from parm=, or from a SYSIN type DD,
then dynamically allocate them before opening them.
Have fun
That's BIG news to me, since when is that so?
Andreas F. Geissbuehler
AFG Consultants Inc.
http://www.afgc-inc.com/
I disagree. Why test a flag after every GET? QSAM essentially
does that for you and branches you to EODAD automatically; if
you find yourself in your EODAD routine you know you're ready
for the next phase of your processing, which might be just
shutting down (CLOSE and RETURN), but it might be more complex,
such as taking subtotals, CLOSE-ing one file and OPEN-ing
another, etc.
But to add the overhead of test-and-branch after every GET is
totally unnecessary.
>
> If your routine works, I guess you are 'getting away with it' because you
> use BAKR/PR and not save areas. No doubt there could be debate out this,
> as if it works, you way is more efficient than testing a flag after every
> get. Your way looks very like sas eof= :)
>
> Further suggestions you could try
> read the input dataset names, either from parm=, or from a SYSIN type DD,
> then dynamically allocate them before opening them.
>
> Have fun
>
QSAM GET is but one example of a whole class of similar operations provided by
many IBM and ISV systems services. The notion of an "open," followed by one or
many "gets," followed by a "close" is just how programming works for hundreds of
different resources--from REXX/CLIST variables, to ENQs, to logger, to BCPii,
and more.
The traditional approach is for the return code to be set non-zero (e.g., 4)
when end of data is reached. For example:
DO INF Do for all objects
SOMESERV REQUEST=GET Obtain next object
DOEXIT LTR,R15,R15,NZ Exit if no more objects
. .
process the returned data .
. .
ENDDO , EndDo for all objects
QSAM GET was invented before there were structured disciplines. Having the
system branch to an arbitrary 'EODAD' label outside the GET loop increases the
program's complexity and makes GET's behavior 'arcane' when compared to the
processing methodology used by nearly every other service that has been invented
since.
An approach that sets a flag that can be tested in the loop solves this problem
nicely, making GET's processing more mainstream.
>Original Message From: "Joe Owens"
>>Your EODAD routine looks like a potential problem.
>>The access method calls
>>your EODAD inside the get.
>
>That's BIG news to me, since when is that so?
It isn't so.
<quote from Using Data Sets>
You can treat your EODAD routine as a subroutine (and
end by branching on register 14) or as a continuation
of the routine that issued the CHECK, GET or FEOV macro.
The EODAD routine generally is not regarded as being a
subroutine. After control passes to your EODAD routine,
you can continue normal processing, such as repositioning
and resuming processing of the data set, closing the data
set, or processing another data set.
</quote>
And the contents of register 14:
<quote>
Contains the address after a GET or CHECK as these macros
generate a branch and link to the access method routines.
FEOV is an SVC. Register 14 will contain what is contained
at the time the FEOV was issued.
</quote>
--
Tom Marchant
Right, so I would argue that the GET approach is more 'traditional'
than the 'traditional approach' you describe: it's been around longer.
> Having the
> system branch to an arbitrary 'EODAD' label outside the GET loop increases the
> program's complexity and makes GET's behavior 'arcane' when compared to the
> processing methodology used by nearly every other service that has been invented
> since.
>
You set up a deliberate disonance when you use the word 'arbitrary';
there need be nothing arbitrary about the routine jumped to for an
EODAD occurrence: it should be well planned and naturally take the
control flow to the next part of the logic.
> An approach that sets a flag that can be tested in the loop solves this problem
> nicely, making GET's processing more mainstream.
Well, I don't see it as a 'problem', I wouldn't characterize the
flag approach as 'nicely', and I disagree with your characterization
of GET processing as non-mainstream.
Other than that ...
Actually, the EODAD (and other DCB exit routines) might be more
closely compared to exception routines in languages such as
Java: event-driven routines that get control specifically when
some event occurs. Event handlers, if you will. Which is more
'modern'? Which is 'better'? As you know, the answer is always
'it depends'.
>
> --
> Edward E Jaffe
> Phoenix Software International, Inc
> 831 Parkview Drive North
> El Segundo, CA 90245
> 310-338-0400 x318
> edj...@phoenixsoftware.com
> http://www.phoenixsoftware.com/
>
I should have said 'typical'. The flaws introduced by older 1960s-era designs
have been corrected in modern implementations. It's practically impossible to
find a modern-era service that handles a simple 'end-of-data' condition using an
out-of-line branch, and with good reason.
>
> You set up a deliberate disonance when you use the word 'arbitrary';
> there need be nothing arbitrary about the routine jumped to for an
> EODAD occurrence: it should be well planned and naturally take the
> control flow to the next part of the logic.
When DCBEODAD was designed, stacks were not used. In modern code, an out-of-line
branch risks a situation where one or more stack frames do not get unwound. This
is exactly the sort of thing that would be flagged by tools that look for
problematic programming that violates good architectural and coding practices,
such as those from 'Cast Software' that are getting so much press lately--having
found Java to be the most problematic language and COBOL the least in a study
involving 745 applications from 160 companies in nearly a dozen industries which
totaled 365 million lines of code.
http://www.computerworlduk.com/news/applications/3323819/java-apps-have-most-flaws-cobol-apps-least-study-finds/
>
> Actually, the EODAD (and other DCB exit routines) might be more
> closely compared to exception routines in languages such as
> Java: event-driven routines that get control specifically when
> some event occurs. Event handlers, if you will. Which is more
> 'modern'? Which is 'better'? As you know, the answer is always
> 'it depends'.
Such 'event handlers' are usually designed to deal with the stack frame issue I
mentioned above, just as ESTAE is aware of the System z hardware linkage stack.
DCBEODAD does no such thing.
Well, the kind of code you write is designed to interface
deeply with the system (for example, you have mentioned
that your company's main product is designed to be eligible
for zIIP (or is it zAAP) execution).
For application programming (granted: there are precious few
applications written in Assembler these days, except by
software product developers), I actually disdain using the
linkage stack, for these reasons:
1. BAKR / PR are included in Chapter 10 of the POO: Control
Instructions, not Chapter 7, General Instructions; they
are semiprivileged instructions
I realize many application programmers use this convention
because it's easy, but I think the easy way is not always
the best way, depending on circumstances
2. Performance can be very slow (granted, if you only do BAKR
on entry, it's not a big deal; but calling lots of subroutines
that all use BAKR can hurt performance)
3. Save area chains may not be available or meaningful for
debugging situations (note Robert Ngan's recent post on
this very list)
4. It is possible to get a stack full exception, which few
application programmers want to deal with (again, see
Robert Ngan's recent post)
>
>
>>
>> Actually, the EODAD (and other DCB exit routines) might be more
>> closely compared to exception routines in languages such as
>> Java: event-driven routines that get control specifically when
>> some event occurs. Event handlers, if you will. Which is more
>> 'modern'? Which is 'better'? As you know, the answer is always
>> 'it depends'.
>
> Such 'event handlers' are usually designed to deal with the stack frame issue I
> mentioned above, just as ESTAE is aware of the System z hardware linkage stack.
> DCBEODAD does no such thing.
Stack frame issues are not really relevant if you don't
use the linkage stack; users of classic linkages simply
don't have that problem.
And I would disagree with your assertion that such event handlers
'are usually designed to deal with the stack frame issue'. Typically
event handlers deal with exceptions such as end of file, file not
found, data format exception, and so on. See:
http://www.trainersfriend.com/General_content/Book_site.htm
the third paper, "Introduction to Java in z/OS", pages 428-445
for an exhaustive list of Java exceptions
So while I agree with your assertions for code that must interface
with some z/OS internals, I don't think the 'typical' Assembler
application program is harmed by not using the linkage stack and
by using any of the various DCB exits as I suggested earlier.
>
> --
> Edward E Jaffe
> Phoenix Software International, Inc
> 831 Parkview Drive North
> El Segundo, CA 90245
> 310-338-0400 x318
> edj...@phoenixsoftware.com
> http://www.phoenixsoftware.com/
>
If you're using unlike concatenation, a test after each GET is
mandatory to avoid processing a garbage record. Adding a flag
for EOD would change the overhead from a two to a three way
branch, and wouldn't be noticeable. But then I'm amazed by how
few programmers make life easier for the users by supporting
unlike concatenation.
Gerhard Postpischil
Bradford, VT
Actually, I wasn't talking about the linkage stack at all. I was referring to
software-only stacking.
In the early days, people rarely coded hierarchically. Everything was a flat
programming model, one routine following another with (one or more) branches to
the label of the next routine. These days, people understand the value of nested
logic. A software register stack is practically a necessity for such coding.
I have made a simple stacking macro available publicly to help those who might
be challenged to 'roll' their own. More sophisticated stack services (such as
the one we use internally) handle so-called 'automatic' variables as well.
Ah, my mis-understanding.
>
> In the early days, people rarely coded hierarchically. Everything was a flat
> programming model, one routine following another with (one or more) branches to
> the label of the next routine. These days, people understand the value of nested
> logic. A software register stack is practically a necessity for such coding.
Totally agree with all of the above.
>
> I have made a simple stacking macro available publicly to help those who might
> be challenged to 'roll' their own. More sophisticated stack services (such as
> the one we use internally) handle so-called 'automatic' variables as well.
Excellent. One can also use the CEEENTRY macro to
handle automatic variables (although it does have
some shortcomings, such as using non-relative branching
instructions).
>
> --
> Edward E Jaffe
> Phoenix Software International, Inc
> 831 Parkview Drive North
> El Segundo, CA 90245
> 310-338-0400 x318
> edj...@phoenixsoftware.com
> http://www.phoenixsoftware.com/
>
To solve this problem, I ended up with a GET routine for every QSAM dataset,
where the EODAD address is part of the routine. The GET routine looked like
this (from memory, I don't have the sources at hand):
GET1 PSTART (R10,R14) start macro for local procedure
GET DATASET1 get record from dataset
XR R15,R15 set eof rc to zero
LR R5,R1 move record address to reg 5
LEAVE , success, leave proc (comma VERY important!!)
EOF1 DS 0H = EODAD address of DATASET1
LA R15,8 end of file, set eof rc to 8
GET1Z PSTOP (R10,R14) end macro for local procedure
so the EODAD branch is hidden in the GET-ROUTINE.
In our shop, we tell the developer to write ASSEMBLER modules without B
or J instructions. All control flow is done using SP macros, which have
been
developed or at least improved inhouse in the past 35 years (I don't
know the
beginning of the history, because I'm with this company since 1988 "only").
Kind regards
Bernd
>BAKR / PR are included in Chapter 10 of the POO: Control
>Instructions, not Chapter 7, General Instructions; they
>are semiprivileged instructions
I do not believe that that reason has merit.
>but I think the easy way is not always
>the best way, depending on circumstances
No argument there.
>Save area chains may not be available or meaningful for
>debugging situations
Available? Yes. Meaningful? Yes, but not as easily. And they only tell
part of the
story, with the other part being on the linkage stack.
Peter Relson
z/OS Core Technology Design
Hmmm. Are you advocating use of semiprivileged instructions
in application code then? Or only some of them? Which ones
are 'safe' or 'OK' to use in standard application programs?
Where does one draw the line?
>
>> but I think the easy way is not always
>> the best way, depending on circumstances
>
> No argument there.
>
>> Save area chains may not be available or meaningful for
>> debugging situations
>
> Available? Yes. Meaningful? Yes, but not as easily. And they only tell
> part of the
> story, with the other part being on the linkage stack.
>
> Peter Relson
> z/OS Core Technology Design
>
Note: I just went and reviewed my course
"z/OS Assembler Programming Part 4: z/Architecture and z/OS"
and I see I included MVCOS, which also comes from Chapter 10.
It looks to me, from the Pops, that if I am in problem
state and the source and target addresses are valid for
me, and the third operand has an integer between 0 and 4095
and I zero out R0, then I have a variable length move that
will work. No need for EX for variable length moves of length
under 4K. Is that a fair assessment?
We have done similar things. Typically the caller places the DCB address in R1
and does a JAS[L] to the 'GetNextRec' subroutine. It expects back R1 (record
pointer for MACRF=L) and R15 (return code: 0=OK, 4=EOF). In addition to setting
return codes, the subroutine ensures R1 contains an invalid address in the EOF case.
| L R1,InputDCB1 Point to input DCB 1
| JAS R14,GetNextRec Get next record
| DOEXIT LTR,R15,R15,NZ Exit if nothing left
| .
| .
|GetNextRec DC 0H
| STKPUSH (R14) Save link register
| DO , Do for GET
| GET (1) Get next record
| XR R15,R15 Set retcode = 0
| LEAVE , Exit
|GetNextEof DC 0H <--- EOF branches here
| L R1,=A(X'7FFFF000) Set invalid address
| LHI R15,4 Set retcode = 4 (EOF)
| ENDDO , EndDo for GET
| STKPOP (R14) Restore link register
| BR R14 Return
I didn't mention this technique because I knew Steve would not approve. If he
thinks one TM/BNZ is too much overhead, imagine how he feels about adding a
JAS[L]/STKPUSH/STKPOP for every GET! :D
>
> In our shop, we tell the developer to write ASSEMBLER modules without B
> or J instructions. All control flow is done using SP macros, which have
> been developed or at least improved inhouse in the past 35 years (I don't
> know the beginning of the history, because I'm with this company since 1988
> "only").
A very sensible development strategy. It sounds you you guys were (and still
are) way ahead of your time. Thanks for sharing...
Once your minimum supported operating system enables use of a particular
semi-privileged instruction, then you can use it just the same as you would any
new macro-based system service provided by that same level of the OS.
If you write code for multiple operating systems, you need to take extra care.
For example, very old z/VSE systems (pre-VSE/ESA 2.5?) used to not enable
'extraction-authority control' so often-used instructions like IPK would not
work in problem state. Thankfully, that is ancient history now. I haven't seen a
similar mismatch between z/OS and z/VSE in quite a while. Nevertheless, if your
code might run under multiple operating systems, this is a consideration.
Well said
(with the restrictions Ed pointed out) I see no reason not to
use SPKA to go in and out of user key in CICS
or
use the linkage stack (where appropriate).
It would be nice if there
would be a way to temporary suspend (make it impossible to use) the
linkage stack... Could have avoided lots of headache.....
Steve- what about SAC (q) - should its used be banned as well?
But the last time I tried it MVCOS was (much) slower than an EXecuted MVC. Don't remember how it compared to a MVCL(E). But it xould help out if you might need to move more than 256 bytes but not more than 4096 bytes.
Fred!
Sent from my iPad
-----------------------------------------------------------------
ATTENTION:
The information in this electronic mail message is private and
confidential, and only intended for the addressee. Should you
receive this message by mistake, you are hereby notified that
any disclosure, reproduction, distribution or use of this
message is strictly prohibited. Please inform the sender by
reply transmission and delete the message without copying or
opening it.
Messages and attachments are scanned for all viruses known.
If this message contains password-protected attachments, the
files have NOT been scanned for viruses by the ING mail domain.
Always scan attachments before opening them.
-----------------------------------------------------------------
Well, remember my focus is always on applications, not system or
system-enhancing or -extending code such as exits. Do you think
applications have a need for using SAC?
I don't like to 'ban' instructions, just to be aware of instructions
that may have restrictions. Clearly, applications code has no
business using privileged instructions; semiprivileged instructions
are a little ambiguous in that context.
I once taught in a shop where the top manager banned BXLE - he thought
it was too hard to understand! (Which, of course, said a lot about the
manager.)
>
> --
> Martin
>
> Pi_cap_CPU - all you ever need around MWLC/SCRT/CMT in z/VSE
> more at http://www.picapcpu.de
>
Wow! I didn't know I wielded such power. :-)
> If he
> thinks one TM/BNZ is too much overhead, imagine how he feels about adding a
> JAS[L]/STKPUSH/STKPOP for every GET! :D
Of course, 'it depends' on the application and on installation
standards.
>
>>
>> In our shop, we tell the developer to write ASSEMBLER modules without B
>> or J instructions. All control flow is done using SP macros, which have
>> been developed or at least improved inhouse in the past 35 years (I don't
>> know the beginning of the history, because I'm with this company since 1988
>> "only").
>
> A very sensible development strategy. It sounds you you guys were (and still
> are) way ahead of your time. Thanks for sharing...
>
> --
> Edward E Jaffe
> Phoenix Software International, Inc
> 831 Parkview Drive North
> El Segundo, CA 90245
> 310-338-0400 x318
> edj...@phoenixsoftware.com
> http://www.phoenixsoftware.com/
>
You da Man! :-D
>> Do you think applications have a need for using SAC?
You could have asked when 64 bit was not available. The answer then:
YES of course. Today: maybe, if the data is still in a dataspace
>> ... a shop where the top manager banned BXLE - he thought
it was too hard to understand!)
Today you can resort to JXLE (or JXLG or BXLEG) ;-)
They sure do if they use data spaces. (Even ignoring the fact that
"applications" does not equate to "unauthorized")
As to where to "draw the line", draw it where it makes sense. If the
operating system lets an unauthorized program do something, then why
restrict that unauthorized program further unless necessary?
>A USER SVC is supposed to have the ability to issue
>any ABEND where the YY is it's ID and X is 0-E (FXX being reserved
>for the SVC YY not defined ABEND)?
I don't think this has ever been true for "X = 0". (I don't have any
comment on how the xFB and xFC completion codes got in there, although I
wouldn't be surprised if some of the xFC ones pre-dated user SVCs)
Ah, that references something that Ed Jaffe alluded to also. For
some reason I had thought that 'semi-privileged' was mostly the
same as 'privileged': some mechanism has to be set up to allow
non-authorized programs to use such instructions. And this
setting up was done by the control program. And I further
thought (and this was my reach too far, apparently) that z/OS
was very stingy in what it allowed for applications programs.
Goaded a bit by your post, I went back to the Pops and re-read the
Program Execution chapter (Chapter 5).
So now I see I should do some more research. But where is it
documented which semi-privileged instructions are available
to problem state programs under z/OS (that is, to echo back
your phrase, how would I know which semi-priviliged instructions
'the operating system lets an unauthorized program do' if the
operating system is z/OS)?
>
>> A USER SVC is supposed to have the ability to issue
>> any ABEND where the YY is it's ID and X is 0-E (FXX being reserved
>> for the SVC YY not defined ABEND)?
>
> I don't think this has ever been true for "X = 0". (I don't have any
> comment on how the xFB and xFC completion codes got in there, although I
> wouldn't be surprised if some of the xFC ones pre-dated user SVCs)
>
> Peter Relson
> z/OS Core Technology Design
>
Thanks in advance
Lindy
http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/Shelves/asmsh030
this is the right shelf (at least I use the same)
>> I wanted to look up info on DSECT (I wanted to know how to do a
>> redefines), but I don't seem to find any good info on it.
You want this:
MARTIN DSECT
FIELD1 DS CL10
FIELD2 DS CL10
ORG MARTIN
FIELDB DS C
FIELDC DS C
or this
MARTIN DSECT
FIELD1 DS CL10
FIELD2 DS CL10
LINDY DSECT
FIELDB DS C
FIELDC DS C
there is not much "redefines" to it- The second one needs an extra
using.
And I expected the programmer's guide to be different. Like the DSORG with explanations, examples, etc.
>> And I expected the programmer's guide to be different.
Just come here- We are willing to help
>I wanted to look up info on DSECT (I wanted to know how to
>do a redefines), but I don't seem to find any good info on it.
ORG
--
Tom Marchant
Check out the ORG statement.
2011/12/12 Martin Truebner <Mar...@pi-sysprog.de>