Lew Pitcher a écrit :
On September 8, 2009 16:59, in comp.lang.c, jacob navia (
[email protected])
wrote:
[snip]
Then they started tripping with IBM mainframes. Nope, I showed
them the documentation of the IBM compilers for mainframes
where they describe the stack and its associated register (r13)
Sorry, Jacob, but R13 is definitely *not* a hardware "stack pointer"
register.
The use of R13 in MVS (and it's follow-on operating systems) and VSE
(and /it's/ followns) is as a single pointer to a linked-list of
dynamically allocated memory blocks. There is no direct equivalent of a
PUSH or POP instruction that places data at a location pointed to by a
register /and/ increments (or decrements) the register atomically.
In fact, the use of R13 as a pointer to a save area (as this block is
called) is a /software convention/, and not dictated by hardware at all.
You can't say that R13 is a stack pointer in the hardware sense. The
/best/ you can do is say that IBM mainframe pointers implement a fifo
using a linked-list of activation records, and the topmost activation
record is pointed to by R13 (and possibly other registers).
Additionally, since such an activation record could exceed 4K in size,
R13 may not necessarily be used to access the contents of the record;
other registers may be used instead.
Finally, since R13 points to the /previous/ activation record, the
currently executing function will use a /different/ register to access
it's own dynamically-allocated storage.
[snip]
I said in this group in Sat, 15 Mar 2008 11:16:43 +0100
There is nothing more "big iron" that the IBM mainframes... at least
within my limited experience since I quit using that environment
in 1984.
The C compiler for the IBM mainframes is "C for VM/ESA", a C89
compiler.
We find in the users guide
http://publibfp.boulder.ibm.com/cgi-bin/bookmgr/BOOKS/cbcvpg00/CCONTENTS
3.1.4.3 Accessing Automatic Memory
Use the EDCDSAD macro to access automatic memory. Automatic memory is
reserved using the USRDSAL, or the DSALEN operand of the EDCPRLG macro.
The length of the allocated area is derived from the ulen and/or dlen
values specified on the EDCPRLG macro. EDCDSAD generates a DSECT, which
reserves space for the *stack frame* needed for the C environment.
<end quote>
I repeat: "... the stack frame needed for the C environment".
First off, let's take a look at the beginning of that section, shall we?
3.1.4 Using Standard Macros
To communicate properly, assembler routines must preserve the use of
certain registers and particular storage areas, in a fashion consistent
with code from the C compiler. C VM/ESA provides three macros for use
with assembler routines. These macros are in SCEEMAC MACLIB. The macros
are:
EDCPRLG
Generates the prolog for assembler code
EDCEPIL
Generates the epilog for assembler code
EDCDSAD
Accesses automatic memory
And we see that you aren't reading about how the C compiled code works, but
about how an Assembly language program must interface with a C program.
What you don't see in the description of the EDCDSAD macro is the magic
that the EDCPRLG macro performs to permit EDCPRLG to work.
Let's move on and follow some of the document that you quote, shall we?
Your quote indicates that the "automatic memory" thus accessed is reserved
either by the USRDSAL or DSALEN operands of the EDCPRLG macro. OK, so let's
look at section 3.1.4.1 Assembler Prolog, which discusses the EDCPRLG
macro. Here we find that...
USRDSAL=ulen
Is used only when automatic storage (in bytes) is needed. To address
this storage, see the EDCDSAD macro description. The ulen value is the
requested length of the user space in the Dynamic Storage Area (DSA).
Ohhhh.... looks like the USRDSAL that you refer to is a static-length block
of memory, allocated at function-entry time.
What about DSALEN, then?
DSALEN=dlen
Is the total requested length of the DSA. The default is 120. If fewer
than 120 bytes are requested, 120 bytes are allocated. If both dlen and
ulen are specified, then the greater of dlen or ulen+120 is allocated.
If DSALEN=NONE is specified, no code is generated for DSA storage
allocation, and R13 will still point to the caller's DSA. Therefore, you
should not use the EDCEPIL macro to terminate the assembler routine..
Instead, you have to restore the registers yourself from the current
DSA. To do this, you can use an assembler instruction such as
LM 14,12,12(13)
You should not use EDCDSAD to access automatic memory if you have
specified DSALEN=NONE, since DSECT is addressable using R13.
Hmmm... again, a fixed length block, this time not to exceed 120 bytes long.
Again, not a stack, but a fixed-length activation record.
Now, as for using R13, the documentation for EDCDSAD says
"The DSECT is addressable using Register 13, which is initialized by the
prolog code."
A DSECT is a description of a fixed-size, fixed-layout area of arbitrary
memory. Consider it the equivalent of a struct {}; as it simply names the
arrangement of data. Like a struct, a DSECT describes something of fixed
size and of fixed layout. It doesn't describe an array of things, but a
single collection of things.
The documentation says that R13 points to this DSECT. In C terms...
register struct EDCDSAD *R13;
No stack here. Simply a fixed layout activation record, pointed to by a
register pointer variable.
Now, as to IBM's reference to a "stack frame", I'm not going to try to
deduce why they phrased it that way. However, I can assure you that there
is *NO* machine stack. And certainly *NO* machine stack addressed by R13.
Indeed, R13 isn't really permitted to change (unlike a stack pointer), as
it *always* has to point at the beginning of the save-area.
--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------