Normal segment-based address translation does not apply to the GDT address in the pseudo-descriptor. You must perform the equivalent address translation yourself, by adding DS * 16 to the GDT address in the pseudo-descriptor:

The same 'fixup' process must be done for the IDT pseudo-descriptor before using the LIDT instruction to load the IDT register (IDTR) in the CPU. The fixup code shown in the image above is typical. Here is another approach:

            xor eax,eax
    	mov ax,ds
    	shl eax,16
    	add [gdt_ptr + 2],eax

Though shorter, there are three potential problems with this fragment:

- Requires a 32-bit CPU
- The 32-bit value at [gdt_ptr + 2] must be initialized to 'gdt'
- This code fragment will not work correctly if called more than once

The first of these problems is not serious (who uses 16-bit pmode?). The other two can be addressed with yet another code fragment:

            xor esi,esi
            mov si,ds
            shl esi,4
            lea eax,[esi + gdt]
            mov [gdt_ptr + 2],eax