Page 1 of 2
using stack...
Posted: Sun Mar 21, 2004 7:26 am
by Silverhawk
Hello, I've some problems with stack...
Is there any body who knows a good tutorial on the subjet ?
- what is the aim of a stack
- how many stacks should my OS own ?
- what should be their size ?
thanks.
Re:using stack...
Posted: Sun Mar 21, 2004 7:39 am
by Tim
There are lots of places where the word 'stack' can be used, but I assume you're talking about the stack that SS and ESP point to.
Silverhawk wrote:
- what is the aim of a stack
To keep things on

. You can push an item onto the top of a stack, then later pop it off again. C passes parameters this way: when a function is called, each parameter is pushed onto the stack and retrieved by the function itself.
- how many stacks should my OS own ?
At least one per thread. You'll usually have one user-mode stack and one kernel-mode stack per thread.
- what should be their size ?
As big as they need to be. 4096 bytes might be enough for kernel mode. In user mode, you'll want a stack which expands automatically: allocate 4KB to begin with and leave the page underneath the stack not present. When the stack grows beyond 4KB, it will trigger a page fault. Then you can allocate another 4KB, map that page, and leave the next page not present -- and so on.
Re:using stack...
Posted: Sun Mar 21, 2004 8:04 am
by Silverhawk
Thank for these precisions tim...
How can I implement a stack ? (a kernel stack for instance ?)
Do I need to have a stack segment descriptor in the gdt ?
Re:using stack...
Posted: Sun Mar 21, 2004 8:55 am
by Ozguxxx
How can I implement a stack ? (a kernel stack for instance ?)
You will need a valid segment data selector to set value of ss and some valid pointer to top of your stack to set value of esp. People set stack segment same as data segment for simplicity and also I think gcc expects stack segment base and data segment base to be mapped onto same place. Is that right?
Do I need to have a stack segment descriptor in the gdt ?
Yes you can have, but not necessarily since you can set stack segment selector same as your data segment selector. You can use your data segment as a stack segment.
Re:using stack...
Posted: Sun Mar 21, 2004 12:32 pm
by Silverhawk
Thank for your advice Ozgunh82 !
I'll try to use what I've learnt...
Re:using stack...
Posted: Sun Mar 21, 2004 3:33 pm
by Neo
I havent started multitaksing etc as yet so have a few questions.
Tim Robinson wrote:
- how many stacks should my OS own ?
At least one per thread. You'll usually have one user-mode stack and one kernel-mode stack per thread.
Why does each thread require a kernel stack? isn't just one enough in the kernel space?
- what should be their size ?
As big as they need to be. 4096 bytes might be enough for kernel mode. In user mode, you'll want a stack which expands automatically: allocate 4KB to begin with and leave the page underneath the stack not present. When the stack grows beyond 4KB, it will trigger a page fault. Then you can allocate another 4KB, map that page, and leave the next page not present -- and so on.
how do you leave pages 'under' the stack? do you mean to say that you leave some pages between the code/data section pages and the stack pages? if so how much space? if not then how do you do this?
Re:using stack...
Posted: Sun Mar 21, 2004 3:42 pm
by Candy
Neo wrote:
Tim Robinson wrote:
At least one per thread. You'll usually have one user-mode stack and one kernel-mode stack per thread.
Why does each thread require a kernel stack? isn't just one enough in the kernel space?
No, in any sort of decent design. If you want one kernel stack, it has to be left in the same position in any case, so your entire kernel may not be preemtible in any point and no kernel space thread can exist. That's really bad design.
As big as they need to be. 4096 bytes might be enough for kernel mode. In user mode, you'll want a stack which expands automatically: allocate 4KB to begin with and leave the page underneath the stack not present. When the stack grows beyond 4KB, it will trigger a page fault. Then you can allocate another 4KB, map that page, and leave the next page not present -- and so on.
how do you leave pages 'under' the stack? do you mean to say that you leave some pages between the code/data section pages and the stack pages? if so how much space? if not then how do you do this?
Pages under the stack : the stack grows down. They're in normal logic ahead of the stack, and not mapped. When you detect a write in the page just below the stack, assume the stack grew and increase its size. If it goes overboard (say, 1M), kill the thread. End of story.
Note, use guard pages.
Note2: Do NOT naturally align the stacks if you want to use HyperThreading, they are so stupid to use a 1-way or 2-way L1 cache, so if they both map to the same 64k-aligned address you start thrashing. (alignment: if the address of both & 0xFFFF is the same, it is wrong).
Re:using stack...
Posted: Wed Mar 24, 2004 5:05 am
by tom1000000
Hi,
If you have multiple threads, don't they all require different virtual addresses for their stacks? (Since they all use exactly the same address space.)
If all stacks have to reserve a fixed range of virtual addresses, what size should the stacks be? 1MB each? 64K each? How does BSD / Linux / Windows determine max stack size for multiple threads?
Re:using stack...
Posted: Wed Mar 24, 2004 6:41 am
by Pype.Clicker
there's no perfect solution in mainstream OSes to this problem, afaik. The stack's size is to be defined by the thread creator (thus specified by the application programmer) or it will have a default size (typically a few MB for every new thread).
I'm investigating a possible solution, based on some article about segmented stacks (which i cannot find back right now), for Clicker ...
Re:using stack...
Posted: Wed Mar 24, 2004 6:53 am
by Candy
Pype.Clicker wrote:
I'm investigating a possible solution, based on some article about segmented stacks (which i cannot find back right now), for Clicker ...
If that is what I think it is then it won't work.
I think you mean having multiple stacks that overlap with one stack being swapped out as another passes through that area.
If so, think about a thread holding a mutex, and a second thread that's not giving it away. You might be able to solve those problems but I doubt it's worth it.
Re:using stack...
Posted: Wed Mar 24, 2004 7:00 am
by Pype.Clicker
no, it doesn't look like this... it's just based on the fact that the whole stack do not actually need to be made of linearily consecutive addresses. With proper guards and mapping, it is (should be) possible to allocate some *new* place to extend a too large stack, mapping the top of the current stack as the bottom of the previous one and deviate the stack pointer so that the application notices nothing ...
i'll write a
teacup about that when i'll get a couple of free hours, but i cannot decently do *that* at work

Re:using stack...
Posted: Wed Mar 24, 2004 7:23 am
by Candy
Hmmmm... ok, that's a nice idea, but I do think you have problems with alloca(32k) and stuff like that. How do you guard against a huge alloca?
Re:using stack...
Posted: Wed Mar 24, 2004 7:56 am
by Solar
alloca() is Windows / PE specific. See
the FAQ on the matter. Unless you want to consciously copy that Windows behaviour, it's not an issue.

Re:using stack...
Posted: Wed Mar 24, 2004 8:19 am
by Candy
Solar wrote:
alloca() is Windows / PE specific. See
the FAQ on the matter. Unless you want to consciously copy that Windows behaviour, it's not an issue.
Ok, aside from the stack probing. What do you do with big things on the edge of memory? Or, with a function that has a split base ?
Re:using stack...
Posted: Wed Mar 24, 2004 10:49 am
by Pype.Clicker
the main difficulty of this trick is to know "how deep" in the existing stack you may have things that will be sp/bp related. In C for instance, you will only have the top frame (arguments, local variables and return address) accessed through [ebp] or [esp], so if you make sure the whole frame (which size you can detect by inspecting esp, ebp and [ebp]) is mapped in the new stack chunk ...