Checking Public Identifiers
Turbo Pascal calculates a checksum of public identifiers for every unit to quickly check if something has been changed.
Procedure CalculateIdentifiersChecksum;
Var UnitCounter: Word;
UnitHeader: PUnitHeader;
UnitIdentifier: PIdentifier;
UnitIdentifierRec: PtrRec absolute UnitIdentifier;
UnitIdentifierData: PUnitIdentifierData;
CheckSum, N: Word;
IdWord: PWord;
begin
UnitCounter := 0; { Push And Clear Unit Segments;}
UnitHeader := Ptr (MainSymbolTable.Segment, 0);
UnitIdentifier := Ptr (MainSymbolTable.Segment, UnitHeader^.UnitNameIdentifierOffset);
Repeat
UnitIdentifierData := PUnitIdentifierData (PChar (UnitIdentifier) + UnitIdentifier^.Name.Len + 4);
Asm
LES DI, UnitIdentifierData
PUSH WORD PTR ES:[DI] { UnitIdentifierData^.UnitSegment) }
PUSH DI { Ofs (UnitIdentifierData^) }
end;
UnitIdentifierData^.UnitSegment := 0;
Inc (UnitCounter);
UnitIdentifierRec.Ofs := UnitIdentifierData^.NextUnitIdentifier;
until UnitIdentifierRec.Ofs = 0;
CheckSum := 0;
IdWord := Ptr (MainSymbolTable.Segment, UnitHeader^.PublicIdentifiersListOffset);
For N := 1 to (SymbolTable [stMain].UsedSize - UnitHeader^.PublicIdentifiersListOffset) div 2 do
begin
Asm
MOV AX, CheckSum
ROL AX, 1
MOV CheckSum, AX
end;
Inc (CheckSum, IdWord^);
Inc (IdWord);
end;
If CheckSum = 0 then CheckSum := $FFFF;
UnitIdentifier := Ptr (MainSymbolTable.Segment, UnitHeader^.UnitNameIdentifierOffset);
UnitIdentifierData := PUnitIdentifierData (PChar (UnitIdentifier) + UnitIdentifier^.Name.Len + 4);
UnitIdentifierData^.PublicIdentifiersChecksum := CheckSum;
Asm
LES DI, UnitHeader
MOV CX, UnitCounter
@1:
POP DI
POP WORD PTR ES:[DI]
LOOP @1
end;
end;