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..