home *** CD-ROM | disk | FTP | other *** search
- program PMShwLDT; {Windows Tech Journal #28 1/93 +
- The Processor and Coprocessor #96/99 -#311}
-
- uses Objects, WinAPI, Views, Dialogs, App, Drivers, Strings;
-
- type
- PLDTColl = ^TLDTColl;
- TLDTColl = object(TStrCollection)
- constructor Init;
- end;
- PLDTWindow = ^TLDTWindow;
- TLDTWindow = object(TDialog)
- constructor Init;
- end;
- TLDTApp = object(TApplication)
- LDTWindow: PLDTWindow;
- constructor Init;
- end;
-
- AccessedStr = array[0..3] of char;
- CodeDataStr = array[0..3] of char;
- DataWriteStr = array[0..4] of char;
- CodeReadStr = array[0..4] of char;
- ConformingStr = array[0..3] of char;
- UpDownStr = array[0..3] of char;
- PresentStr = array[0..3] of char;
- Bit5Str = array[0..3] of char;
- DefSizeStr = array[0..4] of char;
- GranStr = array[0..3] of char;
-
- TShowDesc = record
- LimitL,
- BaseL: word;
- BaseM,
- AccessRights: byte;
- {code segment data/stack segment
- bit 0 accessed
- bit 1 readable writable
- bit 2 conforming expand down
- bit 3 always 1 always 0
- bit 4 segment type
- bit 5+6 descriptor privilege level
- bit 7 present}
- LimitH_Flags, {80386/486 only, must be 0 on 80286}
- {bit 0/4 LimitH
- bit 5 available
- bit 6 default size 16/32 bits
- bit 7 granularity}
- BaseH: byte; {80386/486 only, must be 0 on 80286}
- end;
-
- LongRemap = record
- case Word of
- 0:(Long: LongInt);
- 1:(LoWord, HiWord: Word);
- end;
-
- const
- Accessed: array[boolean] of AccessedStr = (' Na',' Ac');
- CodeData: array[boolean] of CodeDataStr = (' Da',' Co');
- DataWrite: array[boolean] of DataWriteStr = (' R ',' R/W');
- CodeRead: array[boolean] of CodeReadStr = (' NR',' R');
- Conforming: array[boolean] of ConformingStr = (' C',' NC');
- UpDown: array[boolean] of UpDownStr = (' Up',' Do');
- Present: array[boolean] of PresentStr = (' Nl',' Lo');
- Bit5: array[boolean] of Bit5Str = (' 5f',' 5t');
- DefSize: array[boolean] of DefSizeStr = (' 16b',' 32b');
- {default operands/adress size}
- Gran: array[boolean] of Granstr = (' 1b',' 4k'); {granularity}
-
- function HexB(Dest: PChar; B: Byte): PChar;
- const
- h: array[0..15] of Char = '0123456789ABCDEF';
- begin
- Dest[0] := h[b shr 4];
- Dest[1] := h[b and $0F];
- Dest[2] := #0;
- HexB := Dest;
- end;
-
- function HexW(Dest: PChar; I: Word): PChar;
- begin
- HexB(Dest, Hi(I));
- HexB(@Dest[2], Lo(I));
- HexW := Dest;
- end;
-
- function HexL(Dest: PChar; l:LongInt): PChar;
- var
- lr: LongRemap absolute l;
- begin
- HexW(Dest, lr.HiWord);
- HexW(@Dest[4], lr.LoWord);
- HexL := Dest;
- end;
-
- function GetDescriptor(Selector: Word;
- var ShowDesc: TShowDesc): Boolean; assembler;
- asm
- MOV BX,Selector
- LES DI,ShowDesc
- MOV AX,000BH
- INT 31H
- MOV AX, 0 {keep carry flag intact}
- JC @1
- MOV AX, 1
- @1:
- end;
-
- constructor TLDTColl.Init;
- var
- LDTStr, DumStr: array[0..80] of char;
- DumString: String;
- Loop: word;
- ShowDesc: TShowDesc;
- TotalBase,
- TotalLimit: Longint;
- Typ, DPL: word;
- SomeHandle: Thandle;
- begin
- { SomeHandle:= GlobalAlloc(GMEM_FIXED, 1024000);}
- inherited Init(500, 100);
- for Loop:=0 to $1fff do {1FFF is maximum no. of selectors in LDT}
- begin
- if GetDescriptor((Loop shl 3) or 4, ShowDesc) then
- {4=00000100 is LDT only, bits 0 and 1 are automatically
- 'blanked out' by CPU when it is accessing the DT}
- { if ShowDesc.AccessRights = 0 then
- {is it a segment desc. = 1 or gate desc. = 0 ?}
- with ShowDesc do
- begin
- HexW(LDTStr, Loop);
- StrCat(LDTStr, ' ');
- TotalBase:=Longint(BaseL) or (Longint(BaseM) shl 16) or
- (Longint(BaseH) shl 24);
- Str(TotalBase:10, DumStr);
- StrCat(LDTStr, DumStr);
- StrCat(LDTStr, '/');
- HexL(DumStr, TotalBase);
- StrCat(LDTStr, DumStr);
- StrCat(LDTStr, ' ');
- TotalLimit:=Longint(LimitL) or (Longint(LimitH_Flags and $0F) shl 16);
- HexL(DumStr, TotalLimit);
- StrCat(LDTStr, @DumStr[3]); {only 20 bits can be significant}
- StrCat(LDTStr, Accessed[AccessRights and $01 > 0]);
- if AccessRights and $08 > 0 then {code or data?}
- begin
- StrCat(LDTStr, CodeData[True]);
- StrCat(LDTStr, CodeRead[AccessRights and $02 > 0]);
- StrCat(LDTStr, Conforming[AccessRights and $04 > 0]);
- end
- else begin
- StrCat(LDTStr, CodeData[False]);
- StrCat(LDTStr, DataWrite[AccessRights and $02 > 0]);
- StrCat(LDTStr, UpDown[Typ and $04 > 0]);
- end;
- StrCat(LDTStr, ' ');
- DPL:=(AccessRights shr 5) and $03;
- HexW(DumStr, DPL);
- StrCat(LDTStr, DumStr);
- StrCat(LDTStr, Present[AccessRights and $80 > 0]);
- StrCat(LDTStr, Bit5[LimitH_Flags and $20 > 0]);
- StrCat(LDTStr, DefSize[LimitH_Flags and $40 > 0]);
- StrCat(LDTStr, Gran[LimitH_Flags and $80 > 0]);
- DumString:=StrPas(LDTStr);
- Insert(NewStr(DumString));
- end;
- end;
- StrCopy(LDTStr, 'Number of selectors displayed: ');
- Str(Count, DumStr);
- StrCat(LDTStr, DumStr);
- DumString:=StrPas(LDTStr);
- Insert(NewStr(DumString));
- end;
-
- constructor TLDTWindow.Init;
- var
- R: TRect;
- Control: PView;
- ScrollBar: PScrollBar;
- begin
- R.Assign(0, 0, 80, 23);
- inherited Init(R, 'Protected Mode (Borland) LDT List Window');
- R.Assign(78, 1, 79, 22);
- New(ScrollBar, Init(R));
- Insert(ScrollBar);
- R.Assign(1, 1, 78, 22);
- Control := New(PListBox, Init(R, 1, ScrollBar));
- Insert(Control);
- PListBox(Control)^.NewList(New(PLDTColl, Init));
- end;
-
- constructor TLDTApp.Init;
- begin
- inherited Init;
- LDTWindow := New(PLDTWindow, Init);
- InsertWindow(LDTWindow);
- end;
-
- var
- LDTApp: TLDTApp;
- begin
- LDTApp.Init;
- LDTApp.Run;
- LDTApp.Done;
- end.
-
- A few typical screens on my system looks like:
-
- ╔═[■]══════════════ Protected Mode (Borland) LDT List Window ═
- ║ 00BA (= number of selectors displayed)
- ║ 0011 188784/0002E170 0FFFF Ac Co R C 0003 Nl 16b 1b
- ║ 0012 191616/0002EC80 00A8F Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0013 194304/0002F700 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0014 188528/0002E070 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0015 188336/0002DFB0 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0016 2185296/00215850 0255F Ac Co R C 0003 Nl 16b 1b
- ║ 0017 646704/0009DE30 021CF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0018 2185296/00215850 0255F Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0019 2185296/00215850 0255F Na Da R/W Up 0003 Nl 16b 1b
- ║ 001A 2209200/0021B5B0 00FFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 001B 188784/0002E170 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 001C 2213296/0021C5B0 0C2AF Ac Co R C 0003 Nl 16b 1b
- ║ 001D 2263120/00228850 06DBF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 001E 2213296/0021C5B0 0C2AF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 001F 245168/0003BDB0 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0020 0/00000000 00000 Na Da R/W Up 0003 Nl 16b 1b
- ║ 0021 2213296/0021C5B0 0C2AF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0022 2286000/0022E1B0 0032F Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0023 2286816/0022E4E0 0056E Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0024 2288208/0022EA50 00A00 Ac Da R/W Up 0003 Nl 16b 1b
-
- ║ 0025 2290768/0022F450 001AE Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0026 0/00000000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
- ║ 0027 0/00000000 FFFFF Na Da R/W Up 0003 Nl 16b 4k
- ║ 0028 1024/00000400 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0029 655360/000A0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
- ║ 002A 720896/000B0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
- ║ 002B 753664/000B8000 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 002C 786432/000C0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
- ║ 002D 851968/000D0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
- ║ 002E 917504/000E0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
- ║ 002F 983040/000F0000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
- ║ 0030 4448/00001160 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0031 3693024/003859E0 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0032 2213296/0021C5B0 0C2AF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0033 3700288/00387640 01C5F Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0034 4119280/003EDAF0 01FFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0035 167936/00029000 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0036 167744/00028F40 0FFFF Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0037 0/00000000 0FFFF Na Da R/W Up 0003 Nl 16b 1b
- ║ 0038 4127472/003EFAF0 00301 Ac Da R/W Up 0003 Nl 16b 1b
- ║ 0039 1414792540/5454055C 0055C Na Da R/W Up 0003 Nl 16b 1b
-
- The selector with sequential number 2B is the one for the PMode
- variable SegB800.
-
- Selector number 39 is a mystery to me.
- Its BaseH is NOT zero as it should be.
- On my system there are four (39, 69, 8B and BB) of those selectors.
- In case anybody has an explanation for this I would like to know.
-
- The last three columns in the display are not really relevant as they
- are based on a zero value of that part of the descriptor.
- This can't be different as the program operates in the 286 segmented
- memory model.
-
- The memory allocation on line 121 can be varied to see different effects.
-
- Cees Binkhorst/Febr. 2, 1993
- CIS 100016, 3552
-
- Selector number 39 is no longer a mystery as it is a selector pointing
- to a segment that is NOT LOADED.
- This should be indicated by bit 7 of the AccessRights.
- In the original version of PMShwLDT this bit was tested against $8000,
- which obviously is a byte too far, and should be tested against $80.
- It will now correctly show if a segment is present or not.
-
- If a segment is not present, only the field AccessRights is showing
- values that are predetermined by the manufacturer of the CPU.
- The other parts of the descriptor are used by the system implementors
- (Borland in this case) as they see fit and have, as far as I know,
- not yet been documented.
- It is normally used in 'virtual memory' situations to swap memory to disk
- and bring it back through a processor exception in case the descriptor is
- accessed. Room for experiments to find the meaning of the figures!
-
- To be complete I have also included bit 5 in the field LimitH_Flags in the
- display . This bit is 'available to programmers' but because of the
- 286-segmented nature of the DPMI implementation not relevant as it must
- be zero.
-
- The new display now looks like:
- ╔═[■]══════════════ Protected Mode (Borland) LDT List Window ════
- ║ 00AE (= number of selectors displayed)
- ║ 0011 188784/0002E170 0FFFF Ac Co R C 0003 Lo 5f 16b 1b
- ║ 0012 191616/0002EC80 00A8F Ac Da R/W Up 0003 Lo 5f 16b 1b
- ║ 0013 194304/0002F700 0FFFF Ac Da R/W Up 0003 Lo 5f 16b 1b
- ║ 0014 188528/0002E070 0FFFF Ac Da R/W Up 0003 Lo 5f 16b 1b
- ║ 0015 188336/0002DFB0 0FFFF Ac Da R/W Up 0003 Lo 5f 16b 1b
- ║ 0016 2185296/00215850 0255F Ac Co R C 0003 Lo 5f 16b 1b
- ║ 0017 646704/0009DE30 021CF Ac Da R/W Up 0003 Lo 5f 16b 1b
- ...
- ║ 0037 0/00000000 0FFFF Na Da R/W Up 0003 Lo 5f 16b 1b
- ║ 0038 4127472/003EFAF0 00301 Ac Da R/W Up 0003 Lo 5f 16b 1b
- ║ 0039 1414792540/5454055C 0055C Na Da R/W Up 0003 Nl 5f 16b 1b
- ... present bit ^
-
- Cees/Febr. 3, 1993