should program call stack grow upward or downwards?

S

Simon

Hi there:

I know this is a very fundamental question. I am still quite confused
if the program call stack stack should always grow upwards from the
bottom, or the opposite, or doesn't matter??

That means the stack pointer should go upwards when there are "push"
operations,
and stack pointer should go downards when there are "pop" operations??

If this is the case, the address should go upwards (increasing) or
downards (decreasing) then? i.e. The top of the stack should have
address 00000000, or FFFFFFFF? How do we decide that?

Thanks!
 
I

Ian Collins

Hi there:

I know this is a very fundamental question. I am still quite confused
if the program call stack stack should always grow upwards from the
bottom, or the opposite, or doesn't matter??

It doesn't matter. It is a typically a hardware property.
 
S

Simon

Ian said:
It doesn't matter. It is a typically a hardware property.

I see. Isn't it then important to avoid writing code that depends on
stack growth direction?
 
S

Shao Miller

I see. Isn't it then important to avoid writing code that depends on
stack growth direction?

Were you going to write this code in C, assembly language, or something
else? Are you concerned about portable code at all, or are you only
concerned with a particular architecture?
 
K

Keith Thompson

Simon said:
I see. Isn't it then important to avoid writing code that depends on
stack growth direction?

Yes.

If you can show us an example of C code that depends on the direction
of stack growth, perhaps we can help you fix it. (Frankly, it
wouldn't even occur to me to write such code; 99+% of the time,
knowing which way the stack grows isn't even useful.)
 
I

Ian Collins

I see. Isn't it then important to avoid writing code that depends on
stack growth direction?

Yes, if you want it to be portable. You would have to perform
contortions write code that did stack growth direction!
 
S

Seebs

I see. Isn't it then important to avoid writing code that depends on
stack growth direction?

Yes, absolutely!

I don't think you can write code which depends on stack growth direction
and isn't awful, in C.

-s
 
S

Seebs

I know this is a very fundamental question. I am still quite confused
if the program call stack stack should always grow upwards from the
bottom, or the opposite, or doesn't matter??

Doesn't matter.
If this is the case, the address should go upwards (increasing) or
downards (decreasing) then? i.e. The top of the stack should have
address 00000000, or FFFFFFFF? How do we decide that?

You don't.

Okay, a few things:
1. There are real machines on which there *isn't* a "stack" in the sense
you discuss.
2. Even on machines where there is, it simply doesn't matter. You should
never, ever, be writing code in C which would be affected by this.
3. Even if you were, neither of those addresses would be a likely candidate.

Basically, if you are thinking about "the stack" as some kind of contiguous
region of memory, you are not thinking about C, but about some specific
machine. For C, it's enough to know that automatic variables have a lifetime
which ends when you leave the block in which they are declared.

-s
 
J

Joe Pfeiffer

Simon said:
I see. Isn't it then important to avoid writing code that depends on
stack growth direction?

No, because any code that *does* depend on stack growth direction is
badly broken in other ways as well, and fixing that other brokenness
will also make it stop depending on the direction of stack growth.
 
S

Seebs

Yes, if you want it to be portable. You would have to perform
contortions write code that did stack growth direction!

There's a couple of famous ones, including a surprisingly likely to port
implementation of alloca(). The magic in that one is... well, it's magic.

I would point out that the author has repeatedly told people not to use
that. I am very disturbed to note that I found a copy of it in the sudo
source code.

-s
 
M

Malcolm McLean

Alas, saying 'that is not portable' or 'that is undefined behaviour' would
not have been so useful for tracking the source of the watchdog-generating hang.
Not all programs can be written portably, and not all programs can,
strictly, be written in C, though sometimes you can rely on C tricks
like writing to absolute memory addresses, or peeking at the memory
before the pointer returned by malloc(), to obtain your desired
result. Debuggers / watchdogs are examples of programs that are
inherently very OS-specific.
 
K

Keith Thompson

paul said:
I can't show you offhand, but I once had to write a watchdog
interrupt function that read the address of the instruction that
was executing (when the watchdog interrupt occured) from the
stack and write it to non-volatile memory.

Alas, saying 'that is not portable' or 'that is undefined
behaviour' would not have been so useful for tracking the source
of the watchdog-generating hang.

I have no doubt that there are cases where you need to know which
way the stack grows. Though in your case, it seems that you would
need to know a lot more than that; you'd need to know exactly where
the instruction address is stored.

The real point of my question, though, was to find out why the
original poster, Simon, was asking about the direction of stack
growth. My hunch is that it's really not relevant to anything
he needs to do, but he could have a good reason to be concerned
about it. Or he might just be curious, which is also a perfectly
good reason to ask. But knowing what's behind the question can
affect how we answer it.
 
S

sandeep

Keith said:
If you can show us an example of C code that depends on the direction of
stack growth, perhaps we can help you fix it.

I believe that the program below gives an example of such a code:

#include <stdio.h>
#include <stdint.h>

static uintptr_t p[2];

void foo(int x) {
p[x] = (uintptr_t) &x;
if(x == 0)
foo(1);
}

int main(void) {
foo(0);
if(p[1] < p[0])
puts("apple"); // expected on X86
else
puts("banana");
return 0;
}
 
P

Phil Carmody

sandeep said:
Keith said:
If you can show us an example of C code that depends on the direction of
stack growth, perhaps we can help you fix it.

I believe that the program below gives an example of such a code:

#include <stdio.h>
#include <stdint.h>

static uintptr_t p[2];

void foo(int x) {
p[x] = (uintptr_t) &x;
if(x == 0)
foo(1);
}

If your compiler doesn't turn that into the equivalent of

void foo(int x) {
entry:
p[x] = (uintptr_t) &x;
if(x != 0)
return
x=1;
goto entry;
}

then I'd consider getting a better compiler.
If you want to dissuade the compiler from using tail recursion,
at least use some auto variables.

Phil
 
K

Keith Thompson

sandeep said:
Keith said:
If you can show us an example of C code that depends on the direction of
stack growth, perhaps we can help you fix it.

I believe that the program below gives an example of such a code:

#include <stdio.h>
#include <stdint.h>

static uintptr_t p[2];

void foo(int x) {
p[x] = (uintptr_t) &x;
if(x == 0)
foo(1);
}

int main(void) {
foo(0);
if(p[1] < p[0])
puts("apple"); // expected on X86
else
puts("banana");
return 0;
}

Yes, but that's not really the point. Of course you can *contrive*
a program that depends on the direction of stack growth (assuming,
in this case, that the conversion from int* to uintptr_t preserves
order, which is not guaranteed). I asked because I wanted to know
why Simon, the original poster, is concerned about the direction
of stack growth.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top