koyi 0 Newbie Poster

Hi, I am pretty new with assembly so please bear with me if this question sounds stupid :)

I am teaching myself OS development from resources of the web. I came across this tutorial here which talks about setting up GDT. I don't really get it when it is to set the value of CS register using a far jump. The code is like this:

jmp 0x08:flush2   ; 0x08 is the offset to our code segment: Far jump!
flush2:
    ret               ; Returns back to the C code!

Is the jmp command supposed to jump to "flush2" and continue its execution from "ret"? How can that happen? Isn't the long jump supposed to jump to 0x080 + (the address of flush2)?

Thanks in advance :)

Dani AI

Generated

Short answer for : yes — the far jump transfers control to the label and execution continues there, but it does not add 0x08 to the label’s address. In protected mode the left part of a far jump (0x08 in that example) is a segment selector, not a physical base to be summed with the offset. The CPU loads CS with the selector and sets the instruction pointer to the offset that the assembler encoded for the label; execution then proceeds at that offset under the new CS.

Why people get confused: in real mode a segment:offset pair is turned into a physical address by multiplying the segment by 16 and adding the offset. In protected mode the 16‑bit value is a selector. The selector’s index (selector >> 3) picks a descriptor from the GDT/LDT; the descriptor supplies a base, limit and access bits. The effective linear address is descriptor_base + offset, so 0x08 is an index into the GDT (index 1), not a value to add to the label address.

How the switch actually works: the assembler emits a far-jump operand containing both selector and offset. On execution the CPU atomically loads CS from the selector and the IP/EIP from the offset, and it flushes the prefetch queue — that’s why the far jump is used to “flush” into protected mode. A subsequent normal (near) return will pop the saved IP and resume the caller, now running with the newly loaded CS. This is the common trick used right after enabling protected mode to get the rest of the kernel running with the new code segment.

Practical notes: make sure the GDT descriptor you target is present and has the correct type and default operand size (32-bit code, present, executable/readable). Also ensure the offset you jump to lies within the descriptor limit. Remember that CS cannot be written directly — far jump/call/iret (not a simple move) is required to load a new selector.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.