Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"Using" statement?

52 views
Skip to first unread message

hanc...@bbs.cpcn.com

unread,
Jul 6, 2012, 9:52:45 AM7/6/12
to
Many assembler programs begin with a USING * statement. Could someone
explain it?

Thanks.

John W Kennedy

unread,
Jul 6, 2012, 11:24:16 AM7/6/12
to
"USING *" is actually obsolete in properly written z/Architecture code
that segregates code from data and uses only branch-relative
instructions, but in older code, you need a base register for your
branch instructions and to refer to data found in the same CSECT as
your code. USING *,r simply means that, until a DROP r instruction or a
contradictory USING --,r instruction, the assembler can assume that
general register r has the address of * in it. In primitive S/360 code,
you might have:

BALR 12,0
USING *,12

The BALR loads the instruction of the next address into GR12, but
(because the second operand is GR0) it doesn't actually branch. More
modern code would use BASR instead.

Under the usual operating systems, a routine is entered by BALR 14,15,
so GR15 will always have the address of the routine loaded in it, so
you can begin with

USING *,15

Of course, you must be careful to have

USING something else
DROP 15

soon after since GR15 will usually quickly be reused.

But, as I say, if you are writing code expressly for z/Architecture,
and use only the Branch Relative family of instructions, and put all
your data in a separate CSECT or DSECT (or PSECT), you do not need a
base register for your code CSECT. That's why the Branch Relative
instructions were invented -- so that you have one more general
register to use for other purposes.

--
John W Kennedy
"The first effect of not believing in God is to believe in anything...."
-- Emile Cammaerts, "The Laughing Prophet"

hanc...@bbs.cpcn.com

unread,
Jul 6, 2012, 1:15:23 PM7/6/12
to
On Jul 6, 11:24 am, John W Kennedy <jwke...@attglobal.net> wrote:

> "USING *" is actually obsolete in properly written z/Architecture code
> that segregates code from data and uses only branch-relative
> instructions, but in older code, you need a base register for your
> branch instructions and to refer to data found in the same CSECT as
> your code. . . .

Thanks!

Fritz Wuehler

unread,
Jul 12, 2012, 1:31:55 AM7/12/12
to
John W Kennedy <jwk...@attglobal.net> wrote:

> On 2012-07-06 13:52:45 +0000, hanc...@bbs.cpcn.com said:
>
> > Many assembler programs begin with a USING * statement. Could someone
> > explain it?
> >
> > Thanks.
>
> "USING *" is actually obsolete in properly written z/Architecture code
> that segregates code from data and uses only branch-relative
> instructions,

USING is not obsolete in any serious code, whether or not it is
properly-written, reentrant, etc. If you are considering "USING *" a special
case then I'll go further than you and say USING * is never required, use a
label.

You need to understand USING to get addressability to system control blocks
and other DSECTs regardless of whether you have the branch relative and
immediate facility. And you need it to understand 99.999% of the code that
already exists that does use USING.

USING associates a user-defined base register to be used by the assembler in
generating references to the area. Check bitsavers.org for the Assembly
language course book and you will get a good explanation of all this. In
fact, without understanding USING you can never read or write IBM assembler
code.

> general register r has the address of * in it. In primitive S/360 code,
> you might have:
>
> BALR 12,0
> USING *,12

You also need to do this in certain other types of programs that have no
standard method of entry.

> Under the usual operating systems, a routine is entered by BALR 14,15,
> so GR15 will always have the address of the routine loaded in it, so
> you can begin with
>
> USING *,15

Not true of SVCs and certain other system extension routines. And you don't
need a USING for *,15 anyway, you should load your chosen base register with
the contents of R15 and then the next issue you mentioned:


> Of course, you must be careful to have
>
> USING something else
> DROP 15
>
> soon after since GR15 will usually quickly be reused.

becomes irrelevant.

> But, as I say, if you are writing code expressly for z/Architecture,
> and use only the Branch Relative family of instructions, and put all
> your data in a separate CSECT or DSECT (or PSECT), you do not need a
> base register for your code CSECT. That's why the Branch Relative
> instructions were invented -- so that you have one more general
> register to use for other purposes.

