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 withE+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;