ASM Program to copy a file

609 views
Skip to first unread message

Lindy Mayfield

unread,
Dec 8, 2011, 9:14:13 AM12/8/11
to ASSEMBL...@listserv.uga.edu
There was a kinda-sorta challenge for me to write the most basic assembler program to copy a file. Since I am no assembler programmer by any means, it of course took me some time to get it done. Also I had no clue where to start. I'd say all total about 5 or 6 hours to get it finished. This included reading docs, books, etc., coding and debugging. And false starts.

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.

Martin Truebner

unread,
Dec 8, 2011, 11:14:38 AM12/8/11
to ASSEMBL...@listserv.uga.edu
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).


>> 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

Lindy Mayfield

unread,
Dec 8, 2011, 11:34:12 AM12/8/11
to ASSEMBL...@listserv.uga.edu
Thank you. Very much.

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

Martin Truebner

unread,
Dec 8, 2011, 11:54:06 AM12/8/11
to ASSEMBL...@listserv.uga.edu
Lindy,

>> 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)

Vintage Coder

unread,
Dec 8, 2011, 12:05:56 PM12/8/11
to ASSEMBL...@listserv.uga.edu
He has RENT specified in the linkedit parms but his program is not reentrant.

------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

Edward Jaffe

unread,
Dec 8, 2011, 12:19:09 PM12/8/11
to ASSEMBL...@listserv.uga.edu
On 12/8/2011 8:14 AM, Martin Truebner wrote:
> Much better solution is what (ITIR) Ed J. uses ... a MACRO called MVCSL (or
> so) which means MVC in sender length.

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/

Steve Comstock

unread,
Dec 8, 2011, 12:20:56 PM12/8/11
to ASSEMBL...@listserv.uga.edu
On 12/8/2011 9:34 AM, Lindy Mayfield wrote:
> Thank you. Very much.
>
> 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
>

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

Binyamin Dissen

unread,
Dec 8, 2011, 12:43:12 PM12/8/11
to ASSEMBL...@listserv.uga.edu
On Thu, 8 Dec 2011 17:14:38 +0100 Martin Truebner <Mar...@pi-sysprog.de>
wrote:

:>>> 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.

Steve Comstock

unread,
Dec 8, 2011, 12:57:02 PM12/8/11
to ASSEMBL...@listserv.uga.edu
On 12/8/2011 7:14 AM, Lindy Mayfield wrote:
> There was a kinda-sorta challenge for me to write the most basic
> assembler program to copy a file. Since I am no assembler programmer
> by any means, it of course took me some time to get it done. Also I
> had no clue where to start. I'd say all total about 5 or 6 hours to
> get it finished. This included reading docs, books, etc., coding and
> debugging. And false starts.
>
> 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

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.

Lindy Mayfield

unread,
Dec 8, 2011, 1:01:48 PM12/8/11
to ASSEMBL...@listserv.uga.edu
Perhaps this is common, I don't know, but I usually start with something that works, then, as I progress and learn I take out the meaningless stuff.

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

Edward Jaffe

unread,
Dec 8, 2011, 1:32:37 PM12/8/11
to ASSEMBL...@listserv.uga.edu
On 12/8/2011 9:57 AM, Steve Comstock wrote:
>
>> 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?

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.

Mike Shaw

unread,
Dec 8, 2011, 1:34:57 PM12/8/11
to ASSEMBL...@listserv.uga.edu
On Thu, Dec 8, 2011 at 12:57 PM, Steve Comstock <st...@trainersfriend.com>wrote:

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

Lindy Mayfield

unread,
Dec 8, 2011, 1:39:01 PM12/8/11
to ASSEMBL...@listserv.uga.edu
I tried to take out the extraneous stuff from the DCB. I got this:

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

Steve Smith

unread,
Dec 8, 2011, 2:12:22 PM12/8/11
to ASSEMBL...@listserv.uga.edu
On 12/8/2011 12:57, Steve Comstock wrote:
> On 12/8/2011 7:14 AM, Lindy Mayfield wrote:
>> There was a kinda-sorta challenge for me to write the most basic
>> assembler program to copy a file. Since I am no assembler programmer
>> by any means, it of course took me some time to get it done. Also I
>> had no clue where to start. I'd say all total about 5 or 6 hours to
>> get it finished. This included reading docs, books, etc., coding and
>> debugging. And false starts.
>>
>> 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
>
> Omit the START statement; the CSECT statement does
> the same thing.
I'd omit the CSECT statement, because the START statement is the one in
the right place.

