Re: reason for having return addresses in parameter stack?

2015-04-02 Thread Joel Rees
I was asleep when I posted this, so I left out the example code.

Don't know why, but I worked out more complete code than the example I
failed to give. To keep chatter off the list, I posted it in my blog,
if anyone is interested. (Probably not?)

http://defining-computers.blogspot.jp/2015/03/splitting-return-addresses-out-of.html

--
Joel Rees

On Mon, Mar 30, 2015 at 1:08 AM, Joel Rees joel.r...@gmail.com wrote:
 On Sun, Mar 29, 2015 at 2:50 PM, Philip Guenther guent...@gmail.com wrote:
 On Sun, 29 Mar 2015, Joel Rees wrote:
 Is there any good reason for interleaving the return addresses with data
 on the data/parameter stack in C? I know it's the tradition, from back
 when it was all we could hope for to have one page per process, but that
 has not been the case for many years, I think.

 It's easy, efficient,

 I don't agree with those two assertions, but I'm not really looking at
 easy or efficient. I'm thinking about return pointers getting walked
 on.

 doesn't burn another register for a second stack,

 I've often pondered on whether the entire reason for having a frame
 pointer is that you have to have something to lead you around the
 return pointer.

 Still, there is no reason to keep the frame link in a register. Dump
 the saved parameter stack pointer on the flow-of-control stack, paired
 with the return pointer, and you're done. If you think even that is
 necessary. Or you could save the previous top of parameter stack below
 the local variables and temporaries on the parameter stack, which is a
 little more fragile, if you really want to make it appear to be a
 linked list.

 and the ISA (instruction set architecture) may have direct support for it.

 Looking at all the funky instructions and addressing modes the 68020
 and 80286 and 80386 directly supported, but got left behind as CPU
 advanced, direct instruction support really isn't an argument, to me.

 For example, in both i386 and x86_64 the 'call' and 'ret' instructions
 work with the same stack pointer, %sp, as the various 'push' and 'pop'
 instructions.

 Yeah, it does feel like a waste not to use the instructions provided,
 doesn't it?

  If you use %sp for the stack with return addresses so you
 can use 'call' and 'ret', then what is stack pointer for your
 arguments/locals stack?

 Well, if we link the frame on one of the stacks instead of in a
 register, the erstwhile frame pointer register isn't doing anything in
 particular any more.

  On i386, you're crying for registers already;
 losing another would be bad.

 Back when SP and BP were sixteen bits, and pointed into the same
 segment unless overridden, there was definitely something unsettling
 about using them independently, but if you consider that the 6809 was
 even more restricted in stack space when you used SP and UP for two
 separate stacks, you remember that, even now, most stacks aren't that
 big anyway.

 But that was then, this is now, and %sp and %bp aren't sixteen bits
 any more. We can define regions that cause access exceptions to help
 us know when our stacks and heaps collide. And are we still even using
 the segment registers?

 I know older MMUs are kind of tight on the number of page tables you
 can keep active, but are they that tight? This is one of my questions,
 by the way.

 Hmm, wasn't there a shipping processor which explicitly have two stacks
 something like this?  I have a vague memory that it may have been itanium,
 but that could be a hallucination.

 My impression was that the register stack backing store was assumed to
 be allocated with the rest of the procedure frame in the memory stack,
 but the documentation seems to have been written by lawyers who really
 didn't want their end users to be able to pierce the patent haze. I
 couldn't say for sure, and I never had actual hardware to check
 against, and I really don't want to dig into that dinosaur any more.

 Intel has always made things harder than necessary.

 Adding code to the program preamble to reserve space for another stack
 with mmap shouldn't be hard at all. Default address separation of about
 a quarter to a half a gig should be reasonable in 32 bit address space,
 at any rate. New compiler switches would be needed to tune the
 separation. I'm pretty sure openbsd has the means to keep a largish
 no-access region between the stacks.

 Ugh, knobs are bad if more than a tiny fraction of program have to use
 them.

 You won't hear me argue with you there. But default to a quarter gig
 of unallocated logical address space below each stack and only a tiny
 fraction of programs would need to change that.

 The call protocol itself should be simpler, although I might expect some
 debate about which stack to push frame pointers to when pushing frame
 pointers. The problem, I think, is in convincing the compiler to refrain
 from moving the frame pointer to the stack pointer on function entry.
 Maybe.

 Simpler?

 Well, yeah, I think so.

 I doubt it.  To support exception processing and 

