www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - os_query_stackBottom() how does it work?

reply Chad J <""gamerChad\" spamIsBad gmail.com"> writes:
I've run into this while trying to port GPhobos to the arm-wince 
(PocketPC) platform.  Never mind that it's GPhobos though, it's the same 
function in dmd Phobos, Ares too.

It looks like this:

/**********************************************
  * Determine "bottom" of stack (actually the top on Win32 systems).
  */

void *os_query_stackBottom()
{
     asm
     {
	naked			;
	mov	EAX,FS:4	;
	ret			;
     }
}

I hit it while compiling std/thread.d, but I've also found it in 
internal/gc/win32.d.

I'm wondering how to do this without using assembly, or if assembly is 
necessary then how I might do it in ARM assembly.  I'd probably be on my 
way just to have some background knowledge about this though.  Knowledge 
like, what exactly is the stack bottom?  Is it the place you reach when 
you run out of stack memory or when you first start using the stack? 
Something else?  At least a link to some info would help.

It would be better though if someone knew how to do this using 
Win32/WinCE programming, and could show me that.

Google hasn't helped me much in determining how that code works, but it 
did yield some possibly useful information about WinCE memory architecture:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcemain4/html/_wcesdk_Windows_CE_Memory_Architecture.asp
clicking "stack" at the bottom of that page leads to:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcemain4/html/_wcesdk_the_stack.asp
This might also help:
http://blogs.msdn.com/kitlfirst/
searching WinCE API for "CreateThread" found in above article yields:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wcesdkr/html/wce30oriWindowsCE30APIReference.asp

Anyhow I might be able to improvise something using info from those 
links, but I am not sure what's happening on the Phobos side of things. 
  Please help.
May 07 2006
next sibling parent reply =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
Chad J > wrote:

 I've run into this while trying to port GPhobos to the arm-wince 
 (PocketPC) platform.  Never mind that it's GPhobos though, it's the same 
 function in dmd Phobos, Ares too.

You'll notice that that the os_query_stackBottom function is in a version(Win32) conditional compilation block. There are alternative versions of it in: internal/gc/gclinux.d and internal/gc/gcgcc.d Maybe one of those will help you ? --anders
May 07 2006
parent Chad J <""gamerChad\" spamIsBad gmail.com"> writes:
Anders F Björklund wrote:
 
 You'll notice that that the os_query_stackBottom function is in a 
 version(Win32) conditional compilation block. There are alternative 
 versions of it in: internal/gc/gclinux.d and internal/gc/gcgcc.d
 
 Maybe one of those will help you ?
 
 --anders

Well, the one from gcgcc.d made it compile. Hopefully it works at runtime! Thanks for the help.
May 08 2006
prev sibling parent reply mclysenk mtu.edu writes:
In article <e3mf16$1g83$1 digitaldaemon.com>, Chad J says...
/**********************************************
  * Determine "bottom" of stack (actually the top on Win32 systems).
  */

void *os_query_stackBottom()
{
     asm
     {
	naked			;
	mov	EAX,FS:4	;
	ret			;
     }
}

That snippet of code is pulling out the bottom of the stack from the Thread Execution Block (TEB). The TEB is stored in process' memory and is also mirrored in the FS segment. FS:0 is the top of the structured exception handler chain, FS:4 is the bottom of the stack and FS:8 is the top of the stack. As for Windows CE, you'll probably have to do some snooping on your own. The MSDN would probably be a good place to start.
May 08 2006
parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
mclysenk mtu.edu wrote:
 In article <e3mf16$1g83$1 digitaldaemon.com>, Chad J says...
 /**********************************************
  * Determine "bottom" of stack (actually the top on Win32 systems).
  */

 void *os_query_stackBottom()
 {
     asm
     {
 	naked			;
 	mov	EAX,FS:4	;
 	ret			;
     }
 }

That snippet of code is pulling out the bottom of the stack from the Thread Execution Block (TEB). The TEB is stored in process' memory and is also mirrored in the FS segment. FS:0 is the top of the structured exception handler chain, FS:4 is the bottom of the stack and FS:8 is the top of the stack.

Isn't the bottom of the stack the same as ESP? If so, couldn't the code be replaced by something like void* bla(){ int x; return &x; } or using alloca or something? I suppose it's the GC that needs the stack bottom/top, but why would it be interested in anything before ESP? L.
May 08 2006
parent reply mclysenk mtu.edu writes:
In article <e3njs0$l4i$1 digitaldaemon.com>, Lionello Lunesu says...
mclysenk mtu.edu wrote:
 In article <e3mf16$1g83$1 digitaldaemon.com>, Chad J says...
 /**********************************************
  * Determine "bottom" of stack (actually the top on Win32 systems).
  */

 void *os_query_stackBottom()
 {
     asm
     {
 	naked			;
 	mov	EAX,FS:4	;
 	ret			;
     }
 }

That snippet of code is pulling out the bottom of the stack from the Thread Execution Block (TEB). The TEB is stored in process' memory and is also mirrored in the FS segment. FS:0 is the top of the structured exception handler chain, FS:4 is the bottom of the stack and FS:8 is the top of the stack.

Isn't the bottom of the stack the same as ESP? If so, couldn't the code be replaced by something like void* bla(){ int x; return &x; } or using alloca or something? I suppose it's the GC that needs the stack bottom/top, but why would it be interested in anything before ESP? L.

I think there's some confusion with the notation that the GC uses. Internally the stack bottom is the higher address while the stack top is the lower address or the stack pointer. This is a bit confusing at first, but it makes sense given that the stack grows downwards. In order for the GC to mark the entire stack used by the program, it needs the stack pointer for the start of the range and the stack bottom for the end. -Mik
May 08 2006
parent reply Chad J <""gamerChad\" spamIsBad gmail.com"> writes:
mclysenk mtu.edu wrote:
 
 I think there's some confusion with the notation that the GC uses.  Internally
 the stack bottom is the higher address while the stack top is the lower address
 or the stack pointer.  This is a bit confusing at first, but it makes sense
 given that the stack grows downwards.  In order for the GC to mark the entire
 stack used by the program, it needs the stack pointer for the start of the
range
 and the stack bottom for the end.
 
 -Mik
 
 

Interesting. Maybe when that thread/stack is started then the GC could store that address somewhere. Then when it needs the stack "bottom", it could just grab that value. Problem there I see is if the stack gets moved, but I think there is a WinCE function that handles that, allowing you to set a callback that will be used if the stack is moved or something. If such a thing would work it's probably more efficient than the "guess" method that I expect it to use as is. Either that or I'm too much of a newb and don't really understand this stuff. Anyhow those are my thoughts.
May 08 2006
parent Sean Kelly <sean f4.ca> writes:
Chad J > wrote:
 
 Interesting.  Maybe when that thread/stack is started then the GC could 
 store that address somewhere.  Then when it needs the stack "bottom", it 
 could just grab that value.

This is basically what it does. Check std.thread.thread_init. Sean
May 09 2006