>
>> 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
Also, MACRF=GL, where you get the address of your record from R1 is
considerably more efficient. Another thing is that if you use MACRF=GM,
you'd better make sure the input LRECL is what you think it is, or more
S0C4s are coming.

>
>
>> 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
Best to set BLKSIZE=0 for a QSAM dataset. That lets the system
determine the best block size.

Steve Comstock

unread,
Dec 8, 2011, 2:24:35 PM12/8/11
to ASSEMBL...@listserv.uga.edu
On 12/8/2011 11:39 AM, Lindy Mayfield wrote:
> I tried to take out the extraneous stuff from the DCB. I got this:
>
> 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.
>
[snip - to get posting under 250 lines]
>

> ===
>
> 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.

Lindy Mayfield

unread,
Dec 8, 2011, 2:49:14 PM12/8/11
to ASSEMBL...@listserv.uga.edu
Normal, for me, when I am learning new stuff to get things a bit mixed up.

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

Kirk Talman

unread,
Dec 8, 2011, 3:06:53 PM12/8/11
to ASSEMBL...@listserv.uga.edu
IBM Mainframe Assembler List <ASSEMBL...@LISTSERV.UGA.EDU> wrote on
12/08/2011 02:49:14 PM:

> 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

Ray Mullins

unread,
Dec 8, 2011, 8:22:39 PM12/8/11
to ASSEMBL...@listserv.uga.edu
On 2011-12-08 09:43, Binyamin Dissen wrote:
> On Thu, 8 Dec 2011 17:14:38 +0100 Martin Truebner<Mar...@pi-sysprog.de>
> wrote:
>
> :>>> 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.

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�]

Dougie Lawson

unread,
Dec 9, 2011, 3:44:21 AM12/9/11
to ASSEMBL...@listserv.uga.edu
On 9 December 2011 01:22, Ray Mullins <m...@lerctr.org> wrote:
> On 2011-12-08 09:43, Binyamin Dissen wrote:
>>
>> On Thu, 8 Dec 2011 17:14:38 +0100 Martin Truebner<Mar...@pi-sysprog.de>
>> wrote:
>>
>> :>>> 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.
>
>
> 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.
>

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.

--
http://twitter.com/DougieLawson

Rob van der Heij

unread,
Dec 9, 2011, 3:58:10 AM12/9/11
to ASSEMBL...@listserv.uga.edu
On Fri, Dec 9, 2011 at 9:44 AM, Dougie Lawson <dl1...@gmail.com> wrote:

>>> :>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...

Martin Truebner

unread,
Dec 9, 2011, 5:50:14 AM12/9/11
to ASSEMBL...@listserv.uga.edu
Rob,

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).

Clement Clarke

unread,
Dec 9, 2011, 6:35:10 AM12/9/11
to ASSEMBL...@listserv.uga.edu
Don't forget
CLC =C'this is a test',OUTBUF
too.

Clem

Dan Skomsky, PSTI

unread,
Dec 9, 2011, 6:40:53 AM12/9/11
to ASSEMBL...@listserv.uga.edu
Oops. Don't you mean "MVC OUTBUF+1(L'OUTBUFF-1),OUTBUF"? I'm sure you
don't want to zap the byte immediately after OUTBUF. What is "MVC2",
another MACRO? 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?
Why is there no LTORG statement in the sample? For good practice one should
always be there. Once another CSECT is added to the program, the coder is
in for a surprise.

-----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

Rob van der Heij

unread,
Dec 9, 2011, 7:03:18 AM12/9/11
to ASSEMBL...@listserv.uga.edu
On Fri, Dec 9, 2011 at 11:50 AM, Martin Truebner <Mar...@pi-sysprog.de> wrote:
> Rob,
>
> I felt bad about posting it...it does waste storage under a
> baseregister (which is still in most cases 4K)

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

Martin Truebner

unread,
Dec 9, 2011, 7:04:10 AM12/9/11
to ASSEMBL...@listserv.uga.edu
Dan

>> -1 missing

Could I say "it ways a test"

Martin Truebner

unread,
Dec 9, 2011, 7:23:18 AM12/9/11
to ASSEMBL...@listserv.uga.edu
Where does that "Y" come from?

Gerhard Postpischil

unread,
Dec 9, 2011, 8:23:26 AM12/9/11
to ASSEMBL...@listserv.uga.edu
On 12/9/2011 6:40 AM, Dan Skomsky, PSTI wrote:
> Oops. Don't you mean "MVC OUTBUF+1(L'OUTBUFF-1),OUTBUF"? I'm sure you
> don't want to zap the byte immediately after OUTBUF. What is "MVC2",
> another MACRO?

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