Re: reason for having return addresses in parameter stack?

2015-03-29 Thread Joel Rees
On Sun, Mar 29, 2015 at 2:50 PM, Philip Guenther guent...@gmail.com wrote:
 On Sun, 29 Mar 2015, Joel Rees wrote:
 Is there any good reason for interleaving the return addresses with data
 on the data/parameter stack in C? I know it's the tradition, from back
 when it was all we could hope for to have one page per process, but that
 has not been the case for many years, I think.

 It's easy, efficient,

I don't agree with those two assertions, but I'm not really looking at
easy or efficient. I'm thinking about return pointers getting walked
on.

 doesn't burn another register for a second stack,

I've often pondered on whether the entire reason for having a frame
pointer is that you have to have something to lead you around the
return pointer.

Still, there is no reason to keep the frame link in a register. Dump
the saved parameter stack pointer on the flow-of-control stack, paired
with the return pointer, and you're done. If you think even that is
necessary. Or you could save the previous top of parameter stack below
the local variables and temporaries on the parameter stack, which is a
little more fragile, if you really want to make it appear to be a
linked list.

 and the ISA (instruction set architecture) may have direct support for it.

Looking at all the funky instructions and addressing modes the 68020
and 80286 and 80386 directly supported, but got left behind as CPU
advanced, direct instruction support really isn't an argument, to me.

 For example, in both i386 and x86_64 the 'call' and 'ret' instructions
 work with the same stack pointer, %sp, as the various 'push' and 'pop'
 instructions.

Yeah, it does feel like a waste not to use the instructions provided,
doesn't it?

  If you use %sp for the stack with return addresses so you
 can use 'call' and 'ret', then what is stack pointer for your
 arguments/locals stack?

Well, if we link the frame on one of the stacks instead of in a
register, the erstwhile frame pointer register isn't doing anything in
particular any more.

  On i386, you're crying for registers already;
 losing another would be bad.

Back when SP and BP were sixteen bits, and pointed into the same
segment unless overridden, there was definitely something unsettling
about using them independently, but if you consider that the 6809 was
even more restricted in stack space when you used SP and UP for two
separate stacks, you remember that, even now, most stacks aren't that
big anyway.

But that was then, this is now, and %sp and %bp aren't sixteen bits
any more. We can define regions that cause access exceptions to help
us know when our stacks and heaps collide. And are we still even using
the segment registers?

I know older MMUs are kind of tight on the number of page tables you
can keep active, but are they that tight? This is one of my questions,
by the way.

 Hmm, wasn't there a shipping processor which explicitly have two stacks
 something like this?  I have a vague memory that it may have been itanium,
 but that could be a hallucination.

My impression was that the register stack backing store was assumed to
be allocated with the rest of the procedure frame in the memory stack,
but the documentation seems to have been written by lawyers who really
didn't want their end users to be able to pierce the patent haze. I
couldn't say for sure, and I never had actual hardware to check
against, and I really don't want to dig into that dinosaur any more.

Intel has always made things harder than necessary.

 Adding code to the program preamble to reserve space for another stack
 with mmap shouldn't be hard at all. Default address separation of about
 a quarter to a half a gig should be reasonable in 32 bit address space,
 at any rate. New compiler switches would be needed to tune the
 separation. I'm pretty sure openbsd has the means to keep a largish
 no-access region between the stacks.

 Ugh, knobs are bad if more than a tiny fraction of program have to use
 them.

You won't hear me argue with you there. But default to a quarter gig
of unallocated logical address space below each stack and only a tiny
fraction of programs would need to change that.

 The call protocol itself should be simpler, although I might expect some
 debate about which stack to push frame pointers to when pushing frame
 pointers. The problem, I think, is in convincing the compiler to refrain
 from moving the frame pointer to the stack pointer on function entry.
 Maybe.

 Simpler?

Well, yeah, I think so.

 I doubt it.  To support exception processing and debugger
 unwinding of calls and displaying variables from them you'll need some way
 to successively peel call frames off *both* stacks.

On the caller side, push your arguments, perform an unadorned call.
Something like

