Äußere Umstände für Programme beachten

Um die Quelltextlänge soweit als möglich reduzieren zu können, muß man sich über einige äußere Umstände im Klaren sein, die bei jedem Start eines Programmes erfüllt sind.

Als Programmtyp verwenden wir ausschließlich die kompakten COM-Programme, alleine schon deshalb, weil der Debugger keine EXE-Programme übersetzen kann. Weitgehend bekannt, doch selbst von professionellen Programmierern häufig nicht beachtet, ist die Tatsache, daß beim Start dieser COM-Programme alle Segmentregister bereits den gleichen Wert besitzen. Um auf Speicherzellen innerhalb des Programmcodes zugreifen zu können, ist es daher nicht erforderlich, zuvor erst die Segmentregister zu laden. Auch eine Initialisierung des Stapelzeigers kann entfallen, weil DOS den Stapel selbständig an das Ende des Programmsegmentes setzt. Der Befehlszähler zeigt zu Beginn auf das Byte an Offset 100h, weil sich im Bereich von 0 bis 0FFh das sogenannte Programm-Segment-Präfix (PSP) befindet. In ihm sind einige Informationen verzeichnet, die das Programm auswerten kann. Andere wieder sind nur für DOS von Bedeutung und sollten nicht verändert werden.

Der wichtigste Inhalt des PSPs ist die Kommandozeile, die ab Offset 80h beginnt. Sie beinhaltet den Text, der dem Programm beim Aufruf als Parameter mitgegeben wurde, beginnend mit dem Zeichen, das umittelbar auf den Programmnamen folgt. Das Byte an Adresse 80h bestimmt die Länge dieser Zeile. Nachfolgend steht der Text selbst, abgeschlossen mit einem Wagenrücklauf (Carriage Return, ASCII 13). Weniger bekannt ist die Tatsache, daß sich auch ab dem Offset 5Ch Teile dieses Parameters befinden. Beim Programmstart formatiert DOS nämlich die ersten beiden Abschnitte des Parameters als zwei sogenannte Dateisteuerblöcke (File Control Blocks, kurz FCBs). Diese Datenstrukturen beginnen an Offset 5Ch und 6Ch und beinhalten eine eventuelle Laufwerksangabe, gefolgt vom Dateinamen (mit Leerzeichen auf 8 Bytes Länge ausgedehnt) und der 3-stelligen Erweiterung. Ist kein Laufwerk angegeben, enthält das Laufwerksfeld den Wert 0, bei »A:« 1, bei »B:« 2 und so fort. In einigen Fällen ist es sehr viel günstiger, diese FCBs anstelle des Original-Parameters an Offset 80h auszuwerten. Es entfällt dann nämlich die Umwandlung in Großbuchstaben oder die Formatierung einer Laufwerksangabe. Zudem wird das Programm dadurch flexibler, weil z.B. ein versehentlich zuviel eingetipptes Leerzeichen zwischen Programmnamen und Parameter ohne Auswirkungen bleibt.

Relativ unbekannt ist auch die Tatsache, daß beim Start jedes COM-Programmes das Register AX einen Wert enthält, der über das Ergebnis dieser Formatieraktion Auskunft gibt. Das Register AL enthält den Wert 0, wenn der erste Parameter eine gültige oder gar keine Laufwerksbezeichnung beinhaltet. Existiert dagegen kein Laufwerk mit der angegebenen Bezeichnung, hat AL den Wert 0FFh. Bei AH gilt das entsprechende für den zweiten Parameter.

Ganz zu Beginn des PSPs (also an Offset 0) befindet sich der Code für die Anweisung »INT 20H«, welche eine von mehreren Möglichkeiten der Programmbeendigung darstellt. Zusätzlich legt DOS oben auf den Stapel vor dem Programmstart ein Datenwort mit dem Inhalt 0 ab. Die einfachste Möglichkeit, ein Programm zu beenden, ist es daher, einen nahen Return (»RET« oder »RETN«) auszuführen, der diesen Wert in den Befehlszähler lädt und somit zum Interrupt 20h verzweigt. Dieser Befehl belegt nur ein einziges Byte und kommt der Programmstruktur zugute, weil eine Return-Anweisung immer auf das Ende einer Prozedur hindeutet. Alternativ dazu kann ein Programm auch direkt mit der Anweisung »INT 20h« beendet werden. Das ist dann anzuraten, wenn das Programmende zu einem Zeitpunkt erfolgen soll, an dem sich der Stapel nicht im selben Zustand wie beim Programmstart befindet, wie zum Beispiel in einem Unterprogramm. Soll das Programm ein 8-Bit-Ergebnis zurückliefern, das in einer Stapeldatei mit der Anweisung »IF ERRORLEVEL …« abgefragt werden kann, muß es sich der Funktion AH=4Ch des DOS-Interrupts 21h bedienen. Das Register AL beinhaltet dabei den 8-Bit-Ergebniscode.

Benötigt das Programm zusätzlichen dynamischen Speicher, kann es ohne weiteres auf Speicherzellen zurückgreifen, die sich zwischen dem letzten Byte des Programmcodes und dem Stapel befinden. Denn COM-Programmen teilt DOS automatisch den gesamten verfügbaren Systemspeicher zu, sodaß im Programmsegment in der Regel volle 64 KByte Speicher zur Verfügung stehen, abzüglich der 256 Byte für das PSP, möglichst einiger hundert Byte für den Stapel sowie der bei unseren Tips maximal rund 200 Byte für den Programmmcode. Lediglich in den Fällen, in denen die Menge des verfügbaren Speichers kleiner als 64 KByte ist, muß das Programm mit weniger zurechtkommen. Weil aber bei sowenig Speicher auf den meisten PCs sowieso »nichts mehr geht«, sich also praktisch keine Anwendung mehr starten läßt, ist es auch nicht zwingend erforderlich, die Speichermenge zu überprüfen. Bis auf wenige Ausnahmen kommen alle unsere Tips mit weniger als rund 3 KByte verfügbarem Speicher zurecht – ein Extremfall, der im normalen PC-Alltag sowieso nie eintreten wird.

Quelle: 200 Utilities für PC-/MS-DOS von Gerhard Schild und Thomas Jannot

💡 Sie haben einen Linkedin-Account? Dann können Sie meinen Newsletter „Der 18-Jährige, der einen Zettel schrieb und verschwand“ abonnieren ✔︎ 

Matomo