Module Entry and Exit Code

Each module (program or unit) needs some initialization and finalization: entry and exit code. For executable programs this function generates the following:
  • a call to initialize program environment
  • if at least one module was compiled with N+ it generates a call to initialize FPU emulator: if program was compiled with E+ it generates a call to initialize software emulator if no FPU if found, otherwise it generates a call to initialize dummy emulator to use FPU instructions.
  • it generates a call to initialization code for each used unit
Finally for programs and units this procedure creates stack frame.
Function GenerateModuleEntryCode: Word;
Var UnitHeader: PUnitHeader;
    UnitHeaderRec: PtrRec absolute UnitHeader;
    NumberOfUnitsWithInitialization, N, Segment: Word;
begin
  If SourceType < stUnit then
    begin
      GenerateInstruction_CALL_FAR (SysProc_InitTurbo);
      UnitHeader := Ptr (LastLoadedUsedUnit, 0);
      Repeat
        If ufInstructions80x87 in UnitHeader^.Flags then
          begin
            If Emulation80x87 in ModuleCompilerSwitches then GenerateInstruction_CALL_FAR (SysProc_InitEM86)
              else GenerateInstruction_CALL_FAR (SysProc_InitEM87);
            Break;
          end;
        UnitHeaderRec.Seg := UnitHeader^.PreviousUnitSegment;
      until UnitHeaderRec.Seg = 0;
      UnitHeader := Ptr (LastLoadedUsedUnit, 0);
      NumberOfUnitsWithInitialization := 0;
      While UnitHeader^.PreviousUnitSegment <> 0 do
        begin
          UnitHeaderRec.Seg := UnitHeader^.PreviousUnitSegment;
          If PProceduresBlockRecord (Ptr (UnitHeaderRec.Seg,
                                          UnitHeader^.BlockOffset [stProcedures]))^.ProgramCodeBlockRecordOffset <> $FFFF then
            begin
              Inc (NumberOfUnitsWithInitialization);
              Asm
                LES     DI, UnitHeader
                PUSH    ES
              end;
            end;
        end;
      For N := 1 to NumberOfUnitsWithInitialization do
        begin
          GenerateInstruction_Byte (CALL_FAR);
          Asm
            POP    Segment
          end;
          UnitHeaderRec.Seg := Segment;
          GenerateReference (Segment, 0, 0, [rfSegment, rfOffset]);
        end;
    end;
  CreateStackFrame;
  GenerateModuleEntryCode := EndSubroutine;
end;
This function generates code to destroy stack frame and then if unit is compiled it generates return instruction from initialization code (RETF) otherwise it generates code to halt the program.
Function GenerateModuleExitCode: Word;
begin
  DestroyStackFrame;
  If SourceType >= stUnit then GenerateInstruction_Byte (RETF) else
    begin
      GenerateInstruction_Word (XOR_AX_AX);
      GenerateInstruction_CALL_FAR (SysProc_HaltTurbo);
    end;
  GenerateModuleExitCode := EndSubroutine;
end;
 
 
 
© 2017 Turbo Pascal | Privacy Policy