Hi, i have to create an expand-down stack but i don't understand expand-down almost at all.
The intel docs say its expand-up but in reverse. Does that mean the base is the limit and the limits the base or something?
I have a descriptor for my stack with everything that seems to be ok. The type is read/write expand-down.
Because of my granularity being 0 my limit is now AFF and the base is at 9FFFF. IS this right if i want a stack to be the free 640Kb of lower memory before the 1Mb mark?
Thanks, if i finally get a stack that works i can test some other code that i've written.
Regards, Brill.
p.s. Any help would be appreciated. I *really* am stuck with this expand-down concept
damn expand-down is hard!
RE:damn expand-down is hard!
Okay... here's the stack, according to Intel:
Remember how a stack works in real-mode?
Initially:
ss = stack segment
sp = stack segment limit
After each push:
sp is _decreased_ accordingly (gets closer and closer to ss)
This is what Intel considers an expand-UP stack! Contradictory to what it's actually doing, don't you think?
However, in pmode we have the ability to make an expand-DOWN stack:
ss = stack segment
esp = stack starting offset
After each pop:
esp is _increased_ accordingly
In essence, it's a data segment... you work from low (0MB) to high (4GB) memory with each push.
---------
According to Intel, I believe you want and expand-UP stack!
There are a few ways of doing this, actually.
Personally, I'd just define my stack descriptor to span the full memory range, 0 - 4GB, and set ESP to 1MB (0x00100000)
; 0x18 descriptor - Kernel stack segment
; base : 0x00000000
; limit: 0xfffff (4 GB)
; DPL : 0
; 32 bit, present, system, expand-up, writeable
dd 0x0000ffff
dd 0x00cb9200
With this method, of course, it's possible for the stack to work it's way all the way down to 0MB, though... in other words, it's not 100% safe.
What you probably want to do is set a stack with a base of 640k and a limit of (1MB - 640k), expand-UP, and set ESP = 1MB.
There's a major problem with that, though. 640*1024 = 0xA0000. In other words, @ 640k is video memory. You don't want your stack there Also, according to my virtual environment I have very little writeable memory between 640k and 1MB.
According to GRUB I simply have 640k lower memory, and ~100MB upper memory. Grub also reports that 0x9F800 - 0xA0000 and 0xE7000 - 1MB is reserved. This leaves only 0xA0000 - 0xE7000, but 0xA???? and 0xB???? are both video memory.
You'd probably be best off to have your stack above the 1MB mark, or below the 640k mark.
Hope that helps somewhat... :}
Jeff
Remember how a stack works in real-mode?
Initially:
ss = stack segment
sp = stack segment limit
After each push:
sp is _decreased_ accordingly (gets closer and closer to ss)
This is what Intel considers an expand-UP stack! Contradictory to what it's actually doing, don't you think?
However, in pmode we have the ability to make an expand-DOWN stack:
ss = stack segment
esp = stack starting offset
After each pop:
esp is _increased_ accordingly
In essence, it's a data segment... you work from low (0MB) to high (4GB) memory with each push.
---------
According to Intel, I believe you want and expand-UP stack!
There are a few ways of doing this, actually.
Personally, I'd just define my stack descriptor to span the full memory range, 0 - 4GB, and set ESP to 1MB (0x00100000)
; 0x18 descriptor - Kernel stack segment
; base : 0x00000000
; limit: 0xfffff (4 GB)
; DPL : 0
; 32 bit, present, system, expand-up, writeable
dd 0x0000ffff
dd 0x00cb9200
With this method, of course, it's possible for the stack to work it's way all the way down to 0MB, though... in other words, it's not 100% safe.
What you probably want to do is set a stack with a base of 640k and a limit of (1MB - 640k), expand-UP, and set ESP = 1MB.
There's a major problem with that, though. 640*1024 = 0xA0000. In other words, @ 640k is video memory. You don't want your stack there Also, according to my virtual environment I have very little writeable memory between 640k and 1MB.
According to GRUB I simply have 640k lower memory, and ~100MB upper memory. Grub also reports that 0x9F800 - 0xA0000 and 0xE7000 - 1MB is reserved. This leaves only 0xA0000 - 0xE7000, but 0xA???? and 0xB???? are both video memory.
You'd probably be best off to have your stack above the 1MB mark, or below the 640k mark.
Hope that helps somewhat... :}
Jeff
RE:Thanks
Generally speaking, no.
However, I _believe_ your GDT has to be dword aligned (I'm not sure...), in which case you probably would.
If your GDT is defined as a structure in GCC, you'll be fine (GCC will dword align it by default). If, however, you're defining it in NASM, you might want to put a "align 4, db 0" right before "gdt:" to be safe (it's generally a good idea to dword align your structs anyway).
Also (this might be of interest), if you know, for sure, that you have a valid data descriptor, you can actually use it as a stack segment as well. I did this for a while to get my kernel up and running, way back when, before I'd decided upon how I wanted my stack segment to go.
Jeff
However, I _believe_ your GDT has to be dword aligned (I'm not sure...), in which case you probably would.
If your GDT is defined as a structure in GCC, you'll be fine (GCC will dword align it by default). If, however, you're defining it in NASM, you might want to put a "align 4, db 0" right before "gdt:" to be safe (it's generally a good idea to dword align your structs anyway).
Also (this might be of interest), if you know, for sure, that you have a valid data descriptor, you can actually use it as a stack segment as well. I did this for a while to get my kernel up and running, way back when, before I'd decided upon how I wanted my stack segment to go.
Jeff