Stack Creep

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Stack Creep

Post by AJ »

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:

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
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
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Oh, here is a screen shot of the situation if I print what's happening in my scheduling function:

[edit]Kernel and Idle are just test ring 0 tasks, T3 is a test ring 3 task which just does jmp $.[/edit]
Attachments
ccl_tasking.JPG
ccl_tasking.JPG (43.01 KiB) Viewed 493 times
Post Reply