Author Topic: Executing a CS change from memory  (Read 19939 times)

Offline BlackClover

  • Jr. Member
  • *
  • Posts: 3
Executing a CS change from memory
« on: June 05, 2010, 06:00:21 AM »
Hi,

I'm working on a scheduler project for one of my classes. I've come across an issue where I try to make a jump to a TSS -task state segment- descriptor, in order to switch tasks (I'm using a task gate scheduler), but I can't manage to get jump to switch the CS (a.k.a. perform a proper far jump).

I'm using an index to point to a memory position where the next task descriptor to load is stored.

next task's TSS descriptor to jump to  -> edx + eax (edx is the base address of my jump table, while eax is the index I use to move within the table)

The jump needs to be a far one, the segment or descriptor to change to is stored in [edx + eax], and the offset doesn't really matter, since I'm jumping to a TSS.

Any ideas as to how to accomplish this will be greatly appreciated.

*points at nasm and nags at it* "I need you to jump, not hop! D;"

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Executing a CS change from memory
« Reply #1 on: June 05, 2010, 07:54:22 AM »
Code: [Select]
jmp far [edx + eax]

... I should think... What's it do instead?

Best,
Frank


Offline BlackClover

  • Jr. Member
  • *
  • Posts: 3
Re: Executing a CS change from memory
« Reply #2 on: June 05, 2010, 02:04:50 PM »
I've tried that, but it interprets [edx + eax] as an offset, instead of a descriptor.

Offline mik

  • Jr. Member
  • *
  • Posts: 5
Re: Executing a CS change from memory
« Reply #3 on: June 05, 2010, 04:19:36 PM »
jmp far [ebx + eax]

the 32-bit or 48-bit far pointer stored in [edx+eax]

Offline BlackClover

  • Jr. Member
  • *
  • Posts: 3
Re: Executing a CS change from memory
« Reply #4 on: June 06, 2010, 07:00:54 PM »
Thanks a lot for the help. :)

I've finally managed to get it working by using:

Code: [Select]
jmp far word [edx + eax]
And repositioning the  memory layout as follows:

Code: [Select]
edx + eax -> word 0 (trash)
             word Selector (the one I was trying to switch to)
instead of

Code: [Select]
edx + eax -> word Selector
Now I have to admit I'm curious. How exactly does jump load the values from memory? How does the instruction size specifier affect this?

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Executing a CS change from memory
« Reply #5 on: June 06, 2010, 08:31:12 PM »
Good question. I'd expect, in 32-bit code, "jmp far [mem]" to expect dword offset, word selector. Adding the "word" specifier ("o16 jmp far [mem]" should do the same thing) would expect word offset, word selector (Nasm adds a 66h "operand size override prefix").

This memory arrangement is known to other assemblers as an "fword". In 16-bit code, this would be 32 bits (16:16), and in 32-bit code, 48 bits (32:16). Nasm, being an innocent little assembler, doesn't know no "fword". :)

I ASSumed 32-bit code (still do), and ASSumed you knew what the memory layout for "jmp far [mem]" looked like. I really have no idea what loading a TSS does. If the offset is "don't care", what offset *do* we end up at? Gotta execute the next instruction at *some* offset, I would think(?). Not something we do from "userland" code, and I haven't gotten far enough into "initializing an OS" to have encountered it.

Since the offset is "don't care"(?), perhaps "mov cs, [mem]" would work? Nasm assembles it, and it works as expected for other segregs - not something we'd "ordinarily" do with cs. Maybe "mov ax, selector"/"mov cs, ax" would work also? Switching cs "on the fly", without also specifying a new offset, is "usually" a bad idea (thus the notion that a far jump is the way to reload cs), but maybe it works with a TSS... dunno.

Glad to hear you got it working, anyway. Maybe you'll post an "example" for us at some point - always looking for examples!

Best,
Frank