关于GDT加载后汇编代码功能及关键指令的技术疑问
Understanding This Protected Mode Setup Assembly Code
First, let's restate the code clearly for reference:
# Load the GDT. mov $gdt_descriptor, %ecx lgdt (%ecx) mov $0x10, %cx mov %cx, %ds mov %cx, %es mov %cx, %fs mov %cx, %gs mov %cx, %ss ljmp $0x8, $1f 1: mov $kernel_stack, %esp
This is standard setup code for switching an x86 system from real mode to protected mode, and I’ll break down your specific questions clearly below.
Why move $0x10 into %cx before assigning to other segment registers?
There are two key reasons here:
- What $0x10 actually is:
0x10is a GDT segment selector pointing to your kernel’s data segment descriptor. In protected mode, segment registers don’t hold the old real-mode segment base addresses—they hold selectors that reference entries in the Global Descriptor Table (GDT). The GDT starts with a mandatory NULL descriptor (index 0), so your kernel’s code segment is at index 1 (selector0x8, since the lower 3 bits are for privilege level and table flags) and the data segment is at index 2 (selector0x10). - x86 instruction rule: You can’t load an immediate value directly into segment registers like
ds,es,ss, etc. The only exception iscs, which you can’t modify with a regularmovat all. So we usecxas a temporary holder to get the0x10selector into all the data-focused segment registers efficiently.
What’s the purpose of the ljmp instruction?
The ljmp $0x8, $1f is a far jump, and it does two critical things to finalize the protected mode switch:
- Set the CS segment register: Since you can’t change
cswith amovinstruction, this far jump loads0x8(your kernel’s code segment selector) intocs. This tells the CPU to start using the code segment descriptor from the GDT for all future instruction fetches. - Flush the instruction pipeline: When switching modes, the CPU might still have pre-fetched real-mode instructions in its pipeline. The far jump forces the CPU to discard those old instructions and start fetching from the new protected-mode code location (the
1:label), ensuring the system is fully in protected mode before proceeding.
After this jump, setting esp to kernel_stack initializes the kernel’s stack pointer—an essential step for any subsequent function calls or stack-based operations in the kernel.
内容的提问来源于stack exchange,提问作者Junping Qv
相关产品推荐
相关产品推荐