Joe Owens

unread,
Dec 9, 2011, 10:20:16 AM12/9/11
to ASSEMBL...@listserv.uga.edu
This is a great thread. It is great to see someone enthusiastic about
learning assembler.

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

Andreas Geissbuehler

unread,
Dec 9, 2011, 10:51:53 AM12/9/11
to ASSEMBL...@listserv.uga.edu
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?

Andreas F. Geissbuehler
AFG Consultants Inc.
http://www.afgc-inc.com/

Steve Comstock

unread,
Dec 9, 2011, 10:53:49 AM12/9/11
to ASSEMBL...@listserv.uga.edu
On 12/9/2011 8:20 AM, Joe Owens wrote:
> This is a great thread. It is great to see someone enthusiastic about
> learning assembler.
>
> 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.

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
>

Edward Jaffe

unread,
Dec 9, 2011, 11:42:59 AM12/9/11
to ASSEMBL...@listserv.uga.edu
On 12/9/2011 7:53 AM, Steve Comstock wrote:
> 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.

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.

Tom Marchant

unread,
Dec 9, 2011, 11:56:47 AM12/9/11
to ASSEMBL...@listserv.uga.edu
On Fri, 9 Dec 2011 10:51:53 -0500, <afg...@videotron.ca> wrote:

>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

Steve Comstock

unread,
Dec 9, 2011, 12:07:23 PM12/9/11
to ASSEMBL...@listserv.uga.edu

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/
>

Edward Jaffe

unread,
Dec 9, 2011, 1:10:26 PM12/9/11
to ASSEMBL...@listserv.uga.edu
On 12/9/2011 9:07 AM, Steve Comstock wrote:
>
> Right, so I would argue that the GET approach is more 'traditional'
> than the 'traditional approach' you describe: it's been around longer.

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.

Steve Comstock

unread,
Dec 9, 2011, 2:33:19 PM12/9/11
to ASSEMBL...@listserv.uga.edu
On 12/9/2011 11:10 AM, Edward Jaffe wrote:
> On 12/9/2011 9:07 AM, Steve Comstock wrote:
>>
>> Right, so I would argue that the GET approach is more 'traditional'
>> than the 'traditional approach' you describe: it's been around longer.
>
> 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/
>

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/
>

Gerhard Postpischil

unread,
Dec 9, 2011, 3:06:37 PM12/9/11
to ASSEMBL...@listserv.uga.edu
On 12/9/2011 10:53 AM, Steve Comstock wrote:
> 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 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

Edward Jaffe

unread,
Dec 9, 2011, 4:13:15 PM12/9/11
to ASSEMBL...@listserv.uga.edu
On 12/9/2011 11:33 AM, Steve Comstock wrote:
>
> 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:

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.

Steve Comstock

unread,
Dec 9, 2011, 4:56:18 PM12/9/11
to ASSEMBL...@listserv.uga.edu
On 12/9/2011 2:13 PM, Edward Jaffe wrote:
> On 12/9/2011 11:33 AM, Steve Comstock wrote:
>>
>> 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:
>
> Actually, I wasn't talking about the linkage stack at all. I was referring to
> software-only stacking.

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/
>

Bernd Oppolzer

unread,
Dec 10, 2011, 7:08:58 AM12/10/11
to ASSEMBL...@listserv.uga.edu
Some day I designed a large ASSEMBLER program which needed to
read some QSAM files, and I soon discovered that the out-of-line branches
imposed by the EODAD processing violated the clean structure of the program,
because the input logic of the many files which were read in parallel
was somehow
complicated. If, for example, you deal with VSAM instead of QSAM, you
have very
natural return code handling after each GET macro call, which allows
structured
programming, using SP (structured programming) macros, for example.

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

Bowers, Greg

unread,
Dec 10, 2011, 7:14:22 AM12/10/11
to ASSEMBL...@listserv.uga.edu
Team, I'm currently out of the office. I will return on Monday Dec 19, 2011. If you need immediate assistance while I’m gone, please contact my manager (Peter Moir). Otherwise, send me an email message and I will respond when I return. Thank you, Greg Bowers

Peter Relson

unread,
Dec 10, 2011, 9:12:55 AM12/10/11
to ASSEMBL...@listserv.uga.edu
>I actually disdain using the
>linkage stack, for these reasons:

>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

Steve Comstock

unread,
Dec 10, 2011, 9:22:50 AM12/10/11
to ASSEMBL...@listserv.uga.edu
On 12/10/2011 7:12 AM, Peter Relson wrote:
>> I actually disdain using the
>> linkage stack, for these reasons:
>
>> 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.

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
>

