Thread: How to calculate the Stack Size?

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    83

    How to calculate the Stack Size?

    Dear All,
    I want calculate the used Stack Size..till now i did like this..my processor
    assume my processor stack size is 8k bytes...

    Code:
    #include<stdio.h>
    void main()
    {
       int m=0, n=0, sum=0;
       sum=m+n;
       printf("%d", sum);
       return 0;
    }
    since i have three local variables stack consumed is 3 bytes so remaining stack size is=8k-3 bytes=1021 bytes
    Am i right?

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    The size of int is probably 4 (or perhaps 2), so three of those is 12 bytes (possibly 6).

    However, in a traditional system, main is not the first thing on the stack, so there would be a few other things, and main itself will use some space on the stack - probably at least 2 integer sizes (8 or 4 bytes depending on size of integer).

    And of course, calling printf will take one pointer (to the format string) and one integer space on the stack. Pointers are commonly 4 bytes, but may also be 2 or 8 bytes, depending on the type of processor (and perhaps also the settings in the system).

    8KB is 8192 bytes, by the way. I've never heard of anyone counting stack size in bits, as most processors aren't capable of addressing 1 bit, but does it in bytes.

    In summary, it is not entirely trivial to calculate the exact stack-size of a function. You could have a look at the assembler code - it will start by pusihing one or two registers onto the stack, then subtract something from the current stack pointer.



    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Define main() as returning an int.

    You're wrong on your calculations, but the answer is dependent upon what architecture you're writing this for. An int is generally 32-bits (4 bytes), which means 4*3 = 12 bytes. Also, your functions, when they are called, take up space on the stack in terms of the setup and return code as well as any passed variables. So in general you're using more than just your local variables.

    Edit: Beaten again.

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    83

    Thanks for useful information...

    Quote Originally Posted by matsp View Post
    The size of int is probably 4 (or perhaps 2), so three of those is 12 bytes (possibly 6).

    However, in a traditional system, main is not the first thing on the stack, so there would be a few other things, and main itself will use some space on the stack - probably at least 2 integer sizes (8 or 4 bytes depending on size of integer).

    And of course, calling printf will take one pointer (to the format string) and one integer space on the stack. Pointers are commonly 4 bytes, but may also be 2 or 8 bytes, depending on the type of processor (and perhaps also the settings in the system).

    8KB is 8192 bytes, by the way. I've never heard of anyone counting stack size in bits, as most processors aren't capable of addressing 1 bit, but does it in bytes.

    In summary, it is not entirely trivial to calculate the exact stack-size of a function. You could have a look at the assembler code - it will start by pusihing one or two registers onto the stack, then subtract something from the current stack pointer.



    --
    Mats
    Whatever you explained is only for main function..if i have functions in main..i mean every function call take how many stack bytes....Example

    Code:
    #include<stdio.h>
    int add(int, int);
    void main()
    {
        int m=10,n=20;              /* it will take 2 *4 =8 bytes
        printf("%d", add(m,n)); / * printf will take 4 bytes+ function call will take 2 bytes to store add
    }
    
    int add(int x, int y)
    {
       return (x+y); 
    }
    8k=8*1024=8192-(8+6)=8178 bytes remaining..Am i right?

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You're wrong. Each int may take 4 bytes (this varies from system to system).
    So 2 * 4 = 8.
    Printf takes a pointer to const char*, so that probably makes it 12, and then there's the value returned from add, which is int, which probably adds up to 16 bytes.

    Check sizeof(int) and sizeof(const char*), and also remember that there may be stuff on the stack prior to main.
    And main returns int, for gods' sakes. Listen to people.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    You can estimate, but the bigger your little program gets the more inaccurate you'll get.

    Don't forget, depending on the arch (and/or assembler) procedure calls may also go on the stack. If you want to get close, generate the assembly for your program and read through it (and count anything that modifies the stack). There could be a better way however...

    Code:
    #include<stdio.h>
    
    int add(int, int);
    
    int main()
    {
        int m=10,n=20;              /* it will take 2 *4 =8 bytes */
        printf("&#37;d", add(m,n)); / * printf will take 4 bytes+ function call will take 2 bytes to store add */
    
        return 0;
    }
    
    int add(int x, int y)
    {
       return (x+y); 
    }
    Last edited by zacs7; 06-24-2008 at 04:46 AM.

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Again, it depends on the size of integer.

    I compiled this using gcc-mingw:
    Code:
    #include<stdio.h>
    
    int add(int, int);
    
    int main()
    {
      int m=10,n=20;              /* it will take 2 *4 =8 bytes */
      printf("%d", add(m,n));
     /* printf will take 4 bytes+ function call will take 2 bytes to store add */
      return 0;
    }
    
    int add(int x, int y)
    {
       return (x+y); 
    }
    The essense of the call inside main is (T= means total usage):
    Code:
    	pushl	%ebp    // 4 bytes. T=4
    	movl	%esp, %ebp
    	subl	$24, %esp    // This uses 24 bytes.  T=28
    ...
    	movl	$10, -4(%ebp)
    	movl	$20, -8(%ebp)
    	movl	-8(%ebp), %eax
    	movl	%eax, 4(%esp)
    	movl	-4(%ebp), %eax
    	movl	%eax, (%esp)
    	call	_add             // 4 bytes. T=32
    	movl	%eax, 4(%esp)
    	movl	$LC0, (%esp) // 4 Bytes. T=32
    	call	_printf            // 4 btyes. T=36
    	movl	$0, %eax
    ...
    _add:
    	pushl	%ebp    // 4 bytes, T = 36
    	movl	%esp, %ebp
    	movl	12(%ebp), %eax
    	addl	8(%ebp), %eax
    	popl	%ebp          // -4 bytes. T = 32
    	ret                       // -4 bytes. T = 28
    ...
    If you want to know exactly, you must look at (and understand) the assembler code generated by the compiler. Note that the compiler may not restore the stack-pointer immediately after a call - as seen above.

    There is another way: Fill the stack with a certeain pattern. We can do that in main, for example (but we do need to know how large the stack is or things can go REALLY badly quickly)

    I will post some code later on to show that.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Yikes. AT&T syntax. Run for the hills!!!!!!!!!!!!

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Yikes. AT&T syntax. Run for the hills!!!!!!!!!!!!



    unfortunately, for those who prefer the intel syntax, there aren't many options for converting C to x86 assembly (I can only think of one off the top of my head: borland). all of the GNU tools use the AT&T syntax.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    unfortunately, for those who prefer the intel syntax, there aren't many options for converting C to x86 assembly (I can only think of one off the top of my head: borland). all of the GNU tools use the AT&T syntax.
    There is a utility out there that readily converts between formats. I used it way back in my DJGPP and NASM days. However that was a long time ago and have since lost the link (due to several formats - thanks, Bill) but I'm sure it's still around.

    I used it inside of RHIDE with DJGPP and it would handle both inline assembly and pure assembly modules. So nice.

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Sebastiani View Post
    >> Yikes. AT&T syntax. Run for the hills!!!!!!!!!!!!



    unfortunately, for those who prefer the intel syntax, there aren't many options for converting C to x86 assembly (I can only think of one off the top of my head: borland). all of the GNU tools use the AT&T syntax.
    And Microsoft and the Intel compilers use Intel syntax... quite the paradox.
    AT&T syntax is evil!
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #12
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    I did an experiment not too long ago to try to get a handle on how the stack was laid out for any given program. I didn't get too far, but I did realize that one can use printf with the &#37;p formatting option on any function address or (obviously) stack variable to see some "wheres" and "whyfors" of layout.

    Sorta like this:

    Code:
    #include<stdio.h>
    
    int add(int, int);
    
    int main()
    {
    	int m, n ; 
    	printf("variable m is at address %p\n", &m );
    	printf("variable n is at address %p\n", &n );
    
    	printf("function main() is at address %p\n", main );
    	printf("function add() is at address %p\n", add );	
    	printf("function printf() is at address %p\n", printf );
    	return 0;
    }
    
    int add(int x, int y)
    {
       return (x+y); 
    }
    Todd
    Mainframe assembler programmer by trade. C coder when I can.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Appologies for the publishing of AT&T style assembler code. Since I only have easy access to gcc, that's what I have available. [Although I think there is an option to output intel syntax from gcc, I was not able to find it when I was looking a few minutes ago].

    Anyways, as promised but a bit late:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define STACKSIZE 8192
    #define RESERVE_BOT 64
    #define RESERVE_TOP 256
    #define FILLSIZE (STACKSIZE - (RESERVE_BOT + RESERVE_TOP))
    #define FILLPAT 0xCC
    
    void check_stack_use(unsigned char *spbot)
    {
        unsigned char *sptop = spbot - FILLSIZE;
        unsigned char *sp = sptop;
        ptrdiff_t size_remaining;
    
        sp = sptop;
        while(*sp == FILLPAT && sp != spbot) sp++;
    
        size_remaining = sp - sptop;
        printf("Stack used up to &#37;p, used %d bytes, remaining %d\n", (void *)sp, 
    	   FILLSIZE-size_remaining, size_remaining);
    }
    
    int main()
    {
        int x;  // This can be ANY local variable.
        unsigned char *sp;
        // We rely on the stack growing towards zero. 
        sp = (unsigned char *)&x;
        sp -= (RESERVE_TOP);
        printf("sp = %p, %p\n", sp, sp-FILLSIZE);
        memset(sp-FILLSIZE, FILLPAT, FILLSIZE);
        check_stack_use(sp);
        printf("Hello, world (%p)\n", (void *)sp);
        check_stack_use(sp);
        return 0;
    }
    Edit: Updated code, removed the second parameter of the check_stack_use().

    --
    Mats
    Last edited by matsp; 06-25-2008 at 03:25 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  14. #14
    Registered User
    Join Date
    Apr 2008
    Posts
    83

    Logic to develop the code for finding stack size?

    Dear All,

    I Have Complex code in my project..i have to calculate the algorithm for that...i am trying to develop C program for that..Any body know the logic how can implement this?

  15. #15
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    We just told you. No. We gave you approximations to use. That's about it. The best thing you could technically try is matsp's code.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Stack Implementation and Exceptions
    By audinue in forum C Programming
    Replies: 4
    Last Post: 06-22-2008, 09:32 AM
  2. Error with a vector
    By Tropicalia in forum C++ Programming
    Replies: 20
    Last Post: 09-28-2006, 07:45 PM
  3. stack and pointer problem
    By ramaadhitia in forum C Programming
    Replies: 2
    Last Post: 09-11-2006, 11:41 PM
  4. Invalid conversion from 'void*' to 'BYTE' help
    By bikr692002 in forum C++ Programming
    Replies: 9
    Last Post: 02-22-2006, 11:27 AM
  5. Replies: 11
    Last Post: 03-25-2003, 05:13 PM