tags:

views:

105

answers:

4

how to find if stack increases upwards or downwards?

+2  A: 

One possible way is...

#include <stdio.h>

void call(int *a) 
{
    int b;

    if (&b > a) 
        printf("Stack grows up.\n");
    else 
        printf("Stack grows down.\n");
}

int main () 
{
    int a;
    call(&a);
    return 0;
}
Vino
This assumes that the compiler in question passes parameters on the stack, and that local variables are also allocated from the stack. This is not guaranteed and is, indeed, pretty inefficient.
David Lively
This highly depends on how the compiler implements function calls and local variables.
tur1ng
I would add `\n` at the end of the strings.
ndim
This also assumes that comparisons of addresses of items that don't belong to the same array gives meaningful results -- which the C standard does *not* require. Interestingly enough, in C++ `std::less` is required to, even if native comparisons don't.
Jerry Coffin
@ndim. Thanks for the comment.
Vino
+1. While this is an implementation dependent hack, the stack itself can sort-of be considered an implementation dependent hack. The OP is inherently asking a platform dependant question and he should be satisfied with a platform dependent answer.
Billy ONeal
@Billy, I'd agree if the respondent provided some information about which platforms this works on. Any decent optimizer is going to put that local variable in a register and call it a day, making this solution useless.
David Lively
Taking the address of the auto variables (function local variables) forces them to be in RAM and not reside in registers, so this does work. If some standard C implementation does not use the stack for this RAM then I've never heard of it. I know of non-standard implementation that did this, but taking the address of local variables wouldn't work on them.
nategoose
Another assumption here is that the whole stack is contiguous. See the recent work on [split stacks in GCC](http://gcc.gnu.org/wiki/SplitStacks) for an example of something that would break this assumption.
Matthew Slattery
@nategoose On some platforms (the 8051 comes to mind), registers are allocated from RAM, making the distinction that you're trying to make inapplicable. And, yes, in that situation you *can* get the address of a register. The C spec doesn't dictate how these things are implemented.
David Lively
@David Lively -- I actually considered the 8051 when making my comment, which is why I used "standard C implementation". The C I've used for the 8051 isn't ANSI C because of the requirements that it have 3 different types of pointers because of the 3 different address spaces (Stack, Data, and Code) and it has swappable register banks, IIRC. AVR and MSP430 also have registers in RAM space, but if you pass the address of an auto variable to a function that function can push all registers breaking the pointer reference to a register.
nategoose
A: 

Brute force approach is to fill your memory with a known value say 0xFF. Push some items on the stack. Do a memory dump. Push some more items on the stack. Do another memory dump.

mjh2007
+3  A: 

This is very platform-dependent, and even application-dependent.

The code posted by Vino only works in targets where parameters are passed on the stack AND local variables are allocated from the stack, in that order. Many compilers will assign fixed memory addresses to parameters, or pass parameters in registers. While common, passing parameters on the stack is one of the least efficient ways to get data into and out of a function.

Look at the disassembly for your compiled app and see what code the compiler is generating. If your target has native stack manipulation commands (like PUSH and POP) that the compiler is using, then the CPU datasheet/reference manual will tell you which direction the stack is growing. However, the compiler may choose to implement its own stack, in which case you'll have to do some digging.

Or, read the stack pointer, push something on the stack, and read the stack pointer again. Compare the results of the first and second read to determine the direction in which the pointer moves.

For future reference: if you include some details about your target architecture (embedded? PC? Linux, Windows? GCC? VC? Watcom? blah blah blah) you'll get more meaningful answers.

David Lively
+1 for the first statement.
Billy ONeal
A: 

Create function with many local variables.
Turn off optimizations. Either print the assembly language.. Or when debugging, display as mixed source and assembly language. Note the stack pointer (or register) before the function is executed. Single-step through the function and watch the stack pointer.

In general, whether a compiler uses incrementing or decrementing stack pointers is a very minor issue as long as the issue is consistent and working. This is one issue that rarely occupies my mind. I tend to concentrate on more important topics, such as quality, correctness and robustness.

I'll trust the compiler to correctly handle stack manipulation. I don't trust recursive functions, especially on embedded or restricted platforms.

Thomas Matthews