Here is some sample code demonstrating my problem:
.DATA
TESTTYPE2 STRUCT
X1 BYTE ?
X2 BYTE ?
Y WORD 3 DUP (?)
Z SDWORD 6 * 6 DUP (?)
TESTTYPE2 ENDS
TESTTYPE3 STRUCT
X1 BYTE ?
X2 BYTE ?
;TT2 TESTTYPE2 70 DUP (<>) ; -> runs
TT2 TESTTYPE2 75 DUP (<>) ; -> GPF
TESTTYPE3 ENDS
.CODE
Start PROC
LOCAL L_TT2:TESTTYPE2
LOCAL L_TT3:TESTTYPE3
CLD
XOR EAX, EAX ;set L_TT3 to zero ...
MOV ECX, SIZEOF(TESTTYPE3)
LEA EDI, L_TT3
REP STOSB ;GPF here, if any
int 3
RET
Start ENDP
END Start
the debugger shows a size of 0x2C8A (= 11402 bytes) for L_TT3, which causes an access violation at "REP STOSB". Reducing the size of TESTTYPE3 makes this go away.
REP STOSB writes to stack memory (i.e. zeros TESTTYPE3). According to the PE header 1MB of stack memory is reserved and initially 4KB committed, so this should be more than sufficient - but for some reason it isn´t!
A size of about 11000 bytes makes it crash, a size of about 10000 bytes is acceptable (strange enough the exact size, from which on it crashes, seems to vary from run to run). 10000 is more than 4K, so there must have been committed more stack memory than these initial 4K, but when it comes to 11000 it keeps crashing.
As already mentioned i could add /STACK:0x100000,0x100000 to the linker options, which always commits 1MB to the stack (even if it is not needed). But looking at other executables i almost every time see the defaults (1MB reserved and 4KB committed), which obviously work there. Why does my executable not work with these defaults?