No need to reply but you may find this lot interesting.
My (Pmode) interrupt-handling currently includes code of the form
pusha
push ds
push es
push fs
push gs
... handle interrupt
pop gs
pop fs
pop es
pop ds
popa
That simple approach has led to some queries.
===> 1. When pushed in that way does each segment register take up two
bytes or four bytes on the stack? Intel seem remarkably unclear about
this. Their manuals say such as
"PUSH decrements the stack pointer by 2 if the operand-size attribute
of the instruction is 16 bits; otherwise, it decrements the stack
pointer by 4."
http://www.scs.stanford.edu/05au-cs240c/lab/i386/PUSH.htm
IMO that's confusing since the size of the operands in this case is
unavoidably 16 bits but the D bit of the CS descriptor will be set
indicating a default operand size of 32 bits.
I have, I think, satisfied myself that in PM32 the segment registers
will always be pushed as four bytes but that leads to the second point.
===> 2. Since two-byte values are being pushed as four bytes which bytes
hold the value and what gets put in the other two bytes?
If all we are doing is popping them later, as above, then it doesn't
matter but it could be important when priming the stack for a new task
and it could matter to an interrupt handler which accessed the
interrupted task's registers, e.g. a debug-exception handler.
===> 3. Since loading segment registers is slow would it be faster to
wrap the loads in tests such that each segreg is only reloaded if it has
changed as in
if current GS does not equal the GS saved on the stack
pop GS from the stack
else
pop the stack into an unused general register such as EAX
===> 4. Most often it will be a user-mode task which is interrupted so
the DS segreg will have to change to the kernel's data segment. But
there will be times when DS does not need to change such as interrupting
a kernel-mode task or, perhaps more importantly, when there's an
'interrupt storm' and higher-priority IRQs are interrupting
lower-priority ones. Given that, should DS also only be reloaded if it
has changed?
===> 5. Finally, since DS is most likely to be used first by the code
once the interrupt returns would it be better to carry out the reload of
DS (whether wrapped or not) /before/ the other segment registers as in
pop ds ;Do DS first
pop es
pop fs
pop gs
so that DS is more likely to be ready soonest?
As I say, no need to reply unless interested. This has been bugging me
for days but I think I am making progress.
--
James Harris