This is fine advice for "Hello, World!" programs but for any real
programming you will need to understand base addressing and DSECTs and the
assembler USING directive since they are foundations of IBM assembler. And
you will need to understand USING if you are ever going to need to read,
understand and maintain the gigantic body of code written because virtually
none of that code uses the branch relative and immediate facility, not
vendor code and not IBM code. Compilers will use it increasingly, but it is
uncommon to patch compiled code unless you work for one of 3 compiler
vendors targeting z/OS (one of those is IBM). If you want to code in
assembler you need to code like an assembler programmer.


Pete Nelson

unread,
Jul 12, 2012, 11:36:32 AM7/12/12
to
On Friday, July 6, 2012 10:24:16 AM UTC-5, John W Kennedy wrote:

> But, as I say, if you are writing code expressly for z/Architecture,
> and use only the Branch Relative family of instructions, and put all
> your data in a separate CSECT or DSECT (or PSECT), you do not need a
> base register for your code CSECT. That&#39;s why the Branch Relative
> instructions were invented -- so that you have one more general
> register to use for other purposes.
>
Basically true, although whether your literal pool and constants are in a separate CSECT or the same CSECT as your executable code, a base register is still needed to address the data. For small programs, you probably end up using just as many base registers either way; when the size of your executable code approaches/exceeds 4K, then you start avoiding register starvation by using relative branching.

> Under the usual operating systems, a routine is entered by BALR 14,15,
> so GR15 will always have the address of the routine loaded in it, so
> you can begin with
>
> USING *,15
>
> Of course, you must be careful to have
>
> USING something else
> DROP 15
>
> soon after since GR15 will usually quickly be reused.
>

An even better method that is independent of GR15 contents is to use the LARL instruction (Load Address Relative Long) to set your intended base register:

LARL Rn,<data pool start label>
USING <data pool start label>,Rn

which also avoids the need for embedding an adcon to pick up the data pool address. To use the LARL method, you need to ensure that your target label is halfword aligned, and within an internal CSECT being assembled (you can go cross-CSECT, but not external).

John W Kennedy

unread,
Jul 12, 2012, 10:09:34 PM7/12/12
to
The question was about "USING *". I tried to isolate that case.

John W Kennedy

unread,
Jul 12, 2012, 10:13:10 PM7/12/12
to
On 2012-07-12 15:36:32 +0000, Pete Nelson said:

> On Friday, July 6, 2012 10:24:16 AM UTC-5, John W Kennedy wrote:
>> But, as I say, if you are writing code expressly for z/Architecture,>
>> and use only the Branch Relative family of instructions, and put all>
>> your data in a separate CSECT or DSECT (or PSECT), you do not need a>
>> base register for your code CSECT. That&#39;s why the Branch Relative>
>> instructions were invented -- so that you have one more general>
>> register to use for other purposes.
>>
> Basically true, although whether your literal pool and constants are in
> a separate CSECT or the same CSECT as your executable code, a base
> register is still needed to address the data. For small programs, you
> probably end up using just as many base registers either way; when the
> size of your executable code approaches/exceeds 4K, then you start
> avoiding register starvation by using relative branching.

Not if you have the wit to put LTORG in your static-readonly-data CSECT.


>
>> Under the usual operating systems, a routine is entered by BALR 14,15,>
>> so GR15 will always have the address of the routine loaded in it, so>
>> you can begin with
>>
>> USING *,15
>>
>> Of course, you must be careful to have
>>
>> USING something else
>> DROP 15
>>
>> soon after since GR15 will usually quickly be reused.
>>
> An even better method that is independent of GR15 contents is to use
> the LARL instruction (Load Address Relative Long) to set your intended
> base register:
>
> LARL Rn,<data pool start label>
> USING <data pool start label>,Rn
>
> which also avoids the need for embedding an adcon to pick up the data
> pool address. To use the LARL method, you need to ensure that your
> target label is halfword aligned, and within an internal CSECT being
> assembled (you can go cross-CSECT, but not external).


--
John W Kennedy
"The whole modern world has divided itself into Conservatives and
Progressives. The business of Progressives is to go on making mistakes.
The business of the Conservatives is to prevent the mistakes from being
corrected."
-- G. K. Chesterton

Fritz Wuehler

unread,
Jul 13, 2012, 8:12:09 AM7/13/12
to
John W Kennedy <jwk...@attglobal.net> wrote:

Didn't see Pete's post since I killfile everything from google

