MZ-Datei

MZ-Datei
Dateiendung: .exe
Magische Zahl: 4D 5A hex
MZ
Erstveröffentlichung: 1981
Art: Ausführbare Dateien (EXE, DLL) für MS-DOS, Windows und die CLR

Der Begriff MZ-Datei leitet sich von einer magischen Zahl in den Verwaltungsdaten am Beginn (Header) einer Programmdatei ab. Eine ausführbare Datei mit der Datei-Endung „EXE“ für das Betriebssystem MS-DOS wird daher auch als „MZ-Datei“ bezeichnet. Der Header wurde später für EXE-Dateien unter Microsoft Windows weiterverwendet und lediglich mit weiteren Informationen ergänzt. Auch DLL-Dateien verwenden den gleichen Header. Weil auch die ursprüngliche Implementation der Common Language Runtime (die Ausführungsschicht von .Net-Framework-Programmern) zunächst für Windows vorgestellt wurde, verwenden auch plattformunabhängige .NET-Core-Binärdateien diesen Header.

Begriff

Es handelt sich bei der magischen Zahl um eine Byte-Folge mit den hexadezimalen Werten 4D und 5A, die den Buchstaben „M“ und „Z“ entspricht. Dies sind die Initialen von Mark Zbikowski, eines langjährigen Softwareentwicklers von Microsoft, der unter anderem an MS-DOS mitgewirkt hat.[1] „MZ“ bildet den Beginn einer Datenstruktur, die entsprechend als „MZ-Header“ bezeichnet wird.

MZ-Header

Der MZ-Header bildet mit einem feststehenden Aufbau den Anfang einer EXE-Programmdatei und beinhaltet Verwaltungsinformationen, die das Betriebssystem zum Laden und Starten des Programms benötigt. Er wird vom Linker bei der Fertigstellung der EXE-Datei anhand deren konkreten inhaltlichen Aufbaus und ggf. weiteren Erfordernissen (z. B. Overlay) mit entsprechenden Daten belegt. Der Header hat folgenden Aufbau:[2]

Offset Anzahl Typ Inhalt
0000h 2 char Kennung 'MZ'
0002h 1 word Bytes in der letzten Page
0004h 1 word Anzahl der 512-Byte Pages
0006h 1 word Anzahl der Einträge in der Relokationstabelle
0008h 1 word Größe des Headers in Paragraphs (16 Bytes)
000Ah 1 word Minimale erforderliche Anzahl von Paragraphs
000Ch 1 word Maximal erforderliche Anzahl von Paragraphs
000Eh 1 word Startwert von SS (Stack Segment Register) relativ zum Programmstart
0010h 1 word Startwert von SP (Stack Pointer)
0012h 1 word Prüfsumme oder 0
0014h 1 dword Startwert von CS:IP (Code Segment und Instruction Pointer) relativ zum Programmstart
0018h 1 word Offset der Relokationstabelle bzw. 40h bei neuen EXE-Formaten (NE, LE, LX, W3, PE etc.)
001Ah 1 word Overlay-Nummer oder 0

Laden und Ausführung

In DOS-Programmen mit der Endung „COM“ findet man den MZ-Header nicht. Sie werden – übernommen vom Betriebssystem CP/M – mit maximal 63,75 KiB (64 KB) Größe am Offset 100h eines Segments in den Speicher geladen und dort ausgeführt. EXE-Programme sind nicht auf ein Segment begrenzt und können an beliebiger Stelle im Speicher geladen werden. Daher sind die Adressen im Code so angelegt, dass die Segmentwerte erst beim Laden zugewiesen werden. Wo dies vorgenommen werden muss, ist in der Relokationstabelle aufgelistet. So wird zunächst aus dem MZ-Header die benötigte Speichergröße errechnet und anschließend der Programmcode ab Ende des Headers aus der Datei an den Anfang des Startsegments geladen. Gemäß der Anzahl der Einträge in der Relokationstabelle wird diese abgearbeitet und die entsprechenden Stellen des Programmcodes im RAM angepasst. Nach Einrichtung des Stacks und Laden von Stacksegment-Register (SS) und Stackpointer (SP) erfolgt die Programmausführung mit einem Sprung nach CS:IP.[2]

Weitere MZ-Nutzung

Die Buchstabenfolge „MZ“ ist auch am Anfang neuerer EXE-Formate (New Executable und Portable Executable) unter OS/2 und Windows sowie in DLLs (Dynamischen Linkbibliotheken) zu finden. Dies rührt daher, dass diese späteren Programme der Einfachheit halber generell ein EXE-Programm im alten DOS-Format als sog. Stub am Dateianfang beinhalten. Damit wird verhindert, dass unter MS-DOS ein EXE-Programm zu starten versucht wird, das nicht für DOS geeignet ist. In diesem Fall wird lediglich der Stub ausgeführt, der im Regelfall so programmiert ist, dass er nur eine einfache Fehlermeldung ausgibt und dann endet. Solche Stubs werden entweder standardmäßig vom Compilersystem oder individuell vom Programmersteller beim Linken eingebunden. Meist handelt es sich um eine kurze Meldung wie „This program cannot run in DOS mode“ (oder ähnlich).

Hexdump einer als Stub genutzten MZ-Datei als Beispiel:

00000000:   4D 5A 50 00 02 00 00 00 04 00 0F 00 FF FF 00 00    MZP.............
00000010:   B8 00 00 00 00 00 00 00 40 00 1A 00 00 00 00 00    ........@.......
00000020:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
00000030:   00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00    ................
00000040:   BA 10 00 0E 1F B4 09 CD 21 B8 01 4C CD 21 90 90    ........!..L.!..
00000050:   54 68 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E    This program can
00000060:   6E 6F 74 20 72 75 6E 20 69 6E 20 44 4F 53 20 6D    not run in DOS m
00000070:   6F 64 65 0D 0D 0A 24 37 00 00 00 00 00 00 00 00    ode...$7........
00000080:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
00000090:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
000000A0:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
000000B0:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
000000C0:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
000000D0:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
000000E0:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................
000000F0:   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00    ................

Außerdem waren auch andere Stub-Varianten in Gebrauch:

  • Bei kleineren Programmen wurde vereinzelt eine reine DOS-Version als Stub im Real Mode realisiert, während eine zweite Version für den Protected Mode unter OS/2 den Hauptteil des EXE-Programms bildete.
  • Zur Überwindung der Speichergrenze bei PCs unter MS-DOS wurden sog. DOS-Extender eingebunden, über die im Protected Mode auf mehr RAM zugegriffen werden konnte.
  • Zudem war es möglich, Programme für den Textmodus mittels sogenanntem Family Application Mode sowohl unter DOS als auch unter OS/2 lauffähig zu machen. In diesem Fall wurde über den Header mit MZ-Kennung eine Bibliothek von Microsoft (Family Application Program Interface, FAPI) eingebunden, die OS/2-Systemaufrufe auf entsprechende DOS-Funktionen umleitete. Es stand zwar nicht der gesamte Funktionsumfang von OS/2 zur Verfügung; erlaubte jedoch diesen „DOS-Programmen“ die Nutzung der Vorteile des modernen Betriebssystems.

Siehe auch

Einzelnachweise

  1. Die Köpfe hinter der Technik unserer Zeit: Craig Barrett. In: cio.de. Abgerufen am 12. Dezember 2020.
  2. a b Christian Baumgarten: Systemnahe Programmierung mit Borland Pascal. Vieweg, Braunschweig/Wiesbaden 1994, ISBN 978-3-322-87239-5.

Weblinks