[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[MiNT] Gemdos function: Super()
Hi,
I've experimented tonight with the Super() call using Pure C and my own
tos binding library.
I'll start with the part which seems clear:
When an application (in user mode) calls Super(0), it switches to
supervisor mode using its current stack pointer as supervisor stack
pointer. The old supervisor stackpointer is returned as a result of the
call.
After that, it calls Super(old_ssp), passing the old supervisor stack
pointer. This call changes back to user mode and sets the supervisor
stack to "old_ssp". The supervisor stack pointer is copied back to user
stack pointer.
The use of "old_ssp=Super(0)" and "Super(old_ssp)" allows the
application to switch to supervisor mode without modifying its stack
pointer (i.e. if the compiler has put some temporary variables onto the
stack, they are still accessible between the calls).
But what happens if the application specifies its own supervisor stack?
When the appliation calls "Super(my_stack)", it switches into
supervisor mode, receiving the old supervisor stack pointer as a result
of this call. But as we specified our own stack, we loose control over
the content of the old stack. I.e. we don't have access to our
temporary variables and return addresses which laid on the old stack.
(OK, you can use assembler to get the content of USP register, but hey:
we're programming in C :-))
After this, our application calls "Super(old_ssp)", which puts it back
into user mode, but replaces the user stack pointer with the current
supervisor stack pointer! We've finally lost complete control on our
old user stack containing our temporary data (at least if we didn't
save it by accessing USP).
So what's the use of this function? I mean, what's the use of
Super(my_stack), if I can't get back to my old stack. I always thought
that the Super() function is just a facility to switch back and forth
between user and supervisor mode. But this variant is an exception.
Up to now I've never read something about this. Why is this behaviour
not documented anywhere?
(I.e. I've read in no documentation that switching back from supervisor
mode to user mode should not be done with Super(), as this will just
copy SSP to USP.)
To make a final point:
The following binding for Super() can only work with "Super(0/1)" and
"Super(old_ssp)", because of the stack-switching-behavior of this call:
Super:
pea (A0)
move.w #32,-(sp)
trap #1
addq.l #6
rts
It's not possible to implement the "Super(my_stack)" call as a
subroutine, because after switching the stack, we've lost the return
address, which can only be restored by accessing USP in assembly
language.
regards
Philipp