> On 2012-07-12 15:36:32 +0000, Pete Nelson said:
>
> > On Friday, July 6, 2012 10:24:16 AM UTC-5, John W Kennedy wrote:
> >> But, as I say, if you are writing code expressly for z/Architecture,>
> >> and use only the Branch Relative family of instructions, and put all>
> >> your data in a separate CSECT or DSECT (or PSECT), you do not need a>
> >> base register for your code CSECT. That&#39;s why the Branch Relative>
> >> instructions were invented -- so that you have one more general>
> >> register to use for other purposes.
> >>
> > Basically true, although whether your literal pool and constants are in
> > a separate CSECT or the same CSECT as your executable code, a base
> > register is still needed to address the data. For small programs, you
> > probably end up using just as many base registers either way; when the
> > size of your executable code approaches/exceeds 4K, then you start
> > avoiding register starvation by using relative branching.

It's true many people allocate additional base registers when code exceeds
4K but there is another way around this and I have written and worked on
substantial pieces of code that use one code base register no matter how
large the CSECT. There is really no excuse to use more than one code base
register, and I am saying that in reference to OS/360, not just since the
branch relative and immediate facility came out.

>
> Not if you have the wit to put LTORG in your static-readonly-data CSECT.

It's a good idea to use LTORG to organize code and read-only data to
preserve locality of reference. In fact if you don't use it correctly you
often run into base addressing problems as parm lists for macros go out of
range.


John W Kennedy

unread,
Jul 13, 2012, 1:57:58 PM7/13/12
to
On 2012-07-13 12:12:09 +0000, Fritz Wuehler said:

> John W Kennedy <jwk...@attglobal.net> wrote:
>
> Didn't see Pete's post since I killfile everything from google
>
>> On 2012-07-12 15:36:32 +0000, Pete Nelson said:
>>
>>> On Friday, July 6, 2012 10:24:16 AM UTC-5, John W Kennedy wrote:
>>>> But, as I say, if you are writing code expressly for z/Architecture,>
>>>> and use only the Branch Relative family of instructions, and put all>
>>>> your data in a separate CSECT or DSECT (or PSECT), you do not need a>
>>>> base register for your code CSECT. That&#39;s why the Branch Relative>
>>>> instructions were invented -- so that you have one more general>
>>>> register to use for other purposes.
>>>>
>>> Basically true, although whether your literal pool and constants are in
>>> a separate CSECT or the same CSECT as your executable code, a base
>>> register is still needed to address the data. For small programs, you
>>> probably end up using just as many base registers either way; when the
>>> size of your executable code approaches/exceeds 4K, then you start
>>> avoiding register starvation by using relative branching.
>
> It's true many people allocate additional base registers when code exceeds
> 4K but there is another way around this and I have written and worked on
> substantial pieces of code that use one code base register no matter how
> large the CSECT. There is really no excuse to use more than one code base
> register, and I am saying that in reference to OS/360, not just since the
> branch relative and immediate facility came out.

Back in the OS/360 days, frankly, I always regarded more than one code
base register (for which I generally used GR12 unless in a PL/I
environment, in which case I used GR11) as a sure sign that the module
had grown too big, and needed to be refactored.

--
John W Kennedy
Read the remains of Shakespeare's lost play, now annotated!
http://www.SKenSoftware.com/Double%20Falshood

Anonymous

unread,
Jul 15, 2012, 5:54:26 AM7/15/12
to
Agreed.






























JEmebius

unread,
Jul 30, 2012, 5:09:21 PM7/30/12
to Anonymous
When I knew in advance that my OS/360 module would occupy more than 8 Kbytes (4096 bytes) and
certainly less than 12 Kbytes I would define registers GR12, GR11 and GR10 as base registers for the
first 4K, the second 4K and the last 4K, and load them in advance with the appropriate values:
<GR15>, <GR15> + 4096, <GR15> + 8192.

The most straightforward coding for this reads [use fixed-space font]

ABCDEFGH CSECT
USING 12,11,10
LR 12,15
LR 11,15
AH 11,=H'4096'
LR 10,15
AH 10,=H'8192'
.................
LTORG
DC H'4096' (I am not sure if this the correct printing in the output listing)
DC H'8192'

(Takes 18 bytes)

Programmers who dislike literals can of course code something like

