Task switching and stack setup.

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
lepra

Task switching and stack setup.

Post by lepra »

Hi!
I can't fix tasks to work properly, it works once, but then it crashes (Invalid opcode), I may switch to each task once.
Seems like the task_switch function is messing up my stacks.
Here's the task_switch:

Code: Select all

[global _task_switch]
_task_switch:
   cli
   pushad
 
   ;; Last task's stack now contains return address + registers
 
   mov ebp, esp
 
   mov [ebp+32+8], esp  ;; save the last task at the second parameter
   mov esp, [ebp+32+4]  ;; change stack
 
   popad
 
   sti
   retn
And here's the stack setup:

Code: Select all

int SetupTaskStack(task_t *_task, int (*_func)(void)) {
   uint32 iEAX, iECX, iEDX, iEBX, iESP, iEBP, iESI, iEDI, iESP2;
 
   _task->ustack = g_pStacks;
 
   asm("mov %%eax, %0":"=r"(iEAX));
   asm("mov %%ecx, %0":"=r"(iECX));
   asm("mov %%edx, %0":"=r"(iEDX));
   asm("mov %%ebx, %0":"=r"(iEBX));
   asm("mov %%esp, %0":"=r"(iESP));
   asm("mov %%ebp, %0":"=r"(iEBP));
   asm("mov %%esi, %0":"=r"(iESI));
   asm("mov %%edi, %0":"=r"(iEDI));
 
   *_task->ustack = _func;
 
   *_task->ustack-- = iEAX; // EAX
   *_task->ustack-- = iECX; // ECX
   *_task->ustack-- = iEDX; // EDX
   *_task->ustack-- = iEBX; // EBX
   *_task->ustack-- = iESP; // ESP
   *_task->ustack-- = iEBP; // EBP 
   *_task->ustack-- = iESI; // ESI
   *_task->ustack-- = iEDI; // EDI
 
   g_pStacks += 0x1000; // 4 KB limited stack
 
   return _task->ustack;
}
shad

Re:Task switching and stack setup.

Post by shad »

Ive been coding my OS for about ehh.. i wanna say.. 9 months, I still have had NO luck with multitasking. Hope someone unveils it in this thread. :-\
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Task switching and stack setup.

Post by Pype.Clicker »

how do you perform the task switch ?? What's that '[+32+8] stuff ?
lepra

Re:Task switching and stack setup.

Post by lepra »

That's so I may call the task_switch from C using parameters, like this:

iTask1 = ESP for task1
the last task's ESP is saved into iLastTask.

Code: Select all

task_switch(iTask1, &iLastTask);
asmboozer

Re:Task switching and stack setup.

Post by asmboozer »

[global _task_switch]
_task_switch:
cli
pushad

;; Last task's stack now contains return address + registers

mov ebp, esp

mov [ebp+32+8], esp ;; save the last task at the second parameter
mov esp, [ebp+32+4] ;; change stack

popad

sti
retn

I consider this is weird, since mov esp, [ebp+32+4] already changes ESP, then what's the popad ? now the SS:ESP won't be the pushad's content now.

this is my guess. I don't know much about asm. I don't know "USE16,USE32, SEGMENT ,CLASS"etcs usage. one asm tutorial may help me out.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Task switching and stack setup.

Post by Candy »

asmboozer wrote: I consider this is weird, since mov esp, [ebp+32+4] already changes ESP, then what's the popad ? now the SS:ESP won't be the pushad's content now.
The popad pops from the new esp, pointing to the new task. So, the values of the new task get popped, it returns to the new task's most recent IP address (with a retn, which is weird).

In other words, it switches tasks. Isn't that like what it is supposed to do?
asmboozer

Re:Task switching and stack setup.

Post by asmboozer »

I thought if the task swith process is an alone system process would be better. simply to say that the system process don't need to have the same ESP value as the one of the task to be swapped out.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Task switching and stack setup.

Post by Pype.Clicker »

i'm still not convinced by your use of the parameters ...
okay, the '+32' is there for skipping the bytes from PUSHA.
okay, the '+4' and '+8' as there's not the usual 'push ebp' before 'mov ebp,esp'
okay, the 'popad' instruction doesn't affect the value of ESP.

but one of the ords on the stack is a *pointer* to a dword and the other is a dword ...

what your

Code: Select all

mov [ebp+32+8],esp
does is to overwrite the address where the old stack pointer should be stored with the old stack pointer ... All of this happens on the old stack itself ... these changes will be lost when the stack switch function will return (as the caller is likely to add esp, 8 then ...)

You should rather have

Code: Select all

mov eax,[ebp+32+8] ;; eax is now a pointer to the store address
mov [eax],esp          ;; the pointer is saved.
lepra

Re:Task switching and stack setup.

Post by lepra »

Okey, but it didn't help :/
I've played around with the stack setup function, and I don't get Invalid Opcodes anymore, but instead I get Page Faults @ 0x25302063 :/

I have one more question:
How should I switch tasks if the computer can't call an interrupt handler when it's in a infinitive loop? Switch tasks in the tasks them self?
Adek336

Re:Task switching and stack setup.

Post by Adek336 »

How should I switch tasks if the computer can't call an interrupt handler when it's in a infinitive loop? Switch tasks in the tasks them self?
Apps are not likely to have infinite loops written in design so it would be hard to insert a call to sleep() in each of them.

BTW, the interrupt handlers will run on an infinitive loop if only IF==1.

Code: Select all

asm volatile ("sti");
for(;;);   /*task switches will occur*/
Cheers
Post Reply