system: You are Herman Schonfeld, a caller on a 1990s BBS posting in the Assembly Lang. message echo. Write like a real BBS user of the era — plain, direct, in your own voice, no modern polish.

user: You are replying to Paul Wankadia about "protected mode".

They wrote:
PW>The code seems to work until I try to LIDT (i.e. LGDT works, but LIDT
PW>doesn't).  Can anyone tell me why?  TIA.
PW>=====
PW>/*
PW>        boot/boot.h
PW>        ~~~~~~~~~~~
PW>        Contains macros for values used during booting.
PW>*/
PW>#define BOOT_SEG 0x9000
PW>#define KERNEL_SEG 0x0100
PW>#define SYSTEM_SIZE 0x10
PW>=====
PW>/*
PW>        boot/head.S
PW>        ~~~~~~~~~~~
PW>        PUNIX starts here.
PW>*/
PW>#include "boot.h"
PW>.file   "boot/head.S"
PW>.code16
PW>.text
PW>.global start
PW>start :
PW>        movw    %cs, %ax
PW>        movw    %ax, %ds
PW>        movw    %ax, %ss
PW>        movw    $0xFFFF, %sp
PW>        movb    $0x03, %ah
PW>        movb    $0x00, %bh
PW>        int     $0x10
PW>        movw    $0x1301, %ax
PW>        movw    $0x07, %bx
PW>        movw    $msg_yo2, %bp
PW>        movw    msg_yo2_length, %cx
PW>        int     $0x10
PW>/*
PW> *      Disable all interrupts ...
PW> */
PW>        cli
PW>        movb    $0x80, %al
PW>        outb    %al, $0x70
PW>/*
PW> *      ... load GDT and IDT ...
PW> */
PW>        lgdt    gdt_descriptor
PW>        lidt    idt_descriptor
PW>/*
PW> *      ... and enter protected mode.
PW> */
PW>        movl    %cr0, %eax
PW>        orb     $0x01, %al
PW>        movl    %eax, %cr0
PW>        jmp     1f
PW>/*
PW> *      Setup segment registers and stack.
PW> */
PW>1 :
PW>        .code32
PW>        movw    $0x10, %ax
PW>        movw    %ax, %ds
PW>        movw    %ax, %es
PW>        movw    %ax, %fs
PW>        movw    %ax, %gs
PW>        movw    %ax, %ss
PW>        movw    $0xFFFF, %sp
PW>/*
PW> *      Start the kernel!
PW> */
PW>        movw    msg_yo_length, %cx
PW>        movl    $msg_yo, %esi
PW>        movl    $0xB8000, %edi
PW>        cld
PW>        rep
PW>        movsb
PW>        call    _start_kernel
PW>/*
PW> *      start_kernel() shouldn't return, but if it does...
PW> */
PW>2 :
PW>        jmp     2b
PW>idt_descriptor :
PW>        .word   0x00
PW>        .long   0x00
PW>gdt_descriptor :
PW>        .word   0x7FF
PW>        .word   gdt, (KERNEL_SEG)
PW>gdt :
PW>        .quad   0x00
PW>        .word   0xFFFF
PW>        .word   0x0000
PW>        .word   0x9A00
PW>        .word   0x00CF
PW>        .word   0xFFFF
PW>        .word   0x0000
PW>        .word   0x9200
PW>        .word   0x00CF
PW>msg_yo :
PW>        .ascii  "Y.o.!."
PW>msg_yo_length :
PW>        .word . - msg_yo
PW>msg_yo2 :
PW>        .ascii "We are in the kernel!\r\n"
PW>msg_yo2_length :
PW>        .word . - msg_yo2
PW>=====

Write your reply.

assistant: To to allocate a specific LDT descriptor, you must use function 000Dh and
oad
the selector into BX.
to call.,
AX = 000dh
BX = selector
If function was successful, the carry flag is clear and the descriptor has
been allocated. If function failed the carry flag is set.
This function will fail if the selector specified in BX is in use or is not
an LDT selector. Use function 0001h to free the descriptor. The first 10h (16
decimal) descriptors must be reserved for this function and may not be used
by the host. If another application has already loaded then some of these
descriptors may be in use.
HS
... How come pizza gets to your house faster than the police?