Steve Comstock

unread,
Dec 10, 2011, 10:29:35 AM12/10/11
to ASSEMBL...@listserv.uga.edu
On 12/10/2011 7:22 AM, Steve Comstock wrote:
> On 12/10/2011 7:12 AM, Peter Relson wrote:
>>> I actually disdain using the
>>> linkage stack, for these reasons:
>>
>>> 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.
>
> 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?
>

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?

Edward Jaffe

unread,
Dec 10, 2011, 10:36:58 AM12/10/11
to ASSEMBL...@listserv.uga.edu
On 12/10/2011 4:08 AM, Bernd Oppolzer wrote:
> 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.

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

Edward Jaffe

unread,
Dec 10, 2011, 10:56:16 AM12/10/11
to ASSEMBL...@listserv.uga.edu
On 12/10/2011 6:22 AM, Steve Comstock wrote:
> 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?

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.

Martin Truebner

unread,
Dec 10, 2011, 11:44:58 AM12/10/11
to ASSEMBL...@listserv.uga.edu
>> 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.

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?

Fred van der Windt

unread,
Dec 10, 2011, 12:13:53 PM12/10/11
to ASSEMBL...@listserv.uga.edu
Yup,

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

Steve Comstock

unread,
Dec 10, 2011, 2:38:00 PM12/10/11
to ASSEMBL...@listserv.uga.edu
On 12/10/2011 9:44 AM, Martin Truebner wrote:
>>> 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.
>
> 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?

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
>

Steve Comstock

unread,
Dec 10, 2011, 2:41:36 PM12/10/11
to ASSEMBL...@listserv.uga.edu

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/
>

Edward Jaffe

unread,
Dec 10, 2011, 3:59:00 PM12/10/11
to ASSEMBL...@listserv.uga.edu
On 12/10/2011 11:41 AM, Steve Comstock wrote:
>
> Wow! I didn't know I wielded such power. :-)

You da Man! :-D

Martin Truebner

unread,
Dec 11, 2011, 4:18:46 AM12/11/11
to ASSEMBL...@listserv.uga.edu
Steve,

>> 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) ;-)

Peter Relson

unread,
Dec 11, 2011, 10:12:38 AM12/11/11
to ASSEMBL...@listserv.uga.edu
>Do you think applications have a need for using SAC?

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)

Steve Comstock

unread,
Dec 11, 2011, 11:39:59 PM12/11/11
to ASSEMBL...@listserv.uga.edu
On 12/11/2011 8:12 AM, Peter Relson wrote:
>> Do you think applications have a need for using SAC?
>
> 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?

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
>

Lindy Mayfield

unread,
Dec 12, 2011, 12:38:25 AM12/12/11
to ASSEMBL...@listserv.uga.edu
Is this the correct documentation for assembler? Language ref and Programmer's guide? Doesn't seem right. 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.

Thanks in advance
Lindy

http://publibz.boulder.ibm.com/cgi-bin/bookmgr_OS390/Shelves/asmsh030

Martin Truebner

unread,
Dec 12, 2011, 3:24:06 AM12/12/11
to ASSEMBL...@listserv.uga.edu
Lindy,

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.

Lindy Mayfield

unread,
Dec 12, 2011, 3:31:43 AM12/12/11
to ASSEMBL...@listserv.uga.edu
ORG, that's what I was looking for. Thanks.

And I expected the programmer's guide to be different. Like the DSORG with explanations, examples, etc.

Martin Truebner

unread,
Dec 12, 2011, 4:36:14 AM12/12/11
to ASSEMBL...@listserv.uga.edu
Lindy

>> And I expected the programmer's guide to be different.

Just come here- We are willing to help

Tom Marchant

unread,
Dec 12, 2011, 9:01:47 AM12/12/11
to ASSEMBL...@listserv.uga.edu
On Mon, 12 Dec 2011 05:38:25 +0000, Lindy Mayfield wrote:

>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

Steve Comstock

unread,
Dec 12, 2011, 9:19:17 AM12/12/11
to ASSEMBL...@listserv.uga.edu

Check out the ORG statement.

carlos roberto visconde

unread,
Dec 14, 2011, 1:43:39 PM12/14/11
to ASSEMBL...@listserv.uga.edu
If the redefine is of different lenght, don't forget to use ORG without
parameter, at the end of redefines.

2011/12/12 Martin Truebner <Mar...@pi-sysprog.de>

Reply all
Reply to author
Forward
0 new messages