IKJL CSECT
USING 12,11,10
LR 12,15 Origin of CSECT to GR12
LA 11,2048 Number 2048 to GR11
SLL 11,1 Shift one bit to the left so as to obtain 4096
LA 10,2048 Number 2048 to GR10
SLL 10,2 Shift two bits to the left so as to obtain 8192
AR 11,12 Add contents of GR12 to contents of GR11, obtaining <GR12> + 4096
AR 10,12 Add contents of GR12 to contents of GR10, obtaining <GR12> + 8192
...................................................................................

(Takes 20 bytes)

Enjoy this old and bygone(?) stuff!

Ciao: Johan E. Mebius

JEmebius

unread,
Jul 30, 2012, 5:13:30 PM7/30/12
to JEmebius, Anonymous
Silly mistake: 8 Kbytes is of course 8192 bytes. Was too fast editing my post. Johan E. Mebius

JEmebius

unread,
Jul 30, 2012, 5:19:20 PM7/30/12
to JEmebius, Anonymous
> Kbytes (8192 bytes) and certainly less than 12 Kbytes I would define
> registers GR12, GR11 and GR10 as base registers for the first 4K, the
> second 4K and the last 4K, and load them in advance with the appropriate
> values:
> <GR15>, <GR15> + 4096, <GR15> + 8192.
>
> The most straightforward coding for this reads [use fixed-space font]
>
> ABCDEFGH CSECT
> USING *,12,11,10
> LR 12,15
> LR 11,15
> AH 11,=H'4096'
> LR 10,15
> AH 10,=H'8192'
> .................
> LTORG
> DC H'4096' (I am not sure if this the correct printing
> in the output listing)
> DC H'8192'
>
> (Takes 18 bytes)
>
> Programmers who dislike literals can of course code something like
>
> IKJL CSECT
> USING *,12,11,10
> LR 12,15 Origin of CSECT to GR12
> LA 11,2048 Number 2048 to GR11
> SLL 11,1 Shift one bit to the left so as to obtain 4096
> LA 10,2048 Number 2048 to GR10
> SLL 10,2 Shift two bits to the left so as to obtain 8192
> AR 11,12 Add contents of GR12 to contents of GR11,
> obtaining <GR12> + 4096
> AR 10,12 Add contents of GR12 to contents of GR10,
> obtaining <GR12> + 8192
>
> ...................................................................................
>
>
> (Takes 20 bytes)
>
> Enjoy this old and bygone(?) stuff!
>
> Ciao: Johan E. Mebius
>

A lapse of memory: it should read USING *,12,11,10 - Was corrected in place.
I also corrected the "4096 instead of 8192" mistake in place.
Johan E. Mebius

Andy Wood

unread,
Jul 31, 2012, 2:22:23 AM7/31/12
to

JEmebius <jeme...@xs4all.nl> wrote:

>JEmebius wrote:
...
>>
>> When I knew in advance that my OS/360 module would occupy more than 8
>> Kbytes (8192 bytes) and certainly less than 12 Kbytes I would define
>> registers GR12, GR11 and GR10 as base registers for the first 4K, the
>> second 4K and the last 4K, and load them in advance with the appropriate
>> values:
>> <GR15>, <GR15> + 4096, <GR15> + 8192.
>>
>> The most straightforward coding for this reads [use fixed-space font]
>>
>> ABCDEFGH CSECT
>> USING *,12,11,10
>> LR 12,15
>> LR 11,15
>> AH 11,=H'4096'
>> LR 10,15
>> AH 10,=H'8192'
>> .................
>> LTORG
>> DC H'4096' (I am not sure if this the correct printing
>> in the output listing)
>> DC H'8192'
>>
>> (Takes 18 bytes)
>>
>> Programmers who dislike literals can of course code something like
>>

If the number of bytes taken is important, you could reduce it from 18
to 16, by eliminating the use of the H'8192'
...
LR 10,11 After setting GR11
AH 10,=H'4096'
...

If avoiding literals is important
...
LR 2,15 Origin of CSECT to GR12
LA 10,2048 Number 2048 to GR10
LA 11,2048(10,15) GR11 = GR15 + 2048 + 2048
LA 10,2048(10,11) GR10 = GR11 + 2048 + 2048
...
and even better, that takes only 14 bytes.

