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
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;
}