Page 1 of 1
multitasking
Posted: Wed Nov 12, 2008 7:33 pm
by regedit
I am trying to program a simple multitasking sys.. just to run a few programs at 1st..
I have been searching the net tring to find and example of multitasking with asm ... I am only finding C... Converting to asm has been a pain.. and with no luck.. This is one of the functions I am having probs with
Code: Select all
void CreateTask(int id, void (*thread)()){
unsigned int *stack;
Threads[id].esp0 = AllocPage() + 4096; //This allocates 4kb of memory, then puts the pointer at the end of it
stack = (unsigned int*)Threads[id].esp0; //This makes a pointer to the stack for us
//First, this stuff is pushed by the processor
*--stack = 0x0202; //This is EFLAGS
*--stack = 0x08; //This is CS, our code segment
*--stack = (UINT)thread; //This is EIP
*--stack = 0; //EDI
*--stack = 0; //ESI
*--stack = 0; //EBP
*--stack = 0; //Just an offset, no value
*--stack = 0; //EBX
*--stack = 0; //EDX
*--stack = 0; //ECX
*--stack = 0; //EAX
*--stack = 0x10; //DS
*--stack = 0x10; //ES
*--stack = 0x10; //FS
*--stack = 0x10; //GS
Threads[id].esp0 = (UINT)stack; //Update the stack pointer
}
?? *--stack = 0; I am guesing this is some sort of pointer??
or what would this equ in asm??
Re: multitasking
Posted: Wed Nov 12, 2008 9:58 pm
by 01000101
The variable 'stack' is equal to 'Threads[id].esp0'. So say that 'Threads[id].esp0' is equal to 0x123456, then the variable 'stack' is equal to 0x123456, and when prefixed with the '*' turns that variable into a pointer. So '*stack' is equal to the int at memory location 0x123456. The '--' prefix means to decrement the variable
before the operation happens, so if 'stack' equals 0x123456, if the '--' is used, it turns into 0x123456-(4) and then will proceed with the operations. The -(4) is due to it being an of the data type 'int' which is 4-bytes wide.
So the operation '*--stack = 0x202' breaks down to:
Code: Select all
stack--; // stack -= sizeof(int);
*stack = (int)0x202; // pointer to 'stack' now equals 0x202.
Because the stack grows down, the first variable needs to be stored 4-bytes below the stack pointer, and keeps decrementing by 4 for every push to the stack.
A quick translation for the lower-half would be similar to this:
Code: Select all
push esp; save the working ESP
mov esp, 0x123456; the stack position (arbitrary in this case, but should be the thread's esp location
push 0x202; EFLAGS
push 0x08; CS
push (the thread's EIP)
push 0; EDI
etc.etc.etc..
pop esp; restore the current ESP
Re: multitasking
Posted: Wed Nov 12, 2008 11:26 pm
by regedit
I tried something like this... ?
Code: Select all
proc:
;mem done here...
mov esp,[t_esp0+id]
push 0x0202
push 0x08
push ebx ;address of the task
push 0
push 0
push 0
push 0
push 0
push 0
push 0
push 0
push 0x10
push 0x10
push 0x10
push 0x10
mov [t_esp0+id],esp
ret
but when I run it crashes..
mov ebx,test1
call proc
Code: Select all
qemu: fatal: Trying to execute code outside RAM or ROM at 0xe858070c
EAX=00000000 EBX=00012d5c ECX=00000115 EDX=000003f2
ESI=00000000 EDI=00000000 EBP=000007f8 ESP=ffffffa0
EIP=e85800ec EFL=00000202 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0018 00000620 ffffffff 00cf9300
CS =0010 00000620 ffffffff 00cf9a00
SS =0018 00000620 ffffffff 00cf9300
DS =0018 00000620 ffffffff 00cf9300
FS =0008 00000000 ffffffff 00cf9300
GS =0018 00000620 ffffffff 00cf9300
LDT=0000 00000000 0000ffff 00008000
TR =0050 00000000 00000067 0000e900
GDT= 00000bec 00000057
IDT= 00000c4c 000007ff
CR0=60000011 CR2=00000000 CR3=00000000 CR4=00000000
CCS=00000044 CCD=e00bbcb0 CCO=EFLAGS
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000
XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000
XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000
XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000
I am missing something...
Thanks in andavnce for any help!
Re: multitasking
Posted: Thu Nov 13, 2008 2:41 am
by Combuster
ESP must be restored to its original value.
An alternative idea might be to rep movsd a copy in place since the data will be practically the same anyway
Re: multitasking
Posted: Thu Nov 13, 2008 3:33 am
by regedit
nope - tried.. the EIP stays the same val...
I found after a call you can pop eax to get the EIP
Code: Select all
proc:
pop eax
mov [tmp],eax
push ebx
mov ebx,565
call allocate_mem
mov [t_esp0+id],ebx
mov esp,[t_esp0+id]
pop ebx
push 0x0202
push 0x08
push ecx
push 0
push 0
push 0
push 0
push 0
push 0
push 0
push 0
push 0x10
push 0x10
push 0x10
push 0x10
mov [t_esp0+id],esp
inc dword[id]
lea esp,[tmp]
ret
Its loads up - but noting is executing.. ?
Re: multitasking
Posted: Thu Nov 13, 2008 7:09 am
by Combuster
Lots of things
- push/pop mismatch in the original stackframe
- esp is still not restored
- reentrancy problems
- no apparent effort spent in singlestepping before asking
Re: multitasking
Posted: Thu Nov 13, 2008 12:44 pm
by regedit
Thanks - but I did get it working...
Thanks again - for any help given..
Re: multitasking
Posted: Thu Nov 13, 2008 4:33 pm
by 01000101
could you post the solution so that others that come along can see? It doesn't have to be the actual code if you wish, but I think you should at least give the reason for the failure and how you addressed it.
Re: multitasking
Posted: Thu Nov 13, 2008 5:13 pm
by regedit
I will explain-
The crash was caused by where the kernel was executing the program..
loading the val of ecx was not were the allocated mem was.. I needed to change the code to the steps below..
[t_esp0+id] - 1st load the pointer address to the allocated mem
[t_esp0+id] - 2nd load the program into that spot
[t_esp0+id] - then execute this - not the ecx in the other code
or
[t_esp0+id] - push dword[t_esp0+id] into EIP
later I may post a simple program that shows all the code..