SUB SP, parameterbytes


On the called side, if the frame is being maintained, save the
parameter stack pointer on the flow-of-control stack. Do your stuff.
When you're done, if the compiler knows what it has on the stack
anyway, you 

Re: reason for having return addresses in parameter stack?

2015-03-28 Thread Philip Guenther
On Sun, 29 Mar 2015, Joel Rees wrote:
 Is there any good reason for interleaving the return addresses with data 
 on the data/parameter stack in C? I know it's the tradition, from back 
 when it was all we could hope for to have one page per process, but that 
 has not been the case for many years, I think.

It's easy, efficient, doesn't burn another register for a second stack, 
and the ISA (instruction set architecture) may have direct support for it.

For example, in both i386 and x86_64 the 'call' and 'ret' instructions 
work with the same stack pointer, %sp, as the various 'push' and 'pop' 
instructions.  If you use %sp for the stack with return addresses so you 
can use 'call' and 'ret', then what is stack pointer for your 
arguments/locals stack?  On i386, you're crying for registers already; 
losing another would be bad.

Hmm, wasn't there a shipping processor which explicitly have two stacks 
something like this?  I have a vague memory that it may have been itanium, 
but that could be a hallucination.


 Adding code to the program preamble to reserve space for another stack 
 with mmap shouldn't be hard at all. Default address separation of about 
 a quarter to a half a gig should be reasonable in 32 bit address space, 
 at any rate. New compiler switches would be needed to tune the 
 separation. I'm pretty sure openbsd has the means to keep a largish 
 no-access region between the stacks.

Ugh, knobs are bad if more than a tiny fraction of program have to use 
them.


 The call protocol itself should be simpler, although I might expect some 
 debate about which stack to push frame pointers to when pushing frame 
 pointers. The problem, I think, is in convincing the compiler to refrain 
 from moving the frame pointer to the stack pointer on function entry. 
 Maybe.

Simpler?  I doubt it.  To support exception processing and debugger 
unwinding of calls and displaying variables from them you'll need some way 
to successively peel call frames off *both* stacks.

 
 To those on the list who are intimate with the compiler(s), how difficult
 would it be to change the function call protocol to push the program
 counter to a separate stack from the parameters and locals?

Heh, you're talking about creating a new ABI.  For difficultly level, look 
at the x32 ABI in Linux.  It's an alternative ABI for x86-long-mode, 
changing relatively few things from the amd64/x86_64 ABI, and it still 
took a huge effort.

You might want to grab a copy of the ELF ABI for a CPU you're interested 
in, read through it and see what sort of changes would be necessary for 
supporting a two-stack model.  Example code sequences for argument 
passing, relocations, stack unrolling, registers set on process entry,...


Oooh, and then threads come into play, where programs expect to be able to 
specify a single size for the stack, so maybe you should have the two 
stacks grow towards each other from opposite ends of the allocated stack 
memory?


 Or am I speculating about a different world, still?

Tomorrow is a different world, but only slightly so.



reason for having return addresses in parameter stack?

2015-03-28 Thread Joel Rees
This is a question that has bothered me for more than twenty-five years.
Blame it on my being one of those forthies, I guess. Recent posts encourage
me to ask again.

Is there any good reason for interleaving the return addresses with data on
the data/parameter stack in C? I know it's the tradition, from back when it
was all we could hope for to have one page per process, but that has not
been the case for many years, I think.

Adding code to the program preamble to reserve space for another stack with
mmap shouldn't be hard at all. Default address separation of about a
quarter to a half a gig should be reasonable in 32 bit address space, at
any rate. New compiler switches would be needed to tune the separation. I'm
pretty sure openbsd has the means to keep a largish no-access region
between the stacks.

The call protocol itself should be simpler, although I might expect some
debate about which stack to push frame pointers to when pushing frame
pointers. The problem, I think, is in convincing the compiler to refrain
from moving the frame pointer to the stack pointer on function entry. Maybe.

To those on the list who are intimate with the compiler(s), how difficult
would it be to change the function call protocol to push the program
counter to a separate stack from the parameters and locals?

Or am I speculating about a different world, still?

Joel Rees

Computer memory is just fancy paper,
CPUs just fancy pens.
All is a stream of text
flowing from the past into the future.