[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