Or just do like PL/S and its descendants did, set up the base regs
4095 bytes apart rather than 4096 apart. That cuts the number of bytes
taken to set up three base registers down to 10 - at the expense of
losing two bytes of addressability. Of course, the USING/s would have
to reflect the fact of the base regs being only 4095 apart too.

Andy Wood
woo...@trap.ozemail.com.au

Fritz Wuehler

unread,
Jul 31, 2012, 2:46:27 PM7/31/12
to
JEmebius <jeme...@xs4all.nl> wrote:

> When I knew in advance that my OS/360 module would occupy more than 8 Kbytes (4096 bytes) and
> certainly less than 12 Kbytes I would define registers GR12, GR11 and GR10 as base registers for the
> first 4K, the second 4K and the last 4K, and load them in advance with the appropriate values:
> <GR15>, <GR15> + 4096, <GR15> + 8192.

This is unnecessary and wasteful. There isn't any reason you need more than
one code base register, no matter how large the program is. Break the
program into functional routines, branch-enter those as needed, and readjust
the base register as needed to cover only the current routine.

> (Takes 18 bytes)

But wastes 2 registers for no good reason.

JEmebius

unread,
Jul 31, 2012, 9:44:12 PM7/31/12
to Andy Wood
> LR 12,15 Origin of CSECT to GR12
> LA 10,2048 Number 2048 to GR10
> LA 11,2048(10,15) GR11 = GR15 + 2048 + 2048
> LA 10,2048(10,11) GR10 = GR11 + 2048 + 2048
> ...
> and even better, that takes only 14 bytes.
>
> Or just do like PL/S and its descendants did, set up the base regs
> 4095 bytes apart rather than 4096 apart. That cuts the number of bytes
> taken to set up three base registers down to 10 - at the expense of
> losing two bytes of addressability. Of course, the USING/s would have
> to reflect the fact of the base regs being only 4095 apart too.
>
> Andy Wood
> woo...@trap.ozemail.com.au


Dear Mr Andy Wood,

My thanks for your extended reply to my latest post.
I never explicitly intended to set up a coding contest; I just replied to the original post to
celebrate a memory from a previous professional life of mine.

In 1968 I became an employee of Delft University of Technology on the occasion of the purchase of an
IBM S/360 Model 65 with OS/MFT and at a later date OS/MVT as its operating system. I got completely
engaged with and engulfed by IBM stuff, the Systems Journal and the Journal of Research and
Development included. I remember rather vividly the issue of the Systems Journal on NASA's Apollo
missions and got a certain understanding of the necessity of writing tight and nevertheless provably
correct coding of the on-board software.

However, during my IBM time at Delft University I never had to write tight mission-critical code.
So now is the time to take revenge, so to say, and I imagine now I have to write the tightest S/360
machine code for a moderately large module (i.e. moderately large for the 1970s).

So I did take the challenge to write coding for the three base registers in less that 14 bytes - I
did not succeed! - and then to give a proof as watertight as possible that one indeed cannot do
better than 14 bytes.


PROOF THAT ONE CANNOT DO BETTER THAN 14 BYTES IN SETTING THREE BASE REGISTERS
-----------------------------------------------------------------------------

(A)
One needs anyhow "LR 12,15", to add 4096 to GR12 and leave the result in GR11, and to add 4096 to
GR11 and leave the result in GR10. This makes three copy/store operations and two additions.

(B)
The number 4096 cannot be generated directly using only GRs. The shortest code to obtain 4096 is a
"LA ..,2048(0,0)" and one addition, or alternatively, "LH ..,=H'4096'". Generating 8192 requires one
more addition.

(C)
(C1) Altogether one needs a "LA", three copy/store operations and four additions when using GRs
only, or
(C2) with a literal H'4096': three copy/store operations and three additions.

(C1)
The Load Address instruction constitutes the shortest code to combine two additions and a store
operation. Therefore the shortest code ever possible to cover three copy/store operations and four
additions necessarily consists of two "LA" instructions and a "LR" instruction, occupying together
10 bytes. The indispensable "LA ..,2048" takes 4 bytes. Altogether 14 bytes as a minimum.

(C2)
One could try and do the job with a single "LA" and two "AR" instructions, or with three . The "LR
12,15" and the literal H'4096' occupy four bytes, the "LH" instruction to retrieve the literal also
occupies four bytes, so to beat the 14 bytes limit of case C1 one has a coding room of 6 bytes (or 7
bytes, if ever a one-byte constant would enter the game). Still two copy/stores and three additions
to go... this will never fit into six bytes, even not into eight bytes. I tried this, but did not
yet make the effort for a conclusive proof that one needs at least 16 bytes when using H'4096' in
main storage.



