This is my first post here, and I am thankful to have found a board dedicated to assembly programming.

Say I have started a program, and have allocated x bytes to the stack.  Is there a limit on how much the stack can grow if more space is needed?

Also, is there a preference to using malloc over using the stack?

Thank you,

Posted on 2010-12-30 05:08:43 by Allasso
The stack size is handled by the OS.
In the case of Windows, you can specify the size of the stack in the PE header. This can be set with the /STACK linker option:

As you can see, you can reserve a maximum size, and commit a certain size at startup. The 'commit' means that the memory is actually allocated, where the reserved memory doesn't actually take up physical memory yet, it merely gives the OS a hint of how much the application may be using at some point.

There is a caveat with this scheme: Windows will automatically grow the stack (commit new memory as you run out of the currently committed range). It does this by marking the first uncommitted stack page as a 'guard page'. When you write to this page, an exception is triggered by the CPU's memory protection, and the OS handler will commit new memory to grow the stack of your process.
This can go wrong if you allocate very large ranges on the stack, and start writing beyond the guard page. On a stack this is quite easy to do. Namely, the stack starts at the highest address, and grows down. This means that if eg you allocate an array on the stack, element 0 of the array is the furthest away from the previous stack pointer value. So the guard page will sit at the end of the array, not at the start.
By writing values into the array back-to-front, you can trigger the guard pages and avoid a crash (pages are typically 4KB in size, so writing one element at every 4KB interval should be safe).

Which also indirectly answers your other question: when using large arrays, it may be easier to just use malloc(), as the heap is generally much larger than the 1 MB reserved stack space in a regular application, and the heap does not suffer from the problem of guard pages.
Another reason for using malloc() is that you can allocate the memory from within any function... The stack should be cleaned up after you exit a function (so that the calling function can access its stack variables properly again).
Posted on 2010-12-30 09:16:46 by Scali
Thank you for your reply.  The information is helpful, although I use a Unix box.
Posted on 2011-01-01 11:41:05 by Allasso
Unix (Linux, at least) does it the same way. I'd suspected Windows used the same "guard page" mechanism, but wasn't sure until I read Scali's explanation. Thanks Scali! Probably a good "general rule" to use malloc if you need more than 4K.


Posted on 2011-01-01 15:35:18 by fbkotler