Hi all,
is there a limit on the size that can be given to local variables? I think so..

In a dynamically-linked library function, I declared two local arrays, with a total size of 16kbyte, and the program crashes at a push instruction. A size of 4kbytes works without problems.
Anybody knows what's going on?
Thanks
John
Posted on 2004-05-29 09:46:13 by John Kiro
I think I know.
The stack will grow automatically when required.
The mechanism used for this is simple, but usually effective.
Namely, the first unallocated page (or pages) of memory after the stack is set to no-access. This is called a guard-page.
When it is accessed, an exception occurs, and the OS handles this, and allocates more memory to the stack.This is completely transparent to the user.
Your problem is probably that your arrays are so large, that you jump over the guardpage(s), and access memory that is not allocated, and the OS does not know that these should belong to the stack.
The thing with the stack is that it works from high addresses to low addresses. So when you create an array, the element at index 0 is at the 'furthest' address of the stack.
You could either fill the array back-to-front, so that you start from the allocated part, and move to the guardpage... or you could just access your array at 4k intervals (also back-to-front). Since a page is 4k, you will always hit the guard page this way.

Alternatively you could use some linker settings to create a larger stack.
Posted on 2004-05-29 10:04:24 by Scali
Yet another alternative is to dynamically allocate the arrays (perhaps not in the function itself).
Posted on 2004-05-29 10:09:25 by death
When working with a stack (which is where LOCALs are stored) that you know the size to which it will grow from equilibrium you are probably better off to commit the amount of stack space you use. The stack is handled in a way similar to virtual memory, that is there is a certain amount reserved and a portion of that committed. When the stack grows to beyond the committed value an exception occurs and the OS commits more memory from the reserve. This can slow down execution of your program and could lead to unhandled exceptions. There are 2 ways to take care of this, the first is to probe the stack on entry into the procedure and the second is to commit a large part of the reserved memory. By default most assemblers will reserve 1MB for the stack and commit 4KB,of which about 350 Bytes is the equilibrium point. If you are sure that you will be using more than this and know the approximate size of your stack you can reserve or commit more via a linking option. The stack is both committed and reserved in pages (4KB)

In MASM that is...

/STACK:reserve,commit >>> values in decimal bytes

In GoAsm

/StackSize reserve /StackInit commit
Posted on 2004-05-29 10:57:39 by donkey
Posted on 2004-05-29 11:29:42 by f0dder
Thanks for all these usefull infos..

Originally, I allocated the arrays dynamically outside that function. Then I tried to use stack variables instead, to minimize cache misses (according to Agner's pdf).

Next I'll try using the linker option that Donkey posted and compare performance to heap allocation.
Posted on 2004-05-30 07:28:54 by John Kiro