By the way, I was never involved in PL/S programming; my main areas at Delft University Computing
Centre were systems and interface programming in OS/360 and OS/370 Assembler Language and
application programming in Fortran, a little Algol-60, PL/1 and COBOL.
My pet programs still are
(A) a disk file inspection program based on reading full tracks in two revolutions, one revolution
for the Count fields and the next revolution for the full Count-Key-Data blocks (as long as no
End-Of-Data blocks are present; for each EOD block one needs a next revolution to read the next few
data blocks); this program shortened the operators' night shift by about one hour and a half,
fortunately without a reduction of their salaries.
(B) a newly written stand-alone post mortem dump program on punched cards for the IBM S/360 Model
44; the usual post mortem dump program covers the full S/360 instruction set and will not run on the
Model 44 with its reduced instruction set; the existing program did not conserve all of the control
words in the lowest 512 bytes across an IPL.


Best regards: Johan E. Mebius

JEmebius

unread,
Jul 31, 2012, 10:10:21 PM7/31/12
to Fritz Wuehler
My thanks for your comment.
I guess you think of subdividing large programs into CESCTs needing only one base register; correct
guess?
Of course this is a good guideline, but it is a guideline only, not a prescription cut in stone.

I know disciplines of designing and programming. A few times I followed the base register tactics
you explained. Once in a while it is next to impossible, or indeed quite impossible, to break up the
coding into functional parts of 4 Kbytes or smaller. In such cases multiple base registers are far
more practical than artificially subdividing the code into small subroutine-like pieces.

We could set up a philosophical discussion on the concepts of necessity and wastefulness in computer
programming versus the same concepts in real life. In my opinion an inconsequential discussion, a
non-issue.

Ciao: Johan E. Mebius

Michel Castelein

unread,
Aug 3, 2012, 5:13:07 AM8/3/12
to
"Fritz Wuehler" <fr...@spamexpire-201207.rodent.frell.theremailer.net> wrote
in message
news:c2050bf4a69fa2ab...@msgid.frell.theremailer.net...
Yep. But using a sole base register with a "variable" contents does not
facilitate debugging.

M. Castelein


Anonymous

unread,
Aug 3, 2012, 9:05:13 AM8/3/12
to
On the contrary, it is quite helpful for debugging because you always know
in which routine you are, when viewing a dump. This principle is widely
known, indeed the vendor dump analysis products all compute the failure
location by differencing all the GPRs from the next instruction address in
the PSW.



















Allodoxaphobia

unread,
Aug 3, 2012, 9:29:36 AM8/3/12
to
On Fri, 3 Aug 2012 13:05:13 +0000 (UTC), Anonymous wrote:
> "Michel Castelein" <ar...@advalvas.be.without.this.no.spam.tail> wrote:
>> "Fritz Wuehler" <fr...@spamexpire-201207.rodent.frell.theremailer.net> wrote:
>> > JEmebius <jeme...@xs4all.nl> wrote:
>> >
>> >> When I knew in advance that my OS/360 module would occupy more than 8
>> >> Kbytes (4096 bytes) and
>> >> certainly less than 12 Kbytes I would define registers GR12, GR11 and
>> >> GR10 as base registers for the
>> >> first 4K, the second 4K and the last 4K, and load them in advance with
>> >> the appropriate values:
>> >> <GR15>, <GR15> + 4096, <GR15> + 8192.
>> >
>> > This is unnecessary and wasteful. There isn't any reason you need more
>> > than
>> > one code base register, no matter how large the program is. Break the
>> > program into functional routines, branch-enter those as needed, and
>> > readjust
>> > the base register as needed to cover only the current routine.
>> >
>> >> (Takes 18 bytes)
>> >
>> > But wastes 2 registers for no good reason.
>>
>> Yep. But using a sole base register with a "variable" contents does not
>> facilitate debugging.
>
> On the contrary, it is quite helpful for debugging because you always know
> in which routine you are, when viewing a dump. This principle is widely
> known, indeed the vendor dump analysis products all compute the failure
> location by differencing all the GPRs from the next instruction address in
> the PSW.

