On 12/17/2014 8:16, Peter Relson wrote:
yea- but why would you do that?
If you are without a base, it is likely code- right?
I'd say "not right". The reason we would usually do this is because we are
trying truly to have no base at all except when needed (because with the
advent of all the immediate instructions you have far fewer cases where
you need to access data in static storage when you're not invoking
macros).
Then it comes down to whether the instruction you need to access the data
has an index reg.
So consider
LARL RegX,MyData
L RegY,MyWord(RegX,0)
MVC MyTarget(L'MyString),MyString(RegX)
MyData DS 0D
MyWord DC F'3'
MyString DC CL16'...'
In AR-mode, you would need to set the AR of RegX for the MVC but not for
the L, since the L uses RegX in the index reg position.
Everyone familiar with AR-mode coding or with reading AR-mode code should
well understand the extremely valuable technique of utilizing the "index
reg" notation
I don't consider this technique to have much value at all. I would
prefer that AR-mode code set the base and AR correctly, and not just
exploit an index register.
In any case, you can't override the base reg on a relocatable reference,
so your example code is technically incorrect, and could be confusing.
This would be more correct:
LARL RegX,MyData
L RegY,MyWord-MyData(RegX)
MVC MyTarget(L'MyString),MyString-MyData(RegX)
I get that this is just an example... but the real-world cases where you
really need to bypass an AR are actually very rare. This would not cost
much more:
LAE Regx,0
LARL RegX,MyData
USING MyData,Regx
L RegY,MyWord
MVC MyTarget(L'MyString),MyString
sas
But beware that some MVS services (notably WTO) use some subset of ARs
0-1 and 14-15 as work registers, and return them containing non-zero
values. It's documented, but it changed some time back, and caused
trouble for code that inadvertently relied on their not being changed.
a CPOOL callable service started returning some junk in AR1.
The linkage conventions are clear; the documentation for the services is
clear. Do not rely on things that the documentation says are not
preserved. And unless some specific service documents otherwise, assuming
that the low half of reg 0, 1, 14, 15 or the high half of reg 0, 1, 15 or
access register 0, 1, 15 is preserved across any system service is simply
wrong. When it is convenient or necessary services will use the registers
that are available to them (whether that be the low half of registers, the
high half of registers or access registers). FWIW, "junk" to you might be
valuable data to someone else (or might truly be "junk" for everyone other
than the service itself).
Yes, of course. I intended to make that point, if not clearly enough.
The code that had the bug wasn't mine, and I did mean "junk" only from
the perspective of the calling routine.
But maybe the CALL macro should be changed to use LAE.
The fact that this statement is made implies to me that you are not in the
habit of telling macros via SYSSTATE what your ASC environment is.
In many cases you can expect incorrect code if you do not properly tell.
I'll leave to the readers to compare the expansions of
CALL (15),(A,B,C)
SYSSTATE ASCENV=AR
CALL (15),(A,B,C)
That implication is not correct. It's just that CALL expands a parmlist
to append an ALET list when SYSSTATE ASCENV = AR, and this, so far, is
never what I want. Some IBM macros do use LAE regardless, and I think
it would be safe for CALL.
As an aside, LAE didn't even exist when the first version of
cross-memory access came out (primary/secondary only), to the best of my
recollection.
More completely, access registers did not exist at that time.
My point on this statement is admittedly hard to divine... Which is, why
should LAE have support for secondary and home-space mode? Is there
code that takes advantage of an LAE in say, secondary ASC mode, and
subsequently uses that address/AR in AR-mode?
Peter Relson
z/OS Core Technology Design