News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Lowest possible stack address

Started by jj2007, December 16, 2010, 08:01:59 PM

Previous topic - Next topic

dedndave


Antariy

Quote from: jj2007 on December 17, 2010, 01:44:28 AM
Yes I looked but your assumption is incompatible with my test results.

This is not assumption.

jj2007

Microsoft support:
QuoteThis is implemented by placing a page with PAGE_GUARD access at the end of the current stack. When your code causes the stack pointer to point to an address on this page, an exception occurs. The system then does the three following things:

   1. Remove the PAGE_GUARD protection on the guard page, so that the thread can read and write data to the memory.
   2. Allocate a new guard page that is located one page below the last one.
   3. Rerun the instruction that raised the exception.

In this way, the system can grow the stack for your thread automatically. Each thread in a process has a maximum stack size. The stack size is set at compile time by the /STACK:reserve[,commit] linker switch, or by the STACKSIZE statement in the .def file for the project. When this maximum stack size is exceeded, the system does the three following things:

    * Remove the PAGE_GUARD protection on the guard page, as described earlier.
    * Try to allocate a new guard page below the last one. However, this fails because the maximum stack size has been exceeded.
    * Raise an exception, so that the thread can handle it in the exception block.

Complete code (already posted above):
include \masm32\include\masm32rt.inc

.code
start:
mov ebx, esp
print hex$(ebx), 9, " stack on entry", 13, 10
xor edi, edi
.Repeat
push eax
add edi, 4
.Until esp<=33000h ; decimal 208896
xchg esp, ebx
print hex$(edi), 9, " bytes of stack available", 13, 10
ASSUME fs:NOTHING
mov eax, fs:[4]
print hex$(eax), 9, " top of the stack", 13, 10
ASSUME fs:ERROR
print hex$(ebx), 9, " lowest possible stack without crashing", 13, 10
mov eax, 100000h ; 1 MB
sub eax, edi
inkey hex$(eax), 9, " difference to 1 MB"
exit
end start

Antariy

Quote from: dedndave on December 17, 2010, 01:51:29 AM
in the first post, Alex   :U

Oh... Why nobody never read my posts carefully. Did not you see that I have suggested method of determination, and Jochen is not posted code with incorporated suggestion?

Antariy

Quote from: jj2007 on December 17, 2010, 01:57:22 AM
Complete code (already posted above):

No need in MS's quatations.

Code is not right.

The same question as in my previous post... :( :( :(

Right code is:

mov eax, fs:[4]
sub eax,1024*1024


EAX - is the lowest possible address for current thread stack. But this address is not commited usually, since app doesn't go to the last page.

I.e. somewhere in the code:

mov eax, fs:[4]
sub eax,1024*1024
cmp esp,eax
jz @WeCannotPushAnyMore
push etc.


jj2007

Alex,

Try running my post with linker option /stack:0
You will see that top of stack is 70000h (not zero, surprise surprise... :wink), but lowest possible address is again 33000h. The system tries to protect the memory below 33000h, it doesn't care how much stack you wanted. You get roughly what you wanted, but very roughly.

Antariy

Quote from: jj2007 on December 17, 2010, 02:08:18 AM
And instead of whining that nobody reads your posts, start testing the code.

Jochen, I take offence at this point. If you think that I have posted anything just for nothing - this is your problems.

Your code is not supposed to do real testing. Each page of stack, which lies below current, is guarded. Access to that page make access violation, but this is intentionally to do stack allocation by pieces. Page accessed stand commited. But the same last page cannot be commited - it is the last page.

Your code is not do reliable overflowing, since you limit it, and your constants can vary.

Antariy

Now I'll try to make testing plan, even if this is not time for this, and this is very pity to me, that you didn't trust to me.

jj2007

Quote from: Antariy on December 17, 2010, 02:12:40 AM
Your code is not do reliable overflowing, since you limit it, and your constants can vary.

Perhaps you should read my posts carefully:
Try replacing esp<=33000h with esp<33000h...

Antariy

In Ollys Options->Exceptions. Select "Memory Access Violation" Checkbox at "Ignore..." section.

Now, compile this code, and run it in olly.

Press F9. Then Press F9 again. Now in dump window go to the ESP value.

For me, I get

00030000 - would be the lowest address


and current ESP value - 00031000. It is different for 1000h - one page size. The last page is totally unaccesible. And this is end of the stack.

Q.E.D.


include \masm32\include\masm32rt.inc

.code
start:

ASSUME fs:NOTHING
mov eax, fs:[4]
sub eax,1024*1024
print hex$(eax)," - would be the lowest address",13,10

@@:
push eax
jmp @B
end start



jj2007

Which OS? For mine (XP SP3) the value is 33000h.

0012FFC4         stack on entry
000FCFC4         bytes of stack truely available (relative to entry stack)
00130000         top of the stack
00030000         lowest possible address according to Alex
00033000         lowest possible stack according to my computer
0000303C         difference 1 MB minus truely available stack

Antariy

Quote from: jj2007 on December 17, 2010, 02:34:43 AM
Which OS? For mine (XP SP3) the value is 33000h.

Compile code which I write. Only will show true end of the stack. Do things which I explain in previous post when running that code.

You should not rely on ESP value, initial or final or between - it is different for each OS, and for each thread.

Antariy

Quote from: jj2007 on December 17, 2010, 02:34:43 AM
Which OS? For mine (XP SP3) the value is 33000h.


00030000         lowest possible address according to Alex
00033000         lowest possible stack according to my computer


Difference is 3000h - 3 pages, 12 KB. Latest guard pages are signalled you that the end of the stack is close. But next 2 pages are awailable, too. So, latest accessible address is 31000, 30000 - is lowest possible address, but this page (30000-30FFF) is not accessible.

jj2007

Not on my PC. But even if it was, why should an app crash into the last two pages, requiring an exception handler? And how should that exception handler know that the end is near???

Complete code again - the exe must be run from a commandline if TestVal=0.

My output for TestVal=0:
0012FFC4         stack on entry
00033024
00033020
0003301C
00033018
00033014
00033010
0003300C
00033008
00033004
00033000

... and there it stops.

Antariy

Quote from: jj2007 on December 17, 2010, 02:49:08 AM
Not on my PC. But even if it was, why should an app crash into the last two pages, requiring an exception handler? And how should that exception handler know that the end is near???

Complete code again - the exe must be run from a commandline if TestVal=0.


Jochen, you calculate difference not right. Difference is thing between "my" stack end, and "your" stack end.

Please, try code which I suggested. If you want to find the end of the stack, you shoud go to its end, any "hypotetical" calculations is not right.

Why not run the code which I have suggested as test? Just follow to my way of testing. And I say this not because "my way" is tricky and good for me, but because it is only one reliable way.