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