Page 1 of 1
Setting up a stack
Posted: Mon Jan 19, 2009 5:47 pm
by sweetgum
Can some one show me an example of how to do the following:
1. Establish a stack segment
2. Load the segment selector the stack segment into the SS register using MOV, POP, or LSS instruction
3. Load the stack pointer for the stack into the ESP register using a MOV, POP, or LSS instruction. The LSS instruction can be used to load the SS and ESP registers in one operation.
Re: Setting up a stack
Posted: Mon Jan 19, 2009 7:38 pm
by CodeCat
1. There's no need to set up a separate stack segment usually. Just jump to a code segment, and load the same data segment in all segment registers including SS. You'll save yourself a lot of headaches.
2. LSS expects two operands: a register, and a pointer to a 48-bit data structure containing the value to load into the register (32 bits), followed by the value to load into SS (16 bits).
3. If you do
then you can load both in one go. This is the preferred method as it guarantees that the operation is atomic, which prevents something from jumping between the load of SS and the load of ESP and getting an invalid stack. Basically, using LSS leaves no 'downtime' without a valid stack.
Re: Setting up a stack
Posted: Tue Jan 20, 2009 9:22 am
by JAAman
CodeCat wrote:
This is the preferred method as it guarantees that the operation is atomic, which prevents something from jumping between the load of SS and the load of ESP and getting an invalid stack. Basically, using LSS leaves no 'downtime' without a valid stack.
...
so does this:
mov ss, 0x10
mov esp 0x0
this is also guaranteed to not leave an invalid stack...
according to the intel manuals, anytime that SS is loaded, the CPU prevents any interrupt from occurring until following the next instruction, specifically to account for this, so you dont really need to worry about that (basically the CPU treats 'mov ss' and whatever instruction follows it, as a single instruction)
Re: Setting up a stack
Posted: Tue Jan 20, 2009 9:38 am
by CodeCat
Sounds more like a quick hack to me. You might as well do it with LSS anyway.
Re: Setting up a stack
Posted: Tue Jan 20, 2009 10:44 am
by Combuster
So that you know: That behaviour existed long before LSS did
Re: Setting up a stack
Posted: Tue Jan 20, 2009 11:06 am
by CodeCat
So then what's the point of having LSS?
Re: Setting up a stack
Posted: Tue Jan 20, 2009 11:21 am
by Combuster
Last time I checked, there wasn't another instruction that could load a segment register from a random memory location.
Never insult intels misunderstanded wisdom
Re: Setting up a stack
Posted: Tue Jan 20, 2009 12:27 pm
by Firestryke31
But with the two mov instructions, couldn't someone (for some reason) jump in between them? You can't exactly do that with the LSS instruction.
Re: Setting up a stack
Posted: Tue Jan 20, 2009 12:55 pm
by CodeCat
Well apparently there's some logic hard-wired into the CPU that disables interrupts until the next instruction finishes, if the first instruction is a move into a segment register.
Re: Setting up a stack
Posted: Tue Jan 20, 2009 5:26 pm
by Firestryke31
I meant something absurd like this:
Code: Select all
; corrupted code or data that happens to contain
jmp lolwut
; ...
mov ss, ax
lolwut:
mov sp, stackAddr
Of course, if the code is corrupted or you're executing data, you've got bigger problems than messing up the stack...
Re: Setting up a stack
Posted: Wed Jan 21, 2009 9:29 am
by Ready4Dis
Firestryke31 wrote:I meant something absurd like this:
Code: Select all
; corrupted code or data that happens to contain
jmp lolwut
; ...
mov ss, ax
lolwut:
mov sp, stackAddr
Of course, if the code is corrupted or you're executing data, you've got bigger problems than messing up the stack...
And what if someone jumps to AFTER the LSS instruction, or does a mov ss, XX after the LSS instruction. I don't really see what you're arguing, if the code is messed up, it doesn't really matter how you setup your stack, the code is still messed up. Saying that you can break code by skipping, or jumping past part of it, etc doesn't mean anything, because it is irrelevant to the opcodes being discussed. Firstly, using LSS, you must first have memory set aside, using mov ss, xxx, and sp, xxx, do not rely on the program being run from any specific location, so position independant code (PIC) is much simpler to do. It is also supported by all CPU's, so no worries about using it in a boot loader before checking for CPU type, etc. mov ss, ax (especially if AX is already loaded, most if the time you'd load this at the same time as DS) is a 2-byte senquence, and mov sp, Addr, is 3-bytes (5 if it's 32-bit address) , so 5 or 7 bytes total. LSS reg, memaddr takes up 4 bytes for the op-code, and 6 for the seg/reg, so minimum of 10-bytes vs. maximum of 7-bytes for the first method (possibly 10 if you need to load ax first). This means less memory hits, even if it's an 'extra' opcode. This is all mostly useless, but my point is, it takes up less memory (useful in a very limited boot loader), is position independant, supported on all CPU's, and is atomic, why use something that takes more memory, isn't supported by all CPU's, and has almost zero benefits (other than it's a single opcode with a 48-bit seg/offset pair vs. 2 ocodes, and having to load ax with something, so possibly 3 if you aren't loading other segment registers with the same value).
Re: Setting up a stack
Posted: Fri Jan 23, 2009 12:17 am
by iammisc
Firestryke31 wrote:But with the two mov instructions, couldn't someone (for some reason) jump in between them? You can't exactly do that with the LSS instruction.
But since this is your operating system, you wouldn't do that. (unless a jump was caused by a bug and if it was a bug, it should be fixed).
Re: Setting up a stack
Posted: Fri Jan 23, 2009 1:08 am
by Firestryke31
Firestryke31 wrote:
Of course, if the code is corrupted or you're executing data, you've got bigger problems than messing up the stack...
Re: Setting up a stack
Posted: Fri Jan 23, 2009 8:25 pm
by Love4Boobies
You could just as well jump in the middle of the LSS instruction (which is more than one byte long).