unit gdt; interface uses util; type TSegementDescriptor = bitpacked record limit_low : WORD; base_low : WORD; access : Byte; limit_n_flags : Byte; base_high : Byte; end; PSegmentDescriptor = ^TSegmentDescriptor; var GDTarr : array of TSegementDescriptor; GDTptr : PSegmentDescriptor; GDT_length : integer = 0; procedure init(); procedure create(base : dword; limit : dword; flags : byte); implementation procedure init(); var data_addr : dword; begin GDTptr := @GDTarr[0]; data_addr := (@GDTarr[2] - @GDTarr[0]) shr 16; create($0000, $0000, $00); //null segment / GDT pointer create($0000, $FFFF, $9A); //code descriptor create($0000, $FFFF, $92); //data descriptor asm LGDT GDTptr MOV AX, data_addr MOV DS, AX MOV SS, AX MOV ES, AX MOV FS, AX MOV GS, AX end; end; procedure create(base : dword; limit : dword; flags : byte); var descriptor : array[0..8] of Byte; descriptor_ptr : ^Byte = @descriptor[0]; s_descriptor : TSegementDescriptor; s_descriptor_ptr : ^TSegementDescriptor = @s_descriptor; begin if limit <= 65536 then begin descriptor[6] := $40 end else begin if (limit and $FFF) <> $FFF then begin limit := (limit SHR 12) -1 end else begin limit := limit SHR 12; end; end; descriptor[6] := $C0; descriptor[0] := limit and $FF; descriptor[1] := (limit shr 8) and $FF; descriptor[6] := limit or ((limit shr 16) and $F); descriptor[2] := base and $FF; descriptor[3] := (base shr 8) and $FF; descriptor[4] := (base shr 16) and $FF; descriptor[7] := (base shr 24) and $FF; descriptor[5] := flags; asm MOV EAX, descriptor_ptr MOV s_descriptor_ptr, EAX end; descriptor_ptr = @descriptor[4]; asm MOV EAX, descriptor_ptr MOV EBX, s_descriptor_ptr ADD EBX, 1 MOV (EBX), EAX end; GDTarr[GDT_length] := s_descriptor; GDT_length := GDT_length + 1; end; end.