home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
pascal
/
library
/
windows
/
pmldt
/
pmldt.pas
Wrap
Pascal/Delphi Source File
|
1993-02-04
|
12KB
|
310 lines
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