home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* EXECDEMO.PAS *)
- (* (c) 1991 Gerd Cebulla & TOOLBOX *)
- (* Turbo-Pascal ab Version 4.0 oder Quick-Pascal *)
- (* ------------------------------------------------------ *)
- PROGRAM ExecDemo;
-
- USES Dos;
-
- PROCEDURE Execute(Name : PathStr; Params : ComStr);
-
- { Die folgende Prozedur bringt die Fragmentliste der }
- { Turbo-Pascal-Heapverwaltung in Sicherheit, gibt den }
- { unbenutzten Teil des Heap frei und ruft anschließend }
- { das Programm "Name" mit den Kommandozeilenparametern }
- { "Params" auf. }
- { "Name" kann optional einen Laufwerksbezeichner }
- { und/oder einen Suchpfad enthalten. Nach erfolgtem }
- { Programmaufruf wird die Speicherbelegung auf die }
- { Originalwerte zurückgesetzt. Der Fehlerstatus läßt }
- { sich wie üblich der Systemvariablen DosError ent- }
- { nehmen, die folgende Werte enthalten kann: }
- { 0 = alles o.k. }
- { 2 = Datei nicht gefunden }
- { 3 = Verzeichnis nicht gefunden }
- { 8 = nicht genug Hauptspeicher }
- VAR
- Regs : Registers;
- FragLen,
- FragParas,
- ParasAlt,
- ParasNeu : WORD;
- BEGIN
- IF Ofs(FreePtr^) = 0 THEN
- FragLen := 0 { keine Fragmentliste vorhanden }
- ELSE BEGIN
- FragLen := $10000 - Ofs(FreePtr^);
- { Länge der Fragmentliste in Byte berechnen }
- Move(FreePtr^, HeapPtr^, FragLen);
- { Fragmentliste an Anfang des freien Heap kopieren }
- END;
- FragParas := Succ(FragLen DIV 16);
- { Länge der Fragmentliste in Paragraphen }
- ParasAlt := Seg(FreePtr^) + $1000 - PrefixSeg;
- { derzeit vom Programm belegter Speicher }
- ParasNeu := Succ(Seg(HeapPtr^) + FragParas - PrefixSeg);
- { tatsächlich benötigter Speicher }
- Regs.AH := $4A; { Speichergröße ändern }
- Regs.BX := ParasNeu; { BX = Speichergröße/Paragraphs }
- Regs.ES := PrefixSeg; { ES zeigt auf Programmanfang }
- MsDos (Regs); { nicht benötigten Speicher freigeben }
-
- {$IFNDEF VER40 (SwapVectors erst ab Turbo 5.0 definiert}
- SwapVectors; { DOS-Vektoren reinstallieren }
- {$ENDIF}
- Exec(Name, Params); { Kindprogramm aufrufen }
- {$IFNDEF VER40 }
- SwapVectors; { Turbo-Vektoren zurück }
- {$ENDIF}
-
- Regs.AH := $4A; { Speichergröße ändern }
- Regs.BX := ParasAlt;
- Regs.ES := PrefixSeg;
- MsDos(Regs); { freigegebenen Speicher zurückholen }
- IF Regs.Flags AND FCarry <> 0 THEN BEGIN
- { Carry gesetzt => Speicher konnte }
- { nicht zugeteilt werden }
- WriteLn('Fraktaler FEHLER: Das aufgerufene Programm '+
- 'hat die Speicherorganisation verändert!');
- Halt (1); { Programmabbruch }
- END;
- IF FragLen > 0 THEN
- Move(HeapPtr^, FreePtr^, FragLen);
- { Fragmentliste zurückkopieren }
- END;
-
-
- (* ------------------------------------------------------ *)
- (* Das folgende Programm demonstriert die Verwendung der *)
- (* Prozedur "Execute" anhand des Aufrufs einer DOS-Shell *)
- (* und veranschaulicht, daß trotzdem noch der volle Heap *)
- (* verfügbar ist. *)
- (* Achtung: Da dieses Programm die Speicherorganisation *)
- (* manipuliert, sollte es *NICHT* von der integrierten *)
- (* Entwicklungsumgebung aus gestartet werden! *)
-
- TYPE
- BigArray = ARRAY [1..60000] OF BYTE;
- BigArrayPtr = ^BigArray;
- VAR
- Big : ARRAY [1..10] OF BigArrayPtr;
- Index : BYTE;
- BEGIN
- WriteLn('MemAvail = ', MemAvail, ' Byte');
- Index := 0;
- WHILE MaxAvail > SizeOf (BigArray) DO BEGIN
- Inc(Index);
- New(Big[Index]);
- WriteLn(Index, '. dynamische Variable erzeugt; ',
- 'MemAvail = ', MemAvail);
- END;
- FOR Index := Index DOWNTO 1 DO BEGIN
- Dispose(Big[Index]);
- WriteLn(Index, '. dynamische Variable freigegeben; ',
- 'MemAvail = ', MemAvail);
- END;
- WriteLn;
- WriteLn('Wie man sieht, lassen sich beliebige ',
- 'Operationen auf dem Heap durchführen.');
- Write ('Trotzdem ist es noch möglich, ein anderes ',
- 'Programm aufzurufen. Zur Demonstration');
- Write ('wird jetzt der DOS-Kommandointerpreter ',
- 'geladen. Geben Sie beliebige Befehle ein,');
- WriteLn('und verlassen Sie ihn mit EXIT ...');
-
- {$IFNDEF VER40 - GetEnv erst ab Turbo 5.0 implementiert }
- Execute(GetEnv('COMSPEC'), '');
- {$ELSE (V4.0: annehmen, daß sich COMMAND.COM im }
- { Suchpfad befindet). }
- Execute('COMMAND.COM', '');
- {$ENDIF}
- WriteLn('Zurück in ExecDemo ...');
- WriteLn('DosError = ', DosError);
- END.
- (* ------------------------------------------------------ *)
- (* Ende von EXECDEMO.PAS *)
-
-