I'm writing a kernel that uses hardware task switching. To call a task, I need to do a far call to the TSS descriptor of the task (each task has a TSS descriptor in the GDT).
For example, to run task1, one would write:
Code: Select all
call_task1:
call 0x20:0
ret
Code: Select all
call_task1:
call 0x28:0
ret
It's totally unflexible and I don't want to hardcode the segment selector. It needs to by dynamic. Ideally, it should be something like this, where the argument is the task selector of the task we want to call:
Code: Select all
call_task:
call [esp+4]:0
ret
Code: Select all
call_task:
; Opcodes for the far call 0x1234:0x2694
; 9a 94 26 00 00 34 12 lcall $0x1234,$0x2694
push ebp
mov ebp,esp
push ds
push ebx
push eax
mov bx,cs
mov ds,bx
mov dword ebx,(.selfmod+4)
mov ax,[ebp+8]
mov word [ebx],ax ; change the 0xFF below to the contents of AX
pop eax
pop ebx
pop ds
pop ebp
.selfmod:
call 0xFF:0
ret
However, it doesn't work.
I suspect the way I get the address of the .selfmod label is not correct.
Does anyone have an idea how I can write a version of my call_task where the code would do a far jump to the selector passed in argument?
Thanks a lot!