Stack Creep
Posted: Wed Mar 14, 2007 3:45 am
Hi,
I am revisiting my task switching code and seem to have a problem. When switching from a ring0 to ring0 task, no problems. However, when a ring 3 task is involved, its value of esp0 seems to creep by 0x14 (20) bytes on every switch, which is quite worrying.
Obviously I have missed something major, but can't spot it. I'd be grateful if anyone could try to spot my mistake! The switching code is as follows:
In this example, _p points to a structure with current process information and P_ESP0 is the correct offset to the stored esp value.
_ks_switch is a function coded in c which currently simply changes [_p] to the next process in a circular linked list - no checking or stack alteration of any sort.
Hopefully, _tss is self explanatory! The return address for _ks_switch is obviously stored on the outgoing tasks stack, but on return, these values have been popped, so I don't see the problem there.
Any ideas much appreciated. If it would be helpful to see the initialisation code, I can post it, but I can assure you that I am adding a ring3 stack segment and pointer to the new ring 3 task's stack!
Cheers,
Adam
I am revisiting my task switching code and seem to have a problem. When switching from a ring0 to ring0 task, no problems. However, when a ring 3 task is involved, its value of esp0 seems to creep by 0x14 (20) bytes on every switch, which is quite worrying.
Obviously I have missed something major, but can't spot it. I'd be grateful if anyone could try to spot my mistake! The switching code is as follows:
Code: Select all
doswitch:
;SAVE OUTGOING TASK
push ds ;save all registers
push es
push fs
push gs
pusha
mov eax, esp ;save old esp0 stack
mov ebx, [_p]
mov [ebx+P_ESP0], eax
;TASK SWITCH
call _ks_switch
;RESTORE INCOMING TASK
mov ebx, [_p] ;restore new esp0 stack
mov eax, [ebx+P_ESP0]
mov esp, eax
popa ;restore all registers
pop gs
pop fs
pop es
pop ds
;save esp0
push ebx
push eax
mov ebx, [_tss]
mov eax, esp
add eax, 8 ;esp0 after eax and ebx are popped
mov [ebx+4],eax
pop eax
pop ebx
iret
_ks_switch is a function coded in c which currently simply changes [_p] to the next process in a circular linked list - no checking or stack alteration of any sort.
Hopefully, _tss is self explanatory! The return address for _ks_switch is obviously stored on the outgoing tasks stack, but on return, these values have been popped, so I don't see the problem there.
Any ideas much appreciated. If it would be helpful to see the initialisation code, I can post it, but I can assure you that I am adding a ring3 stack segment and pointer to the new ring 3 task's stack!
Cheers,
Adam