Press enter to see results or esc to cancel.

Creating References

Whenever Turbo Pascal needs to reference anything that doesn’t have fixed location, i.e. its address is not known yet like variables, typed constants or procedures, the compiler generates intermediate code reference record which contains all information to later resolve the reference.

Procedure GenerateReference (Segment, BlockRecord, RefOfs: Word; RefFlags: TReferenceFlagSet);
Var ReferencedUnitRecord: Word;
begin
  ReferencedUnitRecord := AddReferencedModule (Segment);
  With PIntermediateCodeRecord (IncreaseSymbolTable (stIntermediateCode, 7))^ do
    begin
      RecordType := icReference;
      ReferencedUnitRecordOfs := ReferencedUnitRecord or Word (RefFlags);
      ReferencedBlockRecordOfs := BlockRecord;
      ReferencedOfs := RefOfs;
    end;
end;

All referenced modules are kept in a symbol table.

Function AddReferencedModule (ReferencedModuleSegment: Word): Word;
Var ReferencedModuleRecord: PReferencedModulesBlockRecord;
    ReferencedModuleRecordOfs: Word absolute ReferencedModuleRecord;
    UnitNameIdentifier: PIdentifier;
begin
  ReferencedModuleRecord := Ptr (SymbolTable [stReferencedModules].Segment, 0);
  While ReferencedModuleRecordOfs <> SymbolTable [stReferencedModules].NextRecordOffset do
    begin
      If ReferencedModuleRecord^.ModuleSegment = ReferencedModuleSegment then
        begin
          AddReferencedModule := ReferencedModuleRecordOfs;
          Exit;
        end;
      Inc (ReferencedModuleRecordOfs, ReferencedModuleRecord^.UnitName.Len + 5);
    end;
  If ReferencedModuleRecordOfs >= $1000 then Error (TooManySymbols);
  UnitNameIdentifier :=                      { ReferencedModuleRecord Offset must be < $1000 to add flags in highest nibble }
    PIdentifier (Ptr (ReferencedModuleSegment, PUnitHeader (Ptr (ReferencedModuleSegment, 0))^.UnitNameIdentifierOffset));
  ReferencedModuleRecord := IncreaseSymbolTable (stReferencedModules, UnitNameIdentifier^.Name.Len + 5);
  With ReferencedModuleRecord^ do
    begin
      ModuleSegment := ReferencedModuleSegment;
      rmrW2 := 0;
      UnitName.Str := UnitNameIdentifier^.Name.Str;
    end;
  AddReferencedModule := Ofs (ReferencedModuleRecord^);
end;