News:

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

Local byte declaration

Started by Webring, June 21, 2005, 05:08:19 PM

Previous topic - Next topic

Webring

I was just curious why the follow doesn't work(makes app just exit silently)

test proc
LOCAL one[2000]:byte
LOCAL two[2000]:byte
LOCAL three[2000]:byte
LOCAL four[2000]:byte
LOCAL five[2000]:byte
LOCAL six[2000]:byte
LOCAL seven[2000]:byte
invoke MessageBox,0,SADD("test"),NULL,MB_OK
ret
test endp


yet the following works

test proc
LOCAL one[2000]:byte,two,three,four,five,six,seven
invoke MessageBox,0,SADD("test"),NULL,MB_OK
ret
test endp

Jeff

just a hunch, but i think you ran out of stack space trying to create 14000 bytes of local memory.  you could try reserving more stack space using .STACK 32768.  however, i do not know the absolute limit for variable sizes.  i do however know that you cannot have a single variable one million bytes big.  ;)

thomasantony

Hi,

LOCAL one[2000]:byte,two,three,four,five,six,seven

    I think in the second case, you only get the ONE var in 2000 bytes and the rest are DWORDS.
So it takes only 2024 bytes. The other one takes 14000 bytes.

Thomas :U
There are 10 types of people in the world. Those who understand binary and those who don't.


Programmer's Directory. Submit for free

chep

This is a typical stack probing problem.

I just saw that MASM allows us to write custom PROLOGUE/EPILOGUE macros so I'm starting to work on a stack probe macro.
Hopefully it may be ready soon... ::)

farrier

It is a GOOD day to code!
Some assembly required!
ASM me!
With every mistake, we must surely be learning. (George...Bush)

chep

Here is a draft of a PROLOGUE macro that takes care of everything for you :
http://www.masmforum.com/simple/index.php?topic=2011.msg15878#msg15878

Jeff

if it wouldnt be too much trouble, could someone explain the idea (in detail) of stack probing or point me in the right direction as to where to find info?  looking at the code found in the "old forum", i cant quite picture what is going on.  i see that the EBP register gets zeroed out but thats about it.

chep

Hmmm... details won't be 100% exact but at least you'll get the main idea...

Windows only *reserves* the stack memory, it doesn't commit it fully at program startup.
This means that past the top of the stack (or should I say the bottom, I never know, well past the lower addresses :toothy) there is uncommitted memory that generates a GPF if you try to access it.
To allow the stack to "grow" automatically, the first uncommitted page is turned by Windows into a guard page, so that whenever this page is touched, Windows can commit it and make the next uncommitted page the guard page.

Roughly :

  Higher addresses
+------------------+ <-- Start of stack
|  Committed page  |
+------------------+
|  Committed page  |
+------------------+
|  Committed page  | <-- ESP in this page
+------------------+
|    Guard page    |
+------------------+
| Uncommitted page |
+------------------+
| Uncommitted page |
+------------------+
| Uncommitted page |
+------------------+ <-- End of stack
  Lower addresses


In the figure above, if you move ESP down by less than 4kb (a page size), no problem as it will be pointing to the guard page. The next access to the stack memory will trigger Windows "auto-stack-growing" feature, ie the guard page will be committed and the next uncommitted page becomes the guard page.

But if you move ESP down by more than 4kb, it will be pointing to an uncommited memory area. Thus the next access will generate a GPF, and as it occurs on the stack Windows gets scared and kills your application silently (just like if you had exhausted the whole stack memory).


The idea behing "stack probing" is : never decrement ESP by more than 4kb at a time without first dirtying the guard page.

So to allocate 8kb of stack space, you should use the following method :

sub esp, 4096
mov dword ptr [esp], 0 ; dirty the guard page
sub esp, 4096
mov dword ptr [esp], 0
; etc if you need to allocate more stack memory


Hope I am clear enough!

Jeff

so its kinda like this?

at (multiples of) 4096 bytes (a page) below the current esp or ebp locations contains a 'bouncer' saying, "HEY! YOU'RE NOT GETTING PASSED ME!"  i kill the 'bouncer' so im free to roam around this area.

or

the 'bouncers' are only pages away from the first committed page (at each line in your diagram).  (tho as far as i can see, this contradicts the example code)

or

i am not getting it.  :D


(i hope that was a good analogy) :U

chep

In fact the "bouncer" is the *whole* guard page. Any address in the guard page triggers the "auto-grow" feature.
Whenever you "kill" the bouncer page you're free to roam around the newly committed page, and the bouncer "resurrects" into the next uncommited page.

Good analogy BTW :U

Jeff

oh so the guard pages only watch the esp/ebp registers to see if they ever pass to produce the GPFs.  then, if any memory location is accessed or modified in the guard's "follower", the follower is "promoted" to guard and the former guard becomes "brainwashed" follow to the cause of the program.  :D


thanks for the explanation chep.

chep

"brainwashed"... LOL! :U


Just a little comment for the sake of completeness. (If I misunderstood you and just say exactly what you said just ignore me, I don't always perfectly understand english :wink)

Quote from: Jeff on June 22, 2005, 09:03:41 AM
oh so the guard pages only watch the esp/ebp registers to see if they ever pass to produce the GPFs.
the esp/ebp registers are not watched, the trigger only occurs when the memory is really accessed (by a mov, push, ...)

Quote from: Jeff on June 22, 2005, 09:03:41 AM
then, if any memory location is accessed or modified in the guard's "follower", the follower is "promoted" to guard and the former guard becomes "brainwashed" follow to the cause of the program. :D
I would say : "if any memory location is accessed or modified in the guard page itself, ..."


Well, that was 2 comments in fact. Never mind :toothy

Jeff

  Higher addresses
+------------------+ <-- Start of stack
|  Committed page  |
+------------------+
|  Committed page  |
+------------------+
|  Committed page  | <-- ESP in this page
+------------------+
|    Guard page    |
+------------------+
| Uncommitted page |
+------------------+
| Uncommitted page |
+------------------+
| Uncommitted page |
+------------------+ <-- End of stack
  Lower addresses
sub esp,4096...

oh hah ok.  thats what i had thought at first but then i looked at the diagram wierd thinking esp/ebp was in the guard page and changed it.  :green

damn i have a grammar error in that post (evidence of the change :wink )

Momoass

14000Bytes, the default stack is not enough.
you must change the stack size of the linker option.