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;