Page 1 of 1

Task Switch: JMP DWORD AX:0x12345678 doesn't work

Posted: Mon Aug 18, 2008 11:21 am
by sevobal
Hey everyone!
I've tried to make a hardware based task switch. First of all, I load a selector into ax:

Code: Select all

mov esi,[tasking_current] ;base of a task table entry
add esi, 0x00000002        ; TSS selector for a task
mov word ax, [es:esi]      ; Now the selector is in ax
Now ax holds a selector of a gdt entry which points to a tss of a task. Now, all I have to do is making a far jmp using this selector as segment. Offset can be a random value, because it will be ignored. So I tried this:

Code: Select all

jmp dword ax:0x12345678
But the assembler (nasm) doesn't like it. So how can I handle it? I need ax (or it's value) to do a correct jump.

Re: Task Switch: JMP DWORD AX:0x12345678 doesn't work

Posted: Mon Aug 18, 2008 2:45 pm
by ru2aqare
Try this:

Code: Select all

    push    eax       ; ax contains your TSS selector
    push    0         ; offset is ignored
    jmp     far ptr [esp+0]
    add     esp, 8    ; if you switch back to this task, remove the dwords pushed onto the stack
Or you can use self-modifying code, like this:

Code: Select all

    mov     [offset dummy_label + 1], ax
dummy_label:
    db      0EAh      ; opcode for far jump
    dw      0         ; selector will be plugged in here
    dd      12345678h ; offset

Re: Task Switch: JMP DWORD AX:0x12345678 doesn't work

Posted: Mon Aug 18, 2008 6:03 pm
by Brendan
Hi,
sevobal wrote:But the assembler (nasm) doesn't like it. So how can I handle it? I need ax (or it's value) to do a correct jump.
It's the CPU that wouldn't like it... ;)

You could try something like this:

Code: Select all

    mov esi,[tasking_current] ;base of a task table entry
    add esi, 0x00000002        ; TSS selector for a task
    jmp far dword [es:esi - 4]
This works because the offset is ignored, so we can pretend that "[es:esi-4]" contains a 4 byte offset (that's ignored) followed by the 2 byte selector.


Cheers,

Brendan