Provided the interrupt PSW is not the result of a WAB...

JEmebius

unread,
Aug 3, 2012, 7:03:52 PM8/3/12
to Allodoxaphobia
Thanks to everybody for all the comments and replies...

But could someone please tell me what a WAB is, is it an acronym? of what??

Google yields several dozens of possible meanings of WAB. Even when adding search terms like "S/360"
I cannot find any clue. The only find after a 5-minute search is an obscure assembly listing;
URL http://www.freeusp.org/Arco/Data/sparc/s1date .

My S/360 and S/370 experience predates the S/390 era. I have an inkling of circumstances under which
an Interrupt Old PSW may be inaccurate: I guess an exact Current Instruction Pointer cannot always
be reconstructed / retrieved in multi-processor and/or instruction pipelining environments. Correct?

Thanks in advance... Johan E. Mebius

Allodoxaphobia

unread,
Aug 3, 2012, 11:14:25 PM8/3/12
to
Wild Ass Branch

> My S/360 and S/370 experience predates the S/390 era.

My first [System Reset][Start][Start] in 1966

Nomen Nescio

unread,
Aug 6, 2012, 9:15:27 AM8/6/12
to
No, it still helps. Think about it. Now instead of wondering where in the
whole program you took the WAB you know it was most likely from the routine
based where the base register points.




























Fritz Wuehler

unread,
Aug 7, 2012, 10:36:58 AM8/7/12
to
JEmebius <jeme...@xs4all.nl> wrote:

> Fritz Wuehler wrote:
> > JEmebius <jeme...@xs4all.nl> wrote:
> >
> >> When I knew in advance that my OS/360 module would occupy more than 8 Kbytes (4096 bytes) and
> >> certainly less than 12 Kbytes I would define registers GR12, GR11 and GR10 as base registers for the
> >> first 4K, the second 4K and the last 4K, and load them in advance with the appropriate values:
> >> <GR15>, <GR15> + 4096, <GR15> + 8192.
> >
> > This is unnecessary and wasteful. There isn't any reason you need more than
> > one code base register, no matter how large the program is. Break the
> > program into functional routines, branch-enter those as needed, and readjust
> > the base register as needed to cover only the current routine.
> >
> >> (Takes 18 bytes)
> >
> > But wastes 2 registers for no good reason.
> >
>
>
> My thanks for your comment.
> I guess you think of subdividing large programs into CESCTs needing only one base register; correct
> guess?
> Of course this is a good guideline, but it is a guideline only, not a
> prescription cut in stone.

Given the relative scarcity of registers, it's a guideline I always follow
and have always been able to implement. I don't see any reason for any piece
of code to ever use more than one code base register. If it does use more
than one, it is poorly designed. When you can't perform a function in 4K of
code, you should work out a better solution.

> I know disciplines of designing and programming. A few times I followed the base register tactics
> you explained. Once in a while it is next to impossible, or indeed quite impossible, to break up the
> coding into functional parts of 4 Kbytes or smaller. In such cases multiple base registers are far
> more practical than artificially subdividing the code into small
> subroutine-like pieces.

Just because you were unable to do it doesn't mean I wouldn't be able to do
it. Indeed, I have made quite a lot of money refactoring poorly written
assembler code. I haven't ever seen a program no matter how large, that I
couldn't fix and reorganize and that includes single modules of up to around
250,000 lines of assembler. Reorganizing these into functional segments is a
high value proposition, because when a program is poorly designed and
requires more than one code base register, it seems like every other change
blows off the end of the base register and even minor changes become
impossible. The little fixes never last. The only answer is to fix it right
once and for all and then it becomes much simpler and less costly to
maintain.

Nomen Nescio

unread,
Aug 7, 2012, 3:33:57 PM8/7/12
to
Fritz Wuehler <fr...@spamexpire-201208.rodent.frell.theremailer.net> wrote:

> JEmebius <jeme...@xs4all.nl> wrote:
>
> > Fritz Wuehler wrote:
> > > JEmebius <jeme...@xs4all.nl> wrote:
> > >
> > >> When I knew in advance that my OS/360 module would occupy more than 8 Kbytes (4096 bytes) and
> > >> certainly less than 12 Kbytes I would define registers GR12, GR11 and GR10 as base registers for the
> > >> first 4K, the second 4K and the last 4K, and load them in advance with the appropriate values:
> > >> <GR15>, <GR15> + 4096, <GR15> + 8192.
> > >
> > > This is unnecessary and wasteful. There isn't any reason you need more than
> > > one code base register, no matter how large the program is. Break the
> > > program into functional routines, branch-enter those as needed, and readjust
> > > the base register as needed to cover only the current routine.
> > >
> > >> (Takes 18 bytes)
> > >
> > > But wastes 2 registers for no good reason.
> > >
> >
> >
> > My thanks for your comment.
> > I guess you think of subdividing large programs into CESCTs needing only one base register; correct
> > guess?

I meant to answer this before; the answer is no, I prefer to have one CSECT
in a source module and my comments about not needing more than one code base
register no matter how large that module is apply exactly to this situation
as the specific case of the general comment.

I generally object to multiple CSECTs in one source module because it makes
the listings ugly and can cause other unnecessary confusion. If you feel you
have code that's suitable for reuse you ought to give it its own source
module and make it a CSECT. It makes it easier to work on it in a team
environment and the end result is smaller when other users link it than if
you had a huge module with many entry points or CSECTs and had to link the
whole thing just to use one service.









Clark F Morris

unread,
Aug 7, 2012, 5:13:57 PM8/7/12
to
With the z series Branch Relative instructions, is the only reason for
a base register the need to handle Macro instructions and constants if
a module must be reentrant? Non-reentrant modules also could require
a base register for data areas?

Clark Morris
>

alistair.j...@gmail.com

unread,
Aug 19, 2012, 8:58:16 AM8/19/12
to
On Friday, July 6, 2012 2:52:45 PM UTC+1, (unknown) wrote:
> Many assembler programs begin with a USING * statement. Could someone explain it? Thanks.

It's great to see some activity here again.

I'm surprised that in the rush to save registers and keeping the code down to 14 bytes, no-one mentioned clock cycles.

John W Kennedy

unread,
Aug 19, 2012, 1:15:57 PM8/19/12
to
In most real-world programs, on most machines with general-purpose
registers, saving registers /is/ saving clock cycles. Saving bytes is
less important, so long as you are not so prodigious with your bytes as
to waste a base register. (Of course, depending on what's going on,
saving code bytes may intrinsically save some cycles, too.)

--
John W Kennedy
"There are those who argue that everything breaks even in this old dump
of a world of ours. I suppose these ginks who argue that way hold that
because the rich man gets ice in the summer and the poor man gets it in
the winter things are breaking even for both. Maybe so, but I'll swear
I can't see it that way."
-- The last words of Bat Masterson

Nomen Nescio

unread,
Aug 19, 2012, 4:20:04 PM8/19/12
to
John W Kennedy <jwk...@attglobal.net> wrote:

> On 2012-08-19 12:58:16 +0000, alistair.j...@gmail.com said:
>
> > On Friday, July 6, 2012 2:52:45 PM UTC+1, (unknown) wrote:
> >> Many assembler programs begin with a USING * statement. Could someone
> >> explain it? Thanks.
> >
> > It's great to see some activity here again.
> >
> > I'm surprised that in the rush to save registers and keeping the code
> > down to 14 bytes, no-one mentioned clock cycles.
>
> In most real-world programs, on most machines with general-purpose
> registers, saving registers /is/ saving clock cycles. Saving bytes is
> less important, so long as you are not so prodigious with your bytes as
> to waste a base register. (Of course, depending on what's going on,
> saving code bytes may intrinsically save some cycles, too.)

Clock cycles are a renewable resource, registers are not.












John W Kennedy

unread,
Aug 19, 2012, 6:30:00 PM8/19/12
to
But registers possess no intrinsic value, whereas clock cycles do. On
some first- and second-generation machines, registers existed only as
unaddressable implementation details (e.g., on 1401s without the
Advanced Programming Feature) or as unique single-purpose devices
(e.g., the Accumulator of the 701).

--
John W Kennedy
"Those in the seat of power oft forget their failings and seek only the
obeisance of others! Thus is bad government born! Hold in your heart
that you and the people are one, human beings all, and good government
shall arise of its own accord! Such is the path of virtue!"
-- Kazuo Koike. "Lone Wolf and Cub: Thirteen Strings" (tr. Dana Lewis)

0 new messages