Wie kriege ich Hauptspeicher?_20141113114814

Transcription

Wie kriege ich Hauptspeicher?_20141113114814
http://www.askos.de/ram/index.html#msdos
Updated 20.07.2004.
Wie kriege ich Hauptspeicher?
Mail an schatz@askos.de
Aus Anlaß 20 Jahre PC-Programmierung: Wie kriege ich Hauptspeicher?
Meiner lieben Ursl gewidmet
Beim Wort "Hauptspeicher" denken viele sicher an RAM. Die RAM-Zahl prangt einem in jeder PC-Zeitungsbeilage
entgegen: Je mehr, desto besser, mindestens MB, mindestens dreistellig und Speicher ist etwas, was manchmal teuerer,
meistens aber immer billiger wird. Aus Sicht des Programmierers ist Hauptspeicher das Papier, auf dem er schreibt, das
Wasser, in dem er schwimmt. Hauptspeicher ist der elektronische Speicher für Programme und Daten. Heute wird er vom
Programmierer nur noch selten wahr genommen. Aber das war nicht immer so. Hier einige Erinnerungen und Gedanken an
die letzten 20 Jahre "Speicher und PC".
Das ist ein Text, der in meiner Freizeit entstanden ist. Ich habe mich zwar bemüht, möglichst genau zu sein, aber mancher wird sicher
hier und da noch über kleinere Fehler stolpern. Andere Fehler entstehen durch Verkürzungen, da dies ein Text zum Schmökern, kein
Nachschlagewerk werden sollte. Insbesondere bin ich bei den Adressierungstechniken des 8088 und beim A20-Gate nicht in die Details
gegangen. Natürlich ist dieser Text auch durch meinen spezifischen Programmiererhintergrund beschränkt, der eng mit der Firma
Borland verknüpft ist. Beispiele für Sprachen und Entwicklungstools, die ich nie benutzt habe, werden sich hier nicht finden.
Für Hinweise auf Fehler bin ich sehr dankbar. Über Berichte eigener Erfahrungen mit dem "Speicherabenteuer" PC würde ich mich sehr
freuen!
Inhalt
Einleitung
1980 - der Ur-PC
Adressgrenzen
Bank Switching
Der 8088 des Ur-PC
Von 16K bis 1 MB
MS-DOS und die 640K-Grenze
Die 1 MB-Grenze
13.11.2014 11:48
1 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Der 640K-Kampf
Der IBM AT
EMS
XMS
80386-PC's
DOS-Extender, DPMI und VCPI
Die Grenzen der "DPMI-Zeit
Win 32s und 48-bit-DPMI
32-Bit-Programmierung, Win9x/ME/NT/2000
Überblick über die Hauptspeichermodelle der Windowsversionen
Hauptspeichermanagement mit Paging
Jenseits 32 Bit
Von 36 auf 64 Bit Bit
Übergänge
Links zum Thema
Einleitung
Hauptspeicher ist der elektronische Speicher für Programme und Daten. Ein Programm muss im Hauptspeicher liegen, damit es
ausgeführt werden kann und Daten müssen im Hauptspeicher liegen, wenn sie das Programm benutzen soll. Am einfachsten macht
man sich dies an einem Editor-Programm klar. Ein Editor ist ein Programm zum Schreiben von Texten ohne Layout. Die Date, mit der
der Editor operiert, ist der Text. Damit Text bearbeitet werden kann, muss er in den Hauptspeicher geladen werden. Nun gibt es relativ
grosse Texte, z.B. wenn Messdaten in Textformat (ASCII-Format) abgespeichert werden. Da kann es selbst heute noch passieren, dass
der Editor nach langer Ladezeit meldet: "Kein Hauptspeicher mehr". Oder er stürzt gleich ab. Für den Programmierer ist das
Ansprechen und Organisieren des Hauptspeichers prinzipiell ein alltägliches Geschäft. Man muss ja auch nicht lange überlegen, WIE
man ein Blatt Papier beschreibt. Deklarieren, Reservieren, Initialisieren und los geht's. Oft ist es sogar noch einfacher: In der
Programmiersprache BASIC muss man im Zweifelsfall gar nichts tun. Man nutzt einfach Namen, meint damit Variablen und BASIC
ordnet den Hauptspeicher zu. Wieso ein Artikel zu diesem Thema? Ein Besonderes der PC-Geschichte ist: Fast immer in den letzten 20
Jahren, wenn man auf einem PC ein größeres Projekt programmierte, rumste man unweigerlich gegen eine Fehlermeldung: "Kein
Hauptspeicher mehr" - obwohl noch Massen davon vorhanden waren. Immer dann, wenn man gerade richtig am Schreiben und
Entwickeln war, sagte einem der PC: "So, schluss jetzt, kein Platz mehr!". Man muss sich das mal als Romanschreiber vorstellen: Man
13.11.2014 11:48
2 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
ist gerade richtig in Fahrt, kommt an die richtig spannende Stelle und mitten drin stellt man fest, dass 400 der 500 Blatt Papier, die man
sich vorher besorgt hat, mit einer Kunststoffbeschichtung versehen sind, die nicht beschreibbar ist. Warum konnte sich so eine
Maschine durchsetzen? Mac-, Atari-, Amiga- und Unix-Programmierer können hier nur den Kopf schütteln. Ich habe selbst jahrelang auf
dem Amiga programmiert und wenn dort der rote Kasten "Heap Overflow" auftauchte, dann war der Speicher wirklich aus, da half nur
der Gang zum Händler, um sich ein Erweiterungsmodul zu kaufen.
Screenshot des Spiels "Tetris", Urversion von Academy Soft Moskau 1986. Größe: Eine com-Datei mit 24K. Voraussetzungen: IBM PC 4.77 MHz, 64K
RAM. Grafikkarte ist nicht erforderlich.
Nun, meine vielleicht etwas gewagte These ist: Wahrscheinlich hat sich der PC gerade WEGEN dieses Problems durchgesetzt.
Genauer gesagt: Wegen seiner restriktiven Kompatibilitätspolitik. Sie sorgte einerseits dafür, dass heute viele 20 Jahre alten
Programme noch auf den neuesten Boliden laufen (z.B. Tetris in Urform!). Sie brachte andererseits unter anderem genau dieses
Speicherproblem mit sich. Vielleicht war es nur diese restriktiven Kompatibilitätspolitik, die dem PC die Durchsetzung vor allen anderen
13.11.2014 11:48
3 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Mikrocomputer-Typen brachte. Die furiosen Kunstgriffe, das Unvereinbare zu vereinen, Hardwareerweiterung und 100%-Kompatibilität
zu verbinden, begleiteten den PC von Anfang an, machten ihn zu einem wundersamen Chamäleon, technik-ästhetisch zu einer
Katastrophe, verliehen ihm aber aus der Sicht des Programmierers ein Abenteuerflair und bildeten mit der Zeit lebende Geschichte.
Wenn ich heute als Programmierer gegen einen "kein Hauptspeicher"-Fehler rumpse, obgleich ich nicht einmal 5% des verfügbaren
Speichers belege, dann begleitet den Ärger ein nostalgisches Lächeln und die Feststellung, dass Programmieren nur halb so schön
wäre, müßte ich diese Kollisionen mit der PC-Geschichte entbehren.
1980 - der Ur-PC
Versetzen wir uns in die Zeit, als das Design des PC's festgelegt wurde. IBM war Marktführer im Bereich Grossrechner (und ist es heute
noch). Der PC war als Versuchsballon geplant, um ein Einstiegspotential in den Mikrocomputermarkt aufzubauen. Im Vergleich zu
Grossrechnern war ein PC - wie auch immer - in Bezug auf professionelle Anwendungen ein Spielzeug. Grossrechnerersatz für den
daheim arbeitenden Ingenieur, Textverarbeitungsmaschine, grosser, programmierbarer Taschenrechner.
Zu diesem Zeitpunkt gab es auf dem PC-Markt:
CP/M-Systeme. CP/M war der Vorläufer von MS-DOS, welcher der Vorläufer von Windows
war. CP/M lief auf Maschinen mit Z80-Prozessor, 64K RAM und Diskettenlaufwerk. CP/M
war wichtig, denn die bei weitem verbreiteste Textverarbeitung, Wordstar, lief
(weithingehend) nur unter CP/M. Wir werden sehen, dass manche HauptspeicherFehlermeldungen, die wohl auch noch in der Windows-XP-Ära auftauchen, genau auf diese
CP/M-Systeme zurückgehen.
Apple-DOS-Systeme. Im Prinzip die gleiche Funktionalität wie CP/M-Systeme, aber nicht
so weit verbreitet.
CBM-Systeme von Commodere. Gleiche Hardware-Charakteristik, aber geschlossene
Systeme und kein maschinenübergreifendes Betriebssystem.
13.11.2014 11:48
4 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
IBM 5100 von 1976, einer der ersten Mikrocomputer mit Textanzeige. Grundausbau: 64x16-Zeichen-Display, 16K, BASIC oder APL, ca. 9000$
Der IBM PC war nicht wirklich der erste Mikrocomputer von IBM. Vorher hatte es eine ganze Reihe von Entwicklungen seit 1975
gegeben, die aber alle reine IBM-Eigenentwicklungen ohne Bestandteile fremder Hersteller und alle sehr teuer waren und alle von den
Verkaufszahlen das Kleinserienstadium nie überschritten. Daran hatte IBM erkannt: Die Hardwareleistung allein ist kaum interessant.
Wichtig sind Preis und Kompatibilität.
IBM wollte nun mit seinem PC
CP/M-kompatibel sein
eine Möglichkeit bieten, die 64K-Hauptspeichergrenze zu sprengen.
Der PC sollte der Universal-Mikro für ein breites Spektrum und Anwender sein. Sowohl der gelegentliche Programmierer, der maximal
50 Zeilen BASIC schreibt, als auch der Leistungsanwender, der eine kleine Firmendatenbank damit betreiben wollte und mit den 64K
längst nicht zurecht kam. Daher entschied sich IBM für einen Intel 8088-Prozessor, der genau diesen Spagat ausführen konnte. Da viele
spätere Probleme mit der speziellen Adress-Architektur dieses Prozessors - dem Urvater aller PC-Prozessoren - zu tun haben, möchte
ich die folgenden Abschnitte dem Thema "Adressierung" widmen.
Adressgrenzen
Hauptspeicher ist eine Menge von elektronischen Speicherbits, angeordnet in Bytes zu je 8 Bit. Der Prozessor spricht jedes Byte mit
einer Zahl an. Das Byte Nr. 0 mit 0, das Byte Nr. 1 mit 1 usw. Diese Zahl ist seine Adresse. Hat der Hauptspeicher 1024 Bytes, so
gehen die Adressen von 0 bis 1023. Die Speicherbytes werden über die Adressleitungen angesprochen, den s.g. Adressbus, der die
einzelnen Bestandteilen des PC's (Prozessor, Speicher, Controler usw.) verbindet. Jede Leitung kann 1 Bit einer Speicheradresse
13.11.2014 11:48
5 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
darstellen. Hat ein Adressbus drei Leitungen, ist er 3 Bit breit und kann 2^3 = 2 hoch 3 = 8 Bytes adressieren. Hat er 10 Bit, dann 2 ^ 10
= 1024 Bytes. Jedes zusätzliche Bit verdoppelt also die Anzahl möglicher Adresssen. Die 1980 üblichen Prozessoren in
Mikrocomputern hatten 16-bit breite Adressbusse, was 2 ^ 16 = 65536 = 64K Bytes ermöglichte. Warum fügte man eigentlich nicht
einfach eine 17. Leitung dazu, als der Platz knapp wurde? Und dann eine 18. usw.? Wo liegt eigentlich das Problem?
Ein Prozessor ist ein Elektronik-Chip mit vielen Beinchen. Ein damaliger 8-Bit-Prozessor hatte ca. 30.
8 davon dienen dazu, den Prozessor zu steuern, 16 andere gehörten zum Adressbus. Mit 8 Bits kann man 256 verschiedene
0/1-Kombinationen herstellen. Daher kann man bei einem 8-Bit-Prozessor 256 verschiedene "Knöpfe" drücken, Befehle erteilen. So ein
Prozessorbefehl heisst "Maschinenbefehl" und die Gesamtheit der Befehle "Maschinensprache". Jeder Prozessor spricht seine eigene
Maschinensprache. Anwendungsprogramme werden als Maschinenspracheprogramme, s.g. Binaries ausgeliefert. (Erkennbar an der
Endung .exe oder .com). Die Binaries müssen also auf der jeweiligen Maschine funktionieren. Viele Maschinenbefehle nutzen
Hauptspeicheradressen. Der Befehl "Lade den Inhalt von Adresse XXXX ins Register D1" ist eine Folge von 3 Bytes: Zuerst der
eigentliche Befehl und dann die beiden Adressbytes. Und das ist der Knackpunkt. Da ein Binary aus Bytes besteht, müssen seine
Adressangaben in Bytes erfolgen. Das mit dem 17. Bit funktioniert also nicht. Entweder es sind 8 (1 Byte), 16 (2 Bytes), 24 (3 Bytes), 32
(4 Bytes) oder ... Leitungen. Die maximale Anzahl der mit den bisherigen Adressbytes anzusprechenden Bytes nennt man den
"Adressraum" - egal, ob der konkrete Computer faktisch diesen Speicher installiert hat oder nicht. Hat man den ganzen Adressraum mit
Speicher ausgestattet und es immer noch nicht genug ist, dann hat man ein ernsthaftes Problem. Nicht, daß es zu teuer wäre, die
zusätzlichen Leitungen zu bauen. Das muß man ja gar nicht. 16 Adressbits im Programm können auch nur 9 Adressleitungen
entsprechen - die anderen Adressen sind dann eben phyikalisch nicht belegt. Aber es muß auf alle Fälle dieses zusätzliche Adressbyte
her - in den neuen Programmen kommen an jeder Stelle, an der auf eine Adresse verwiesen wird, 3 statt 2 Bytes. Oder 4 statt 3. Die
Binaries sind also fundamental anders - sie sind nicht mehr kompatibel. Ein Programm mit 2 Bytes Adressangabe läuft eben nicht auf
einem Computer, der 3 Bytes Adressangabe erwartet. Und keinem nutzt ein Computer, für den es keine Programme gibt. Insofern
wartete 1980 auf die Hardware-Entwickler eine ziemliche Aufgabe.
Bank Switching
Es war nicht so, dass es nicht auch Lösungen gegeben hätte. Schon für einen der allerersten "PC", der Apple II, basierend auf einem
Prozessor mit 16 Bit Adressraum, wurde eine 128K-Karte angeboten - der Nachfolger Apple III kam sogar von Haus aus mit soviel
Speicher zum Kunden, obwohl auch er auf dem MCS 6502 aufbaute. Die Lösungen liefen mehr oder weniger alle auf das Verfahren des
"Bank Switchings" hinaus. Ein zusätzlicher Chip schaltete bei diesem Verfahren den logischen Adressraum oder Teile davon auf andere
Speicherbausteine um. Nehmen wir an, ein Computer mit 16 Bit Adressraum ist mit 96K RAM ausgestattet. Das sind dann 32K "zuviel".
Der Bank Switch kann nun wahlweise eine von zwei 32K Banks in die oberen 32K des Adressraums einblenden, während die unteren
32K fix bleiben. Dieses Verfahren wurde auf verschiedene Art genutzt. Beim berühmten C64 konnten so 8K des 20K-ROM gegen 8K
weitere RAM eingetauscht werden, da der C64 mit echten 64K RAM bestückt war. Beim CPC464/664 betrug der benötigte Adressraum
64K RAM plus 32K ROM. Wenn das ganze ROM eingeblendet war, hätten dem Programmierer nur noch weniger als 30K freier
Speicherplatz zur Verfügung gestanden. Tatsächlich hatte er 42K, da ein Teil des ROMs per Bank Switching eingeblendet wurde. Die
128K-Boliden der späten 8-Bit-Zeit konnten die zweite 64K-Bank grundsätzlich nur über Bank Switching ansprechen - entweder explizit,
wie beim CPC6128 oder implizit, wie beim C128, was letzteren zum Schleichrechner werden ließ. Was praktisch klingt, war nur
13.11.2014 11:48
6 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
eingeschränkt nutzbar. Der Programmierer mußte sein Hauptspeichermanagement gut organisieren: Was kommt in die eine, was
kommt in die andere Bank? Was tun, wenn die eine voll ist, die andere noch nicht, etwas aber eigentlich in die erste Bank gehört? Es
gab nur zwei Wege: Entweder ein ausgeklügeltes Managementprogramm benutzen, das aber selbst wiederum Speicher und
Rechenzeit frass oder das Management selbst programmieren, was viel Aufwand bedeutete. In jedem Fall musste unter Umständen viel
hin- und hergespeichert werden, was Zeit kostete - vergleichbar zu heutigen PCs, wenn sie "swappen", d.h. zwischen Hauptspeicher
und Festplatte Hauptspeicher- inhalte austauschen.
Der 8088 des Ur-PC
In diese Situation hinein kam der 8088 von Intel. Grundlegend an seiner Adresstechnik war die Segmentierung in 64K-Blöcke. Jede
Adresse kann aus zwei Teilen bestehen: Segmentnummer (2 Bytes) und Adresse innerhalb des Segments, (2 Bytes) der s.g. Offset.
Kompliziert, aber es war dadurch möglich, daß eine Adresse nicht 4 Bytes haben MUSSTE. Es können auch zwei Bytes genügen, wenn
klar ist, um welches Segment es sich handelt. Damit das klar ist, kann man dem 8088/86 vier Segmentnamen übergeben. Und ihm
sagen: "Arbeite ab jetzt mit Segment Nr. 2" - Bank Switching läßt grüßen. Damit ergeben sich drei Hauptspeichermanagement-Modelle:
1. CP/M-Kompatibilitätsmodus: Alles spielt sich im 64K-Bereich ab, 2 Bytes Adresse und nur ein Segment.
2. "Bank-Switching": Arbeit mit bis zu vier Segmenten, zwischen denen der Prozessor schnell hin- und herschalten kann.
Ermöglicht, z.B. das Programm in ein Segment, die Daten aber in ein anderes Segment zu tun.
3. Wo 1. und 2. nicht genügen, bleibt dann immer noch die 4-Byte-Adressierung mit großen Adressraum.
Besonders Modell 2 war interessant, da es für die CP/M-Programmportierung auf den PC nur wenige Eingriffe erforderte, um
mindestens 128K Speicherplatz zur Verfügung stellen zu können - ein eindeutiger Vorteil des PC gegenüber den Konkurrenzsystemen.
Von 16K bis 1 MB
Kommen wir zurück zur Programmierersicht. Die oben angeführten Aspekte brachten manche Merkwürdigkeit mit sich. Kaufte man um
1981 den Ur-PC, konnte man ihn sich theoretisch mit 1 MB RAM bestellen. (Wegen eines Elektronikfehlers tatsächlich nur mit 576K), da
der 8088/86 16 Segmente adressieren konnte (der physische Adressbus war 20 Bit breit: 16+4). Schon 512K kosteten ca. 4000 DM und
in Zeiten, in denen ein Programm mit 30K als groß galt, erschien dies eher absurd. Der Ur-PC wurde mit BASIC im ROM ausgeliefert
und dieses BASIC arbeitete nach Modell 2.: Für Userdaten, d.h. das BASIC-Programm und die Variablen standen knapp 64K zur
Verfügung. Das war vergleichsweise viel. Die kleinste PC-Version kam mit 16K RAM auf den Markt, was für die eingangs zitierten 50
BASIC-Zeilen genügte. Aber wenn man 4000 DM für RAM ausgegeben hatte, war es bitter, nur 1/8 des teueren RAMs zur Verfügung zu
haben! Es dauerte eine geraume Zeit, bis Programme wie dBase, Word usw. auf den Markt kamen, die mit Modell 3 arbeiteten. Und es
dauerte bis 1987, bis Turbo Pascal 4.0 der Firma Borland die 64K-Grenze sprengte und echte .exe-Binaries ermöglichte.
MS-DOS und die 640K-Grenze
13.11.2014 11:48
7 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Was auch immer über MS-DOS und PCs geschrieben wurde, eines ist klar: 1980 sollte der PC eine CP/M-Maschine werden. Nur kam
die CP/M-Portierung nicht so zustande, daß CP/M 1981 mit dem ersten PC hätte mitausgeliefert werden können. Der PC brauchte aber
ein eigenes Betriebssystem. Und dies war MS-DOS. Sehr CP/M-ähnlich, aber von Anfang an für eine 4-Byte-Adressierung
ausgelegt.Da klar war, daß ein PC, den IBM herausbringt, wichtig sein wird, war es für die großen Softwarehersteller von Anfang an
wichtig, ihre Produkte für den IBM PC verfügbar zu haben. Aufgrund der Segmentierung und der CP/M-Ähnlichkeit von MS-DOS war die
Portierung auch kein großer Aufwand. Wenngleich die ersten Versionen der jeweiligen Programme aus dem PC kaum mehr
herausholten als aus einer CP/M-Maschine. Bei 128K Grundausstattung für PCs bis 1984 war dies kein größeres Problem. Ergo: Weil
der Druck zur Portierung unterschätzt, MS-DOS relativ primitiv und die Portierung dadurch einfach war, warteten die Herstellter nicht auf
CP/M, der Zug fuhr ab und die PC-Welt war MS-DOS. Wahrscheinlich war es ein Glücksfall, daß IBM und Microsoft die Rolle von
MS-DOS völlig falsch eingeschätzt hatten und ihm ein Minimum an Leistungsfähigkeit zukommen ließen. Dadurch war ein
DOS-Rechner einfach schnell. Für Dinge wie Multitasking, Piping usw. interessierte sich zu dieser Zeit unter den PC-Usern ohnehin
keine Sau.
Worin bestand nun die ominöse 640K-Grenze? Nun, wie David Bradley, einer der Systemdesigner des Ur-PCs in einem Artikel in der c't'
10/90, S. 34 erzählt, überlegte man, den Adressraums des PC's in folgende Bereiche aufzuteilen:
0 bis 640 K Conventional Memory für Programme und Daten
640K bis 768K Videospeicher
768K bis 896K Adressraum für Adapterkarten
896K bis 1024K ROM-BIOS
Und man setzte die Überlegung in die Tat um. Auf den ersten Blick erschien diese Aufteilung sinnvoll: 640K war damals ungefähr
genauso viel Platz wie 2002 40 GB, ca. 60% der maximal adressierbaren 64 GB eines Pentium III/4. Es war kaum vorstellbar, dass man
einmal mehr brauchen würde. Auf der anderen Seite gab es keinen Zwang, die Reihenfolge so festzulegen. Man hätte das Conventional
Memory auch obenauf packen können. Man hätte vor allem aber die Grenzen des Adressraums nicht fixieren müssen. Eine Tabelle an
fixer Adresse mit den Segmenten der reservierten Bereiche hätte genügt und man hätte viel mehr Flexibilität gehabt. Den geregelten
Hauptspeicherzugriff hätte dies kaum verlangsamt. Schliesslich waren alle Programme in der DOS-Äria auf Operationen
innerhalb von Segmenten orientiert, die Neuzutritt zu einem weiteren Segment geschah nur relativ selten.
Die Speicheraufteilung und die fehlende Allocation Table war also der erste Pferdefuss. Auf diese Weise konnte kein
Assemblerprogrammierer auf den Bereich oberhalb 640K, die s.g. UMA (Upper Memory Area) zugreifen, ohne das Risiko einzugehen,
in die Ports einer Adapterkarte (z.B. einer Netzwerkkarte) oder in einen Grafikspeicher reinzuschreiben.
Der andere Pferdefuss war DOS. DOS hätte durchaus es übernehmen können, die fehlende Allocation Table zu ersetzen. Dafür hätten
allerdings alle Hardware-Erweiterungen bei DOS angemeldet werden müssen (so, wie das heute bei Windows geschieht). So eine
Anstrengung hat es nie gegeben, vermutlich deshalb, weil mit zusätzlichen 128K bis 192K das SPeicherproblem unterhalb der 1
MB-Grenze auch nicht gelöst worden wäre.
13.11.2014 11:48
8 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Ab 1990 gab es von seiten der Firma Digital Research und von Herstellern von Memory Extendern (siehe unten) eine etwas andere
Lösung: Zwar war die UMA für Daten und Programme immer noch tabu, aber Treiber und die DOS-residenten Dateien konnten dorthin
verlagert werden. 1992 zog dann MS-DOS nach, indem es diese Techniken lizensierte und DOS 5.0 befügte.
Insofern stelle ich die These auf: Es hat nie ein 640K-Problem gegeben. Vielmehr ein 1 MB-Problem. Und das war weder mit einer
Systemerweiterung noch mit einem besseren DOS zu lösen.
Die 1 MB-Grenze
Dass es unter DOS eine 1 MB-Grenze gab, ist nicht so logisch, wie es sich vielleicht zunächst anhört. Die 1 MB-Grenze war alles
andere als unvermeidlich, sondern hängt letztendlich von einer recht willkürlichen Entscheidung ab. Ich kenne die Entscheidung und will
sie gleich darstellen, leider weiss ich jedoch nicht sicher, wer sie letztendlich getroffen hat. Vermutlich waren es die Prozessor-Designer
bei Intel.
Fassen wir nochmals zusammen, was wir im Abschnitt "Adressgrenzen" besprochen haben:
Ein Prozessor mit 16-Bit-Adressbus braucht genau 2 Bytes für die Angabe einer Adresse.
Ein Prozessor mit einem Adressbus breiter als 16 Bit braucht mehr als 2 Bytes für die Angabe einer Adresse.
Daher müssen die Programme für beide inkompatibel zueinander sein.
Wenn man nun "16" durch "20" ersetzt, hat man den Fall des 8086/88 und damit die 1 MB-Grenze. Denkt man. Stimmt aber nicht. Denn
für eine 20-Bit-Adresse braucht man mindestens 3 Bytes. Das heisst, die logische Adressbreite eröffnet einen logischen Adressraum
von 16 MB. Und beim 8086/88 ist die logische Adressbreite nicht nur 3 Bytes, sondern, wie wir gerade gelernt haben, 4 Bytes. 2 Bytes
für den Offset und 2 Bytes für die Segmentangabe. Das heisst, man hätte im logischen Adressraum Platz für 64K Segmente a 64K, also
für 4 GB. Wo war eigentlich das Problem und wo soll hier eine 1-MB-Grenze sein? Nun gut, beim 8086/88 entsprach nur den ersten 16
Segmenten eine physikalische Adresse. Aber beim 80286 hätte es den Protected Mode nicht gebraucht. Programme hätten unter DOS
einfach bei Bedarf Segment 17 bis 256 mitnutzen können. Worin lag das Problem?
Das Problem lag darin, dass aus ziemlich unerfindlichen Gründen sich jemand dazu entschieden hatte, dass für die
Segmentnumerierung nicht die ganzen 2 Bytes genutzt wurden, sondern nur die oberen 4 Bits. Die unteren 12 Bits waren redundant.
Falls sie gesetzt waren, wurden sie zu den oberen 12 Bits der Offsetadresse addiert.
Das, was ich jetzt nicht weiss, ist, ob die Übersetzung der logischen in die physikalische Adresse im Prozessor selbst geschieht oder ob
dies im BIOS erledigt wird. Vermutlich im Prozessor selbst, ansonsten hätten die BIOS-Hersteller vermutlich bald 16-MB-kompatible
Versionen ihrer Produkte herausgebracht und Intel hätte sich den Protected Mode sparen können.
Eine misslichere Entscheidung als diese, die unteren 12 Bits der beiden Segmentbytes praktisch wegzuwerfen, hat es in der
PC-Geschichte wohl nicht gegeben. Die Folgen für die PC-Entwicklung waren zwar im Grossen gering, aber im Kleinen ärgerlich:
Wieviel Programme konnten nicht so geschrieben werden, wie sie ihr Schöpfer schreiben wollte, weil er zwar vor einem 4-MB-PC sass,
13.11.2014 11:48
9 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
aber nur 1 MB zur Verfügung hatte?
Der 640K-Kampf
Die Zeit blieb nicht stehen und nach 1987, als eine Textverarbeitung mit Silbentrennung, Thesaurus und Doppelseitenformatierung
aufwarten musste, wurde es in den 640K langsam eng. Zumal 1986 der Atari ST mit vollständig adressierbaren 1 MB, aber für die Hälfte
des Geldes daherkam. Auch für die Anwendungsprogrammierer wurde der Hauptspeicher langsam knapper als ursprünglich erwartet.
Passte bei Turbo Pascal 1.0 noch Editor, Compiler und Linker samt von denen benötigten Arbeitsspeicher in 40K, so daß 24K für
Anwendungsprogramme übrig blieb (Ihnen erscheint das wenig? Dann schreiben Sie erstmal ein 20K langes Programm!), so wuchsen
die Ansprüche schnell. Ist ja auch klar: Insgesamt sind bei der integrierten Programmentwicklung 16 Speicherfresser am Werk:
1. Betriebssystem
2. Datenspeicher für's Betriebssystem
3. Programmentwicklungswerkzeuge:
4. Editor
5. Datenspeicher für Editor
6. Compiler
7. Datenspeicher für Compiler
8. Linker
9. Datenspeicher für Linker
10. Debugger
11. Datenspeicher für Debugger
12. Programmsource
13. Objectcode
14. Binary
15. User-Stack
16. User-Heap
Braucht jeder dieser Fresser im Schnitt 30K, sind 480K weg.
Mit dem Aufkommen der Festplatten wurde die Situation etwas gelindert. Daten konnten relativ schnell schnell auf die Platte geswappt
werden. (Das ging schon mit einem einfachen 8088 und Random-Access-Zugriff.) Aber das erhöhte den Programmieraufwand und
verringerte die Arbeitsgeschwindigkeit wesentlich.
13.11.2014 11:48
10 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Das Nächste waren Overlay-Techniken. Hier versuchte man, Teile des Programms auf die Festplatte zu swappen.BASIC-Programmierer
kannten diese Technik schon. Den Befehl "Merge" zum Nachladen von Programmteilen gab es schon bei den frühen Homecomputern.
Aber der Programmierer muss so selbst organisieren, was wann gemergt wird. In den strukturierten Programmiersprachen C und
Pascal greift man beim Programmieren auf Bibliotheken zurück. Man hatte nun die Möglichkeit, diese Bibliotheken als "Overlay" zu
deklarieren: Es wurde zur Laufzeit immer nur der Code geladen, der gerade benötigt wurde. Kam man damit nicht weiter, blieb nichts
übrig, als auf den Komfort einer integrierten Entwicklungsoberfläche zu verzichten und jeden Schritt wieder von Hand zu machen:
Source abspeichern, Editor beenden, Compiler laden, compilieren, Linker laden, linken, Debugger laden, debuggen, Fehlerzeile
aufschreiben, Debugger beenden, Editor laden, Programm verbessern, abspeichern ...
Borland verbesserte seine IDE weiter, indem sie die IDE selbst in Overlay-Technik programmierten: Beim Kompilieren wurde der Editor
ausgelagert, vor dem Linken wurde der Compiler aus dem Speicher entfernt usw. Das war einerseits angenehm, raubte einem
andererseits den Ausweg, durch Verlassen der IDE Speicherplatz zu sparen. Das brachte dann schlicht nichts mehr.
Der IBM AT
Mit dem IBM AT kam der Intel 80286. Dieser hatte 24 Adressbusleitungen, was die Adressierung von 256 Segmenten ermöglichte - 16
MB. Ausweg aus der Speicherkrise? Keineswegs. Um seine Prozessorverbesserungen nicht mit der bisherigen Software kollidieren zu
lassen, entschied sich Intel, fast alle Verbesserungen nur in einem neuen Modus verfügbar zu machen: Dem "Protected Mode". Der alte
8086/88-Mode hieß nun "Real Mode". Hintergrund dieses Bruchs zum alten 8086 war die Sackgasse, in die das damalige Lieblingskind
von Intel, der iAPX-432, gekommen war. Ein waschechter 32-Bitter mit allen Schikanen, der eigentlich für die grosse
Mikrocomputerzukunft ersehen war. Allein, das Provisorium 8086, das allein und ausschliesslich als CP/M-gestützte Überbrückung
gedacht war, war so erfolgreich, dass vom AIX kaum jemand Kenntnis nahm. Und so entschied sich Intel, viel der Entwicklungsarbeit für
den iAPX-432 via Protected Mode in den 80286 einzuschleussen. Intel hatte wohl die Hoffnung, dass nach und nach die
Softwarehersteller Protected Mode-Programme anbieten würden. Das ging aber nicht, solange MS DOS Real Mode blieb. Und MS-DOS
blieb Real-Mode, damit die alten Programme noch liefen. So kauften die Leute AT's für viel Geld, aber fast der einzige Vorteil war der
um 30% höhere Prozessortakt. Microsoft machte einen ernsthaften Versuch, das schon 1980 herausgebrachte SCO-Xenix, eine
abgespeckte Unix-Variante, mit dem AT zu etablieren. Doch die Softwarehersteller zogen nicht mit, da Portierungen auf Xenix sehr
aufwendig waren. So schöne Tricksereien, wie Ports direkt zu adressieren, wäre gar nicht möglich gewesen. Und die Leute kauften AT's
und Real-Mode- Software, solange es nichts anderes gab.
Was ist Protected Mode?
Man muss sich unter dem Protected Mode nicht eine komplett andere CPU vorstellen. Vielmehr arbeitet die CPU weithingehend mit den
gleichen Registern und Befehlen wie im Real Mode, so dass ein Real Mode Programm prinzipiell auch im Protected Mode laufen würde.
Der Unterschied liegt nur in der Adressierung. Intel beabsichtigte, mit dem Protected Mode nicht einfach den Adressbus zu verbreitern,
sondern grundsätzlich die Adressierungstechnik zu modernisieren: Es sollte möglich sein, geschützte Adressräume einzuführen. Daher
der Name "protected". Sobald also ein Programm über ein Segment hinaus adressiert (eine s.g. FAR-Adressierung), funktioniert im PM
alles anders als im RM.
13.11.2014 11:48
11 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Allerdings funktioniert auch schon innerhalb der 64K-Grenze etwas anders: Die Ansteuerung des BIOS. Der Grund ist ziemlich
kompliziert und kann hier bei Dr. Dobbs nachgelesen werden.. Dies führt dazu, dass eine simple Textausgabe am Bildschirm
anderen Maschinencode braucht wie im Real Mode.
Adressierung im Protected Mode
Die ersten (hohen) 16 Bit einer logischen PM-Adresse haben eine komplett andere Bedeutung als im RM. Sie sind ein Zeiger auf einen
Eintrag in der s.g. Descriptor Table. Ein Deskriptor (also solch ein Tabelleneintrag) enthält die physikalische Adresse des Segments und seine Länge. Im PM sind Segmente keineswegs immer 64K gross. Sie können auch kleiner sein - sogar nur lediglich ein Byte
gross. Wenn eine PM-Adresse also 0010:0008 heisst, dann bedeutet dies keineswegs eine Adresse ganz am Anfang im Speicher.
Sondern 0010 ist der zweite Eintrag in einer Desciptor Table. Und dort steht die eigentliche Basisadresse des Segments, z.B. FA0000.
Dann kommt noch die Offset-Adresse dazu und wir haben die entgültige physikalische Adresse, nämlich FA0008. 0010 nennt man auch
den "Selektor". Er verweist auf den zweiten Deskriptor in der Desciptor Table, da jeder Deskiptor 8 Bytes lang ist. 0008 verweist also auf
den ersten, 0010 auf den zweiten, 0018 auf den dritten Deskriptor usw.
Es gibt allerdings aufgrund der "Protected"-Idee nicht nur eine Deskriptorentabelle, sondern deren viele. Jede Task sieht dabei immer
zwei: Die Global Descriptor Table (GDT) und eine Local Descriptor Table (LDT). Die GDT enthält Segmente, auf die alle Tasks zugreifen
dürfen. Die LDT enthält Segmente, auf die nur der spezifische Task zugreifen darf. Auf diese Art und Weise behält die CPU die Kontrolle
über Speicherzugriffe. Kommt ein Maschinenprogramm ins Schleudern und führt Nonsense-Code aus, dann wird es früher oder später
Bytes als Selektoren interpretieren, die auf verbotene Deskriptoren verweisen - was die CPU dazu veranlasst, "Feueralarm" zu geben der berühmte "Segment Default Error" beim Absturz eines 16-Bit-Windows-Programms.
Weiter ging's meist im Real Mode...
Die ersten, die vom Protected Mode ausserhalb von Xenix profitierten, waren diesmal die Programmierer, da Compile?r und Linker
keine BIOS- Zugriffe brauchten. Daher konnten hier bald Protected Mode-Versionen angeboten werden - als KommandozeilenProgramme. Das brachte zumindest den Vorteil, dass man nun Binaries mit vollen 600K schreiben konnte, da es während der
Compilation, bzw. während dem Linken, bei dem jeweils zwei Versionen des Programms im Speicher liegen müssen, keine
640K-Grenze mehr gab. Das Binary selbst arbeitete weiterhin im Real Mode.
Mithin war die Grenze für Binaries auf ca. 600K angehoben. Wie aber sah es mit dem Variablenspeicher aus? Man muß sich vor Augen
halten, daß der AT 1984 auf den Markt kam. Erst 1987 brachte Borland mit Turbo Pascal 4.0 eine erste Programmiersprache für
"Normalprogrammierer", mit der man die vollen 640K als Variablenspeicher ansprechen konnte. Und erst 1990 erblickte mit DOS 4.0
eine Möglichkeiten das Licht der Welt, auf AT's über diese Grenze hinauszukommen - zu einer Zeit, in der 386-PCs nicht nur schon
käuflich, sondern in der SX-Version schon unter 5000 DM erhältlich und erschwinglich waren. Dies war der Treiber Ramdrive.sys.
Sehr viel mehr Speicher wurde durch Ramdrive.sys verfügbar. Dieser Treiber schaffte einen besonderen Zugang zum Speicherbereich
oberhalb der 1 MB-Grenze. Dieser Bereich nenne ich hier AOM-Bereich ("Above One MB"), um Mißverständnisse mit den später
einzuführenden Begriffen "Expanded Memory" und "Extended Memory" zu vermeiden. Ramdrive.sys simuliert einen zusätzlichen
13.11.2014 11:48
12 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Datenträger, speichert dessen Inhalt aber im RAM und zwar im AOM-Bereich. Der Datenzugriff ist dadurch wesentlich schneller, als auf
einen echten Datenträger, aber natürlich immer noch viel langsamer als ein direkter RAM-Zugriff.
C++-Klasse, die man dazu benutzen kann, Hauptspeicher auf der RAM-Disk zu verwalten.
EMS
Mit LIM, EMS, XMS, VCPI und DPMI betreten wir ein wirklich verworrenes Kapitel der PC-Geschichte, das sich wiederum um die
eigentlich so einfache Frage dreht: Wie bekomme ich den Speicher, den ich eigentlich schon habe?
Ein Versuch, am Anfang die Verwirrung ein bisschen zu begrenzen...
Memory Extender
sind Programme, die es DOS-Programmen ermöglichen, mittels Paging-Verfahren auf den Bereich oberhalb von 1 MB
zuzugreifen, ohne den Real Mode zu verlassen.
DOS-Extender
sind Zusatztools zu Linkern und Compilern, die ein Real Mode-Programm in den Protected Mode übersetzen. Dabei müssen alle
BIOS-Zugriffe, muss die Interrupt-Behandlung und vor allem die Speicheradressierung den Gegebenheiten im Protected Mode
angepasst werden. Das Programm kann aber auf diese Art und Weise problemlos 16 MB oder 4 GB Speicher adressieren - ohne
Paging.
Extended Memory
ist der Bereich oberhalb von 1 MB, genauer: Oberhalb von 1 MB + 64K.
Expanded Memory
ist der Bereich oberhalb von 1 MB, wenn er von einer speziellen Art von Memory Extender, nämlich einem EMS-Extender
verwaltet wird.
EMS
ist ein Standard für Memory Extender, die eigentlich für den 8086 gedacht sind und Zusatzhardware, eine s.g. EMS-Karte,
benötigen. Um 1990 herum wurde die EMS-Funktionalität oft schon auf dem Motherboard integriert. Der 80386 benötigt keine
Zusatzhardware, er kann mit Hilfe einer geeigneten Software EMS emulieren.
XMS
...ist ein Standard für Memory Extender für den 80286. XMS braucht keine Zusatzhardware, sondern nutzt Funktionen des 80286
aus. Es ist leistungsfähiger als EMS. Der Standard-Extender, der mit DOS ausgeliefert wurde und auf dem die
Windowsversionen 3.x beruhten, ist HIMEM.SYS.
Zurück zu EMS
Fassen wir noch einmal die Frühzeit des PC's, diesmal im Jahr 1984, ins Auge. Ein Jahr, nachdem der PC im europäischen Markt
eingeführt wurde, dasselbe Jahr, in dem IBM den PC AT mit Intel 80286 (wir kommen noch später darauf) für mehr als 20.000 DM
13.11.2014 11:48
13 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
vorstellte, (ausgerüstet mit 512K Speicher), hatten die meisten PC's eine Speicherausrüstung von 64K oder 128K und der
Programmierer-Horizont orientierte sich, wie weiter oben schon dargestellt, an CP/M und BASIC-Programmen. Der nutzbare
Adressbereich umfasste, wie wir jetzt wissen, den Bereich 0 bis 640K, das s.g. Conventional Memory, und erschien so unerschöpflich,
wie im Jahr 2002 4 GB Adressraum. (Und es kostete mindestens genausoviel, auf 640K aufzurüsten, wie es heute kostet, auf 4 GB
aufzurüsten...).
Expanded Memory und Tabellenkalkulationen
Firmen und Behörden orientierten sich damals (wie heute) allerdings nicht an dem, was es an üblicher Technik gab, sondern an der
Grösse des Problems, dass es für sie zu lösen galt. So erwies sich die Tabellenkalkulation als ein sehr nützliches Werkzeug für
Kalkulationen - auch und gerade mit sehr vielen Daten. So kamen auch in den frühen 80er-Jahren schnell Anwendungsfälle für Tabellen
mit einigen tausend Zeilen und mehr als hundert Spalten zustande, vor allem, weil es eine Verknüpfung zu Datenbanken, wie sie heute
möglich ist, in den frühen Tabellenkalkulationen noch nicht gab.
Nehmen wir an, eine Tabellenzelle benötigt 16 Bytes. Die Tabelle hat 256 Spalten. Dann benötigt eine Zeile 4K. Hat man 512K freien
Speicher zur Verfügung, ist bei 128 Zeilen Schluss. Für eine Firma, die komplexe Kalkulationen bezogen auf 1000 Beschäftigte oder
Artikel oder andere Einheiten durchführen muss, viel zu wenig.
Die "Killer"-Applikation in diesem Bereich zu dieser Zeit war Lotus 1-2-3. Lotus 1-2-3 hatte relativ grosszügige Beschränkungen der
Grösse der Tabelle. Also entstand sehr schnell der Wunsch, solche Tabellen hauptspeicherseitig auch realisieren zu können.
Above Boards
Schon früh brachten Hersteller daher Speicherweiterung-Boards für den IBM PC für Preise von einigen Tausend Dollar auf den Markt.
Alle funktionierten via Bank Switching. Die Ansteuerung war aber nicht genormt. Daher hätte Lotus für jeden Board-Hersteller einen
neuen Treiber generieren müssen. Das war indiskutabel. Somit setzen sich Lotus, Intel und Microsoft 1983 zusammen und vereinbarten
einen Bank-Switching-Standard für den IBM PC, den s.g. "Expanded Memory Standard", EMS, der 1984 verabschiedet wurde.
Witzigerweise im gleichen Jahr, als der IBM AT herauskam, dessen 80286-Prozessor ohne Bank-Switching 16 MB RAM adressieren
konnte. Aber die praktische Nutzung dieses Features war aus mehreren Gründen Zukunftsmusik für die derzeitigen Lotus- und
Framework-Nutzer: Die Anschaffung eines IBM AT plus dem benötigten Speicher war allemal teurer als die Anschaffung lediglich des
benötigten Speichers.
Intel brachte noch im gleichen Jahr das erste EMS-Erweiterungsboard heraus. Es hatte neben dem Speicher gleich einen MemoryController, der das Bank-Switching verwaltete. Kurze Zeit später zogen die anderen RAM-Kartenhersteller nach: Alle
Speichererweiterungskarten waren in der Folgezeit EMS-fähig. Ab ca. 1987 hatten die PC's die EMS-Controller z.T. auch schon
eingebaut, da sie nun schon oft auf dem Motherboard auf 2 MB Speicher erweitert werden konnten.
Mit EMS konnte man bis zu 512 16K-Bänke verwalten, also bis max. 8 MB. Die ersten Above-Boards brachten allerdings nur maximal 2
MB auf dem Board unter. Mir ist nicht bekannt, ob es die Möglichkeit gab, mehrere Boards simultan zu betreiben. Jedenfalls änderte
13.11.2014 11:48
14 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
sich die Situation in den Folgejahren mit dem Aufkommen von 1 MBit-Chips schnell: Nun waren 8 MB auf dem Board kein Problem
mehr.
Die Funktionsweise von EMS
Der Programmierer kann bis zu vier 16K-Banks, hier Pages genannt, im Conventional Memory für den Datenaustausch reservieren. Der
Bereich oberhalb von 1 MB heisst "Expanded Memory". Der Programmierer belegt nun eine Page, ruft eine bestimmte EMS-Funktion
auf, die wiederum den Inhalt ins Expanded Memory schreibt. Der Programmierer bekommt eine Kennzahl, ein s.g. Handle zurück, die
diese Page identifiziert. Nun kann er diesselbe Page im Conventional Memory wieder beschreiben. Und wieder durch die EMS-Funktion
im Expanded Memory "abspeichern" lassen. Usw. Das Ganze kann er solange machen, bis 7 MB Expanded Memory voll sind.
Will er die Daten wieder haben, übergibt er der entsprechenden Call-Funktion des EMS-Treibers den Handle und die Nummer der
gewünschten Page (0 bis 3), in die der Abschnitt des Expanded Memories kopiert werden sollte.
Das EMS-System hatte den Nachteil eines jeden Bankswitching-Systems: Es war langsam und es verlangte vom Programmierer eine
Menge Speicherbuchhaltung.
Spulen wir nun ein paar Jahre vor, z.B. ins Jahr 1990. Dies war das Jahr, in dem die 640K so langsam richtig knapp wurden. Inzwischen
gab es nur noch wenige PC's, das meiste waren AT's und 386er-PC's. Beide beherrschten den Protected Mode und waren in der Lage,
16 MB und mehr Speicher anzusprechen. Gab es viel Motivation, EMS zu nutzen? Nein, eigentlich nicht. Dazu hätte ich PC's, die
eigentlich problemlos mit 16 MB Speicher umgehen können, mit einem Memory- Expansion-Board ausstatten müssen! Irgendwie haben
IBM und Microsoft mit EMS an ihrer eigenen Entwicklung vorbeigearbeitet. Der AT war schon auf dem Markt und es war klar, dass der
PC gerade für Large Memory-Anwendungen nicht die Basis werden würde. Dieser wenig weitsichtigen Planung haben wir ein
ziemliches Verwirrspiel in den 90er-Jahren zu verdanken.
XMS
Der 80286 mit seinem Protected Mode blieb bei der Festlegung des EMS-Standard also ausserhalb des Blickfelds. Der Protected Mode
konnte wiederum unter DOS nicht genutzt werden, solange ein Programm DOS-Systemaufrufe (insbesondere für
Datenträgeroperationen) benötigte. Aber er konnte genutzt werden, um ein Bank Switching zu simulieren, d.h. die Pages zwischen
Conventional Memory und AOM auszutauschen. Dazu brauchte es nur einen cleveren Treiber, der den 80286 in den Protected-Mode
schaltete, den Inhalt hinauf- oder hinunterkopierte und dann wieder in den Real-Mode zurückschaltete.
Schon ein Jahr nach Verabschiederung der ersten Version des EMS-Standards legte das LIM-Konsortium für diese Art von Paging
einen zweiten Standard fest: XMS 1.0. XMS war also der Standard für eine Software-Lösung des Pagings auf 286-Systemen (oder auf
höheren Prozessoren). Es war EMS in vielerlei Hinsicht überlegen:
1. Es erlaubte den Austausch von bis zu 64K beliebig grossen Pages, war also nicht mehr auf die starre Grösse von 16K
beschränkt.
13.11.2014 11:48
15 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
2. Es war dafür vorgesehen, im 1.0-Standard 32 MB, im 2.0-Standard sogar 64 MB maximalen Adressraum zu verwalten.
3. Ein XMS-Treiber sorgte nicht nur für den Up/Download der Pages, sondern auch für die Organisation des AOM-Bereichs, der hier
nun XMS-Speicher oder EXTended Memory heisst. Im Gegensatz zu EMS war es also möglich, den AOM-Speicher zu
reorganisieren. Bei EMS wurde ein Handle für eine Page nur einmal vergeben, zumindest bis zur nächsten Totallöschung des
AOM-Bereichs.
4. Ein XMS-Treiber kostet im Conventional-Memory praktisch keinen Speicherplatz, da der Puffer für die Pages im s.g. HMA
residierten. Was HMA ist, wird in einem eigenen Kapitel erklärt.
EMS- und XMS-Systeme wurden unter dem Namen "Memory Extender" (wohl zu unterscheiden von den späteren "DOS-Extendern")
zusammengefasst. Solche Memory-Extender-Software wurden ab 1987 von verschiedenen Firmen wie PharLap, Quarterdeck und
Quemm herausgebracht. Sie beinhaltete meist sowohl den EMS- als auch den XMS-Standard.
Der Weg für Programmierer über die 640K-Grenze hinaus war also möglich, aber er war steinig:
Anschaffung eines AT's mit mehr als 1 MB Speicher
Anschaffung eines Memory-Extenders (Preis zwischen 200 und 600 DM)
Schreiben einiger Assembler-Routinen, die die Ansteuerung des XMS-Extenders erledigen.
Schreiben der Software, incl. der Speicherbuchhaltung für das Paging.
Schwerer, als der Aufwand, wog für die meisten Software-Hersteller, dass man bei Nutzung von Memory-Extendern die zugehörige
Extender-Software voraussetzen musste und damit entweder das Programm verteuerte (wenn man selbige gleich mitlieferte) oder den
Kundenkreis von vornherein stark einschränkte. Dies war der Grund, warum Memory-Extender zwar für Eigenentwicklungen genutzt
wurden, jedoch die Hersteller von Standardsoftware darauf verzichteten und lieber die tollsten Kunststücke und wahre Swap-Orgien auf
die Festplatte vollbrachten, als Extended Memory einzusetzen.
Die Situation änderte sich mit dem Erscheinen von MS-DOS 4.0 1990. Diese Version brachte u.a. ein kleines, unscheinbares Stück
Software namens Himem.sys mit. Dahinter verbarg sich nichts anderes als ein vollwertiger XMS-Treiber. Ab diesem Zeitpunkt konnte
jeder DOS-User XMS nutzen. Merkwürdigerweise sprangen die Software-Firmen (incl.Microsoft selbst) nicht gerade begeistert auf den
neuen Zug auf. Der Doom-Vorgänger, der erste Ego-Shooter "Wolfenstein 3D", nutzte XMS. Der Packer pkzip nutzte XMS. Aber viele
Programme dieser Zeit und danach für DOS, MS-Word 5.0 und 5.5, das erste Office-Paket, die Borland- und Microsoft-Compiler bis
1993, usw., sie alle ignorierten XMS.
Dass der XMS -Standard sich selbst keine grossen Hoffnungen machte, den Kampf im Conventional Memory um jedes Byte zu
beenden, beweist er mit seinem eigenen Design. Es zählt vielleicht zu den absurdesten¦Varianten dieses Kampfes um jedes Stückchen
Freiraum unterhalb der 640K-Grenze
13.11.2014 11:48
16 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Wie oben schon erläutert, basiert der Adressraum des 8088/86 auf 20 Bit, die aber mit Hilfe von zwei 16-Bitadressen in Programmen
beschrieben werden. Diese beiden 16-Bit-Adressen werden um 4 Bits verschoben miteinander addiert. In Hex-Schreibweise (16erSystem: Jede Ziffer geht von 0 bis F und repräsentiert 4 Bit):
Segment:
C A 8 F
Offset:
+
C 1 1 A
-----------------------20-Bit-Adr.
D 6 A 0 A
PC-Maschinenadressen notiert man als CA8F:C11A.
Die letzte 20-Bit-Adresse kann man also durch
Segment:
F F F F
Offset:
+
0 0 0 F
-----------------------20-Bit-Adr.
F F F F F
,d.h. FFFF:000F bilden. Oder durch FFFE:001F. Usw. Aber was ist mit FFFF:0010? oder FFFF:FFFF? Diese Adressen liegen ja
oberhalb der 1 MB-Grenze! Richtig. Beim 8088/86 machte das keinen Sinn und somit interpretierte das BIOS, das zwischen CPU und
RAM vermittelt, FFFF:0010 als 0000:0010. Ab dem 80286 aber gab es ein Bit, mit dem man Adressleitung 20 (Numerierung: 0..20), die
ja nun existierte, "freischalten" konnte, damit dem logischen Adressbereich FFFF:0010 bis FFFF:FFFF (das sind 64K-16) ein phyischer
Speicher entsprach. Diese Umschaltbarkeit nennt man "A20-Gate".
Wie knapp der Hauptspeicher anfangs der 90er war, kann man daran ersehen, welchen Aufwand man betrieb, diese kostbaren 64K im
AOM zu ergattern. Der XMS-Standard legte nämlich den Austausch-Speicher, den s.g. Paging-Buffer, genau in diesen Bereich. Der
Treiber Himem.sys brachte die Routinen zum Ansprechen der HMA gleich mit. Man konnte diese Routinen auch dazu benutzen, andere
residente Programme, insbesondere die DOS-Routinen selbst in die HMA zu verfrachten - das schränkte natürlich wiederum die
Leistungsfähigkeit eines XMS-Extenders ein.
Ein weiteres Kapitel der Memory-Extender wurde mit Erscheinen des 80386-Prozessors 1986 aufgelegt, aber darauf komme ich dann
im 80386-Kapitel zurück.
Speicherkarte eines PC's
13.11.2014 11:48
17 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
80386-PC's
Die Zeit zwischen 1989 und 1991 war pc-seitig eine seltsame Zeit. Die Zeit der 80386 hatte 1986 begonnen, aber erst 1989 begannen
13.11.2014 11:48
18 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
sie in den Bereich unter 10.000 DM einzudringen und wurden langsam in nennenswerten Stückzahlen verkauft.
Der 80386 brachte einen gegenüber dem 80286 stark erweiterten Protected Mode mit, auf seinem 32 Bit breiten Adress- und
Datenbusse 4 GB Adressraum anbietend, das auch in linearer Adressierung und - im richigen Betriebmodus - mit Adress Protection.
Vorausgesetzt, Programme und Betriebssystem unterstützten dies. Und noch mehr: Es gab auch die Möglichkeit, parallel zum Protected
Mode Prozesse im s.g. Virtual-8086-Mode anzustossen. Virtual deshalb, weil in DOS natürlich nicht mehrere Prozesse nebeneinander
exisitieren konnten. Aber es war möglich, auf jedem der Virtual-8086-Prozesse ein separates DOS zu fahren.
Linux oder Windows NT gab es noch nicht, nicht einmal Windows 3.0 war schon auf dem Markt oder nennenswert verbreitet. DOS
kannte keinen Protected und schon gar keinen Virtual-8086-Mode. Es gab nicht wenig Hersteller und Händler, die 1988/89 einen damals
noch sehr teuren 386-Rechner anboten, mit 1 bis 2 MB RAM und unter DOS. Und die meisten Kunden werden ihn so stolz benutzt
haben, ohne jemals auf die Idee gekommen zu sein, dass sie nur 30% ihres Rechners überhaupt nutzten - sowohl, was die
Prozessorpower,als auch, was den Hauptspeicher anbelangte.
Mir selbst ist ein Fall bekannt, in dem eine Firma 1987 einen 386er anschaffte (mit wieviel Speicher, das weiss ich nicht, aber dem mir
genannten Preis nach zu urteilen, waren wahrscheinlich 1 MB oder mehr drin.) Sie übertrugen ein Grossrechnerprogramm auf Fortran
unter DOS. Und erweiterten es immer mehr und kämpften mit der 640K-Grenze, wie man nur kämpfen konnte (13.000 Zeilen
Programmcode). Doch selbst 1995 kamen sie nicht auf die Idee, dass es einen Ausweg aus dem DOS-Gefängnis geben könnte.
Es gab ihn. Und nicht nur einen. Und nicht erst 1995. Der erste Ausweg hiess XMS. Das beherrschte der 80386 noch viel besser als der
80286. Im 32-Bit-Protected Mode war er ab LIM-Standard 3.0 in der Lage, nicht nur 16 MB, sondern theoretisch 4 GB zu adressieren.
Theoretisch. Kein mir bekanntes Programm ist in der Lage, unter XMS mehr als 64 MB zu adressieren. Das 64 MB-Limit rührt daher,
daß in dem Moment, in dem das System selbst den zur Verfügung stehenden Speicher über das BIOS ermittelt, es diesen von DOS
über eine 16-Bit-Zahl mitgeteilt bekommt - in Kilobyte zum Glück...
Eine weitere Möglichkeit mutet mir heute noch etwas seltsam an: Die damaligen kommerziellen Memory-Extender für 386-Prozessoren
beherrschten neben XMS auch EMS. Vielleicht konnten das auch Versionen für 286-Prozessoren, das weiss ich nicht. Wohlgemerkt:
EMS via Software, nicht via Expansion Board. Einfach dadurch, dass EMS-Routinen angeboten wurden, die intern alles in XMS
übersetzten (was ja nicht schwer war). "XMS emuliert EMS" hiess das dann. Wozu sollte das gut sein? Nun, obwohl XMS schon 1986
das Licht der Welt erblickte, wurde es bis 1990 so gut wie ignoriert. Ich vermute fast, dass die damalige Memory-Extender-Software
auch auf 286er-Systemen EMS anbot - um der lieben Kompatibilität mit den wenigen alten PC- Oldtimern mit Expansion Board willen.
Und das hat sich dann mal wieder verselbstständigt: Die Software-Hersteller setzten auf EMS und die Memory-Extender-Hersteller
sahen keinen Grund, auf XMS umzusteigen.
Borland jedenfalls nutzte meines Wissens nach 1991 zum ersten Mal einen Mem-Extender und das war EMS. In Turbo Pascal 6.0
wurde der Editor damit beglückt, damit das Turbo Vision-Fenster-System überhaupt einen Sinn machte. Für den Programmierer blieb
ansonsten alles beim alten:
Max. 64K grosse Units (Module)
13.11.2014 11:48
19 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Max. 64K Stack
Max. ca. 300K Heap innerhalb der IDE
Max. ca. 300K-grosse Programme innerhalb der IDE
Erst mit Turbo-C++ 3.0, bzw. Turbo-Pascal 7.0 hielt XMS in die IDE Einzug - 1993. Die ganze IDE arbeitete mit XMS, so dass, wenn
auch nur Real-Mode-Programme entwickelt werden konnte, diese wenigstens den gesamten (500 bis 600K) grossen Speicher nutzen
konnten.
Als 1991 DOS 5.0 herauskam, hatte es ein besonderes Schmankerl dabei: EMM386. Ich vermute, dass kaum jemand damals begriff
und heute weiss, was es mit diesem obskuren EMM auf sich hatte. Nun, es war ein lizenzierter EMS-Emulator. (Siehe oben).
AusschlieÜlich für 386er. Ohne ihn wären manche Programme ohne eigens angkauften Memory-Extender gar nicht oder nur innerhalb
von 640K gelaufen - z.B. Turbo Pascal 6.0. Und das alles wegen einer Handvoll exotischer IBM PC's 1984...
DOS-Extender, DPMI und VCPI
Es gab noch einen dritten Weg, 1987ff. an den Speicher eines 386er zu gelangen: Die Nutzung eines DOS-Extenders. DOS-Extender
realisierten auf einem 386er das, was auf einem 286er unter DOS meines Wissens nach nicht möglich gewesen war: Die dauerhafte
Nutzung des Protected Mode. Gegenüber Memory Extendern hatten sie den grossen Vorteil, die inneren Speicherstrukturen nicht mehr
in eine Paging-Verwaltung umsetzen zu müssen. Abgesehen vom Zuwachs an Rechengeschwindigkeit, der aus dem Wegfallen des
Pagings und der Nutzung eines echten 16-Bit oder 32-Bit-Betriebsmodus resultierte.
Wie benutzte man DOS-Extender? Man kaufte sich eine solche Software, band sie in seinen Linker ein, dann schrieb man sein
Programm, das die 1 MB-Grenze geflissentlich ignorierte und anschliessend konnte man dem Linker die Anweisung geben, das
Programm für den Protected Mode umzusetzen. Um das Programm auszuführen, brauchte man bei den meisten Extender eine kleine
Runtime-Datei, die man zusammen mit seinen Programmen frei verteilen durfte. Grössten Bekanntheitsgrad dürfte der DOS-Extender
DOS4GW bekommen haben- ihn wird der ein oder andere von Spielen her noch kennen.
Warum gab es EMS und XMS, wenn es auch so einfach ging? Nun, zunächst sind EMS und XMS Kinder der Vor-386--ra. Zweitens aber
war die Realisation eines DOS-Extenders eine technisch sehr aufwändige Sache, so dass, solange es DOS gab, die bekannten
DOS-Extender nie so frei zugänglich waren, sondern immer eine Stange Geld kosteten. Während ab DOS 4.0 der XMS-Treiber
Himem.sys eine kostenlose Dreingabe von DOS wurde. Mit DOS-Extendern zu entwickeln, blieb den Profi-Entwicklungssystemen
vorbehalten. Es gab allerdings auch Freeware-DOS-Extender, z.B. für die Borlandprodukte den Swallow-Extender Download hier), die
auch ziemlich problemlos einsetzbar waren. Der Nachteil des Swallow ist, dass er nicht im Grafik-Modus funktioniert - ein Handicap für
Spieleprogrammierer.
Auch sonst ist DOS-Extender nicht gleich DOS-Extender. Es gibt 16-Bit- (ab 80286) und 32-Bit-Protected-Mode-(ab 386)-Extender. Es
gibt Extender, die den Grafikmodus ermöglichen und welche, bei denen es nicht geht. Fast alle Extender haben enorme Probleme, den
Betrieb eines Debuggers zu ermöglichen. Z.B. funktioniert der Debugger im Protected Mode in BP7.0 nicht. Bei den Watcom-Compilern
13.11.2014 11:48
20 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
funktionierte er, aber nur über ein aufwändiges Threading (unter DOS wohlgemerkt!).
Wie funktioniert ein DOS-Extender? Das weiss ich auch nicht so genau. Eine gewisse Rolle spielt dabei wohl der Virtual-8086-Mode des
386er. Das Problem sind ja unter DOS die DOS-Aufrufe und insbesondere die Rückkehr zum Betriebssystem. Solange ein Programm
ganz ohne Dateizugriff arbeitet, den Bildschirmspeicher direkt beschreibt und der PC nach Beendigung des Programms neu gebootet
wird, sind Protected Mode-Programme auch auf dem 80286 kein Problem. Sollen aber Datei-, Bildschirm- und Druckerzugriff von DOS
genutzt werden, muss DOS im Real Mode aufgerufen werden. Das heisst, jeder Dateizugriff erfordert ein Hin- und Herschalten. Diese
Umschaltung ist naturgemäss nicht besonders schnell. Sie ist aber insbesondere enorm heikel, da die Inhalte sämtlicher
adressbezogener Register im jeweils anderen Mode bedeutungslos werden. So einen DOS-Extender hat wohl nie jemand geschrieben.
Die DOS-Extender für den 386er haben die Umschaltung nicht nötig. Sie lassen das Progamm im Protected Mode laufen und parallel
dazu einen Virtual-8086-Prozess und darin DOS. Jeder DOS-Aufruf wendet sich an diesen parallel laufenden Prozess. Und fertig ist die
Laube.
Da nun aber DOS im Real Mode und die Programme im Protected Mode laufen, sind die Programme praktisch ohne Oberhoheit,
besonders, was die Speicherverwaltung angeht. Zwei Protected Mode-Programme gleichzeitig können sich, müssen sich fast
irgendwann gegenseitig in die Speicherbereiche schreiben. Um das zu verhindern, entwarfen Lotus und Pharlap eine Art
Betriebssystem-Aufsatz für den Protected Mode, den VCPI-Standard. DOS-Extender, die dem VCPI-Standard genügten, nannte man
daher auch VCPI-Extender. Programme mit VCPI-Extender brauchen also zwei Assistenten: Das VCPI-System, das den Speicher
verwaltet und den eigentlichen DOS-Extender. Programme,die VCPI nutzten, waren nur mässig verbreitet. Mir sind hauptsächlich
Programme aus der Statistik und Numerik bekannt.
Als Microsoft 1990 sein Windows 3.0 herausbrachte, war ein DOS-Extender das Mittel der Wahl, die gestiegenen Ansprüche an
Ressourcen und Speicher mit der weiterhin existierenden DOS-Gebundenheit zu koppeln. Und es wäre naheliegend gewesen, dafür
einen VCPI-Extender zu verwenden. Vermutlich wegen der Lizenzkosten, vielleicht auch aus marktpolitischen Gründen und vielleicht
auch, weil Microsoft nun mal Microsoft ist, taten sie das nicht, sondern entwickelten ihren eigenen Standard. DPMI, das DOS Protected
Mode Interface. Immerhin enthielt Windows auch einen VCPI-Treiber, der VCPI in DPMI sozusagen übersetzte, so dass auch
VCPI-Programme unter Windows liefen.
(Siehe DPMI-Dokumentation von Tenberry)
Damit hatte man 1990 unter einem Windows-Entwicklungssystem zumindest volle Protected-Mode-Eigenschaften - endlich: Bis zu 64
MB Speicher, wenngleich dieser immer noch in 64K-Blöcke segmentiert war. (Es war bis 1994 selten, dass ein PC mehr als 16 MB
Speicher hatte.) Für Programmierer, die keine GUI's brauchten, war Windows aber zunächst keine ideale Umgebung. Ein einziger
Pointerfehler und schon war das ganze Windows abgeschossen. Dann hiess es: DOS hochfahren, Windows hochfahren, IDE
hochfahren, Programm laden. Für "Nicht-GUI's" war es das Beste, unter Windows 3.x im DOS-Fenster zu arbeiten. Dann brauchte man
bei einem Programmierfehler, sei es unter Turbo Pascal oder Turbo C++, nur ein neues DOS-Fenster aufzumachen und die IDE neu
hochfahren. Die Versionen der "Turbo"-Produkte von Borland, die seit 1992 auf den Markt kamen, machten von DPMI Gebrauch: Die
IDE lief selbst komplett mit DPMI, was es ermöglichte, innerhalb der IDE Binaries zu entwickeln und zu debuggen, die den
13.11.2014 11:48
21 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
640K-Bereich bis zum Rand füllten, mithin ein Entwicklungsvolumen im Megabytebereich aufwiesen. Seit 1992 unterschied Borland
auch zwischen Standard- und Professionalprodukt. Das Professionalprodukt hob sich vom Standardprodukt im Wesentlichen dadurch
ab, dass es dem Nutzer erlaubte, selbst 32-Bit-DPMI- Programme zu schreiben.
Was bedeutet eigentlich 16-Bit und 32-Bit? Das hat mit der Adressierung im Protected Mode zu tun, der s.g. virtuellen Adressierung.
Vorbei die Zeiten von physikalischen Adressen aus 16, 24 oder 32 Bit. Im Protected Mode wird die Idee der Segmente weiter
fortgeführt, indem eine virtuelle Adresse sich zusammensetzt aus einem s.g. 16-Bit-Segmentselektor und einem Offset-Selektor. Der
Segmentselektor gibt eine Adresse in einer Tabelle im Hauptspeicher an und erst dort steht, wo sich das Segment eigentlich befindet.
Beim 80286 ist der Offset-Selektor 16 Bit breit, ab dem 386 32 Bit, d.h. hier können die Segmente bis zu 4 GB umfassen. Was erhellt,
warum es möglich ist, mit dem 80386 in flacher Adressierung zu arbeiten.
Um Missverständnisse zu vermeiden: Wenn mit 32-Bit-Segmenten gearbeitet wird, macht die Arbeit mit Segmenten eigentlich gar
keinen Sinn mehr, da der Adressraum nur eines 32-Bit-Segments in einen 32-Bit-Adressraum reinpasst... Entsprechend ist in diesem
Fall in der LDT, der Local Descriptor Table, wo die physischen Basisadressen der Segmente stehen, nur ein Eintrag: Ein Segment und
dieses zeigt auf Basisadresse null.
Theoretisch jedoch ist der logische Adressraum 48 Bit breit, weil theoretisch mehr 32-Bit-Einträge als nur einer in der LDT denkbar
wären. So kommt die Vorstellung von "48 Bit" zustande: Ein 16-Bit-Selektor des Tabelleneintrags (der allerdings separat im DS-Register
gespeichert ist) und die 32-Bit breite Offset-Adresse.
Entsprechend unterscheiden sich die DOS-Extender: Die einen sind für den 80286, die anderen für den 80386 ausgelegt, die einen
segmentieren ihren Speicher in 64K-Häppchen, die anderen benutzen ein grosses 32-Bit-Segment.
BP 7.0 war insofern ein lustiger Zwitter, weil der Compiler für eine Adresse vorsichtshalber 48 Bit reserviert, obwohl der beigefügte
DOS-Extender nur ein 16-Bit-Extender ist, also lediglich mit 16-Bit-Segmenten umgehen kann. Findige Programmierer haben später flux
einen 48-Bit-Extender progammiert, so dass sie es schafften, auch mit dem BP 7 echte 48-Bit- (im landsläufigen Sinn "32-Bit-Software")
zu schreiben. Sehr theoretisch waren damit 256 TB adressierbar ;-)).
Wer sich allerdings nun vorstellt, mit oder ohne DOS-Bit-Extender- so problemlos in einem 16 MB-Speicher herumprogrammieren zu
können, wie unter Linux oder MacOS, der hat sich getäuscht. Neben einigen Einschränkungen, auf die ich gleich noch komme, lief der
Debugger für Protected Mode-Programme nicht. Weder der interne noch der externe.
13.11.2014 11:48
22 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Fenster zu den Eigenschaften einer DOS-Emulation unter Win 3.x. Hier können die Speicherbereiche unter der ganzen Speicherverwaltungsstandards, die sich im Laufe der DOS-Ära angesammelt haben, (EMS, XMS, DPMI) begrenzt werden, falls dies dem User notwendig erscheint.
Die Grenzen der "DPMI-Zeit"
Wer 1994 arglos von einem Atari, Amiga, Mac oder Unix-Rechner auf einen Win 3.x-PC umstieg, insbesondere, wenn er
Datenverwaltung oder numerische Berechnungen unternahm, konnte er arg frustriert werden. Nehmen wir an, er startete mit einem
80486, 8 MB RAM, Win 3.11 und Borland Pascal 7.0. Dann wird er wohl als erstes folgendes versucht haben:
VAR x: ARRAY[0..125000] of Double;
BEGIN
...
END.
Dies quittiert BP 7.0 beim Kompilieren mit "Stack overflow". Auch im Protected Mode. Grund: 1.) Keine Variable und kein Objekt darf
eine Segmentgrenze überschreiten. Das heisst, für eine einzelne Variable oder ein einzelnes Objekt stehen maximal 64K zur Verfügung.
Der Grund ist einfach: Innerhalb der Objekte wird mit 16-Bit-Adressen gearbeitet - die CP/M-Zeit läßt grüßen. 2.) Die Gesamtheit lokaler
13.11.2014 11:48
23 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Variablen einer Prozedur, bzw. des Hauptprogramms darf jeweils 64K nicht überschreiten - auch hier noch CP/M - es könnte ja sein,
daß Wordstar von 1975 wieder aufersteht!
Für große Datenmengen bleibt also nur eine Heap-Reservierung:
TYPE
tarray=array[0..125000] of Double;
parray=^tarray;
VAR
data: parray;
BEGIN
new(data);
...
dispose(data);
END.
Doch so etwas quittiert BP7.0 mit der Fehlermeldung: "structure too large": Jedes Speicherobjekt im Heap ist ebenfalls an das 64K-Limit
gebunden. Man muss es also in kleinere Stücke zerlegen.
Also stöhnt der Umsteiger mehrmals laut auf und programmiert dann:
TYPE
tarray=array[0..125000] of ^double;
parray=^tarray;
VAR
data: parray;
i: longint;
BEGIN
new(data);
for i:=0 to 125000 do
new(data^[i]);
...
for i:=0 to 125000 do
dispose(data^[i]);
13.11.2014 11:48
24 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
dispose(data);
END.
So geht's aber auch nicht. Schon wieder "structure too large": Das Zeigerarray umfasst 4 Bytes pro Zelle, also ca. 500K, was klar größer
als 64K ist.
Jetzt bleibt nur noch ein durch und durch uninformatischer Weg: Man stückelt das Array:
TYPE
tarray1=array[0..9] of double;
tarray2=array[0..12500] of ^tarray1;
parray=^tarray2;
VAR
data: parray;
i,j: longint;
BEGIN
new(data);
for i:=0 to 12500 do
new(data^[i]);
data^[i div 10]^[i mod 10]:=...
...
for i:=0 to 12500 do
dispose(data^[i]);
dispose(data);
END.
Hier erscheint alles in Ordnung: - Stack-Variablenspeicher 12 Bytes < 64K - Jedes Speicherobjekt < 64K, das größte ist tarray2 mit
12500x4 = 60000 Bytes
Wenn allerdings das Programm läuft, meldet es nach ca. 200K reserviertem Speicher einen "Heap Overflow". Spätestens an diesem
Punkt kehrt der Umsteiger wieder zurück zu seiner alten Kiste und fragt sich, wie es PC-Programmierer je geschafft haben, dieser
Maschine mehr als 64K Speicher zu entlocken...
Der Grund für den "Heap Overflow" ist diesmal allerdings eine Beschränkung des Compilers: Borland Pascal 7.0 verwaltet maximal
2048 Pointer. (Das habe ich nirgends dokumentiert gesehen, aber es ist offenbar so.)
Wenn man die Stückelung andes vornimmt, also z.B. durch
13.11.2014 11:48
25 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
TYPE
tarray1=array[0..999] of double;
tarray2=array[0..125] of ^tarray1;
parray=^tarray2;
kommt man zum Ziel. Wenn man das dann geschafft hat, fühlt man sich wie ein Gamer, der das höchste Level erreicht hat... Nur kann
man seine unbändige Freude niemand mitteilen. PC-Programmierer schweigen sich geflissentlich über diese Schwäche ihrer
Maschinen aus und der kleine 14-jährige BASIC-Anfänger aus dem Nachbarhaus auf seinem alten Atari ST von 1988 würde sich
kaputtlachen, wenn er erfährt, daß die stolze Leistung darin bestand, auf einer 8 MB-Maschine 0,8 MB Hauptspeicher zu adressieren!
Die Adressierungsprobleme der DMPI-Zeit lassen sich in zwei Kategorien einteilen:
a. Segmentierungsprobleme
b. Limits der Pointertabellen
Gäbe es a. nicht, würde b. wahrscheinlich gar auffallen. a. ist ein Problem von DPMI, vor allem der 32-Bit-Variante
b. ist ein Problem des jeweiligen Compilers - zumindest bis zu dem Punkt, an dem die Pointertabelle ebenfalls die Segmentgrenze
erreicht. Das heisst, in 16-Bit-Compilern wird die Pointeranzahl immer unterhalb 16K bleiben müssen.
Punkt a. betrifft ebenso das Programm selbst: Jedes Modul des Programms (in Pascal jede Unit) darf 64K an Umfang nicht
überschreiten. 1994 war also die CP/M-Ausrichtung des PC's für den Programmierer noch an allen Ecken und Enden spürbar!
32-bit-DPMI und Windows
Windows 3.x arbeitete mit 16-Bit-DPMI. Daher gab es dort viele 64K-Beschränkungen, z.B. konnte der Editor keine Dateien grösser als
64K laden. Lustigerweise erhielt sich diese 64K-Beschränkung bei vielen kleinen Dienstprogrammen auch noch in Windows95, obwohl
dieses 32-Bit-DPMI benutzte: Auch der notepad von Win95 kam bei mehr als 64K ins Straucheln...
Sobald man mit der Windows-API zu tun hatte, waren also 64K-Häppchen angesagt. Wenn's hoch kam. Voreinstellungen sahen oft
Stacks von 8K vor. Immerhin konnte man recht viele dieser Häppchen bekommen - eine 640K-Grenze gab's zum Glück nicht mehr...
Angenehmer war die Arbeit aus vielen Gründen in der DOS-Konsole. Erstens aus dem schon obengenannten Grund: Die
DOS-Konsolen hatten einen geschützten Speicherbereich und rissen nicht Windows mit in den Tod. Zweitens hatten sie in gar nicht mal
so schlechtes preemptives Multitasking. Und drittens konnte man unter der DOS-Konsole problemlos mit 32-Bit-DPMI arbeiten, da es ja
DOS-Extender gab. Hingegen gab es zunächst keine Windows-Extender.
Das änderte sich aber. Ca. 1994 kam Win32s auf den Markt. Dies war das Gegenstück zu einem DOS-Extender. Nun war es möglich,
auch reine Windows-Programme in vollem 32-Bit-Modus laufen zu lassen inkl. API-Aufrufe. Diese API-Aufrufe gingen an die Win32SSchnittstelle, die diese in 16-Bit-Aufrufe übersetzte und an die originale Win-API weiterleitete. Mehr als solch ein "Thunking"-Tool war
13.11.2014 11:48
26 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Win32S nicht.
Doch auch unter 32-Bit-DPMI war die Welt nicht immer gleich in Ordnung. So kollidierte man, wenn man arglos war, recht schnell mit
einer 64K-Grenze: Die Stackgrösse war oft by default auf 64K eingestellt. Man konnte sie allerdings, wenn man wusste wie, auf
mehrere MB einstellen - für naturwissenschaftlich-technische Programmierung ein Muss. Wenn man dachte, damit auch faktisch keiner
64K-Limitierung mehr zu begegnen, täuschte man sich: Es waren immer noch keine Speicherobjekte > 64K möglich. (Zumindest gilt das
für DOS4GW). Das konnte heimtückisch sein. Sammelten sich z.B. zuviele zu umfangreiche Eigenschaften in einer Klasse an, dann
konnte es leicht passieren, daß nach dem Hinzufügen eines einzigen Integers das Programm zwar weiterhin lief, aber irgendwelchen
Unsinn anstellte, da der klasseninterne 16-Bit-Adresszeiger den zusätzlichen Integer über eine Adresse > 64K anzusprechen versuchte,
was natürlich faktisch zum Modulo-Wert der Adresse wurde ("Wrap around").
Aber auch an der Obergrenze gab es ein Limit: Offenbar sind 32-Bit-Extender im Normalfall nicht in der Lage, mehr als 64 MB
anzusprechen. Das 64 MB-Limit rührt daher - es wurde weiter oben schon bei XMS angesprochen - daß in dem Moment, in dem das
System selbst den zur Verfügung stehenden Speicher über das BIOS ermittelt, es diesen von DOS über eine 16-Bit-Zahl mitgeteilt
bekommt - in Kilobyte zum Glück...
32-Bit-Programmierung, Win9x/ME/NT/2000
Seit Herbst 1999 programmiere ich unter NT mit Watcom C++ 10.5, Virtual Pascal und Excel 97 VBA, alles reine 32-Bit-Systeme. Die
letzte Begegnung mit dem 64K-Limit hatte ich vor ein paar Monaten, als eine Klasse in einem C++-Programm, das ich mit Watcom
pentiumoptimiert und mit flacher Adressierung kompilierte, bei 64K einen Wrap around produzierte. Das ist vermutlich eine
Compilereigenheit - nichtsdestotrotz ein CP/M-Relikt! Aber auch in VBA gibt es ein 64K-Limit, unter Excel97 (wahrscheinlich auch unter
Excel 2000 und XP) und ist sogar dokumentiert:
13.11.2014 11:48
27 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Diese Limits - man könnte sie im Zeitalter an der Schwelle zu den 64-Bit-Systemen getrost als Bugs bezeichnen - sind wohl kaum einer
Kompatibilitätsüberlegung geschuldet, sondern eher etwas willkürlichen Ausflügen der Compilerhersteller in die 16-Bit-Adressierung.
13.11.2014 11:48
28 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Dem Anwendungsprogrammierer werden sie in der Regel nicht auffallen, es sei denn, er arbeitet mit entsprechend hohen
Speicherlasten. Dann kann er damit gehörig auf die Nase fallen.
Die 64 MB-Grenze von DOS/Win 3.x kennt 32-Bit-Windows nicht. Hier wird's erst unter Win9x/ME bei 512 MB langsam eng. Die
Speicherverwaltungs- routine von Win9x, die z.B. beim Beenden eines Tasks den Speicher aufräumt, operiert nur bis zur 512
MB-Grenze. Als Programmierer kann man sich auch jenseits davon Speicher reservieren, aber Sicherheit ist dann nicht mehr garantiert,
daß man nicht Code oder Daten eines anderen Tasks überschreibt. Das dürfte allerdings kein grundsätzliches Handicap sein. Sicher
gibt es Anbieter für bessere Speichermanager, die das Problem bis zur 4 GB-Grenze beheben. Ausserdem wird die alte Windowslinie
bis ME wohl ausgestorben sein, wenn Speicher oberhalb 512 MB zum Standard werden. Unter NT und 2000, wie auch unter Linux ist
der 4 GB-Raum ohne Limit nutzbar. (Testen konnte ich das allerdings bisher noch nicht!)
Überblick: Die Hauptspeicherverwaltung der Windows-Versionen
Windows 1.x
Nur Real Mode
Kein Memory-Extender
Kein DOS-Extender
Limit: 640K
Prozessor: Mindestens 8086
Windows 2.x
2 Betriebsmodi:
Real Mode
Wie Windows 1.x
286 Mode
16-Bit-Protected Mode mit Hilfe eines DOS-Extenders
DOS-(Real Mode)-Treiber
Real Mode BIOS-Zugriff
EMS-fähig
Betrieb nur im Ring 0 ==> Keine Code Protection
13.11.2014 11:48
29 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Limit: 16 MB
Prozessor: Mindestens 80286
Windows 3.0
3 Betriebsmodi:
Real Mode
Wie Windows 1.x
286 Mode
Wie Windows 2.x
386 Enhanced Mode
32-Bit-Protected Mode, 64K segmented
Protected Mode Treiber
Protected Mode BIOS-Zugriff
EMS- und XMS-fähig
Betrieb nur im Ring 0 ==> Keine Code Protection
Limit: 64 MB
Prozessor: Mindestens 80386
Windows 3.1x
2 Betriebsmodi:
286 Mode
Wie Windows 2.x
386 Enhanced Mode
Wie Windows 3.0
13.11.2014 11:48
30 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Win32s
Betriebssystemaufsatz f. Win3.1x. Besteht aus "thunking"-Interface und eine kleine API im 32-Bit-Flat Model. Programme, die im
Flat-Model arbeiten, greifen über die Win32s-API auf die segmented Win3.1-API zu.
Windows95/98/ME
Nur 386 Enhanced Mode mit flacher Adressierung (32-Bit-API).
Segmented Model-Programme ("16-Bit") aus Win3.x-Zeiten werden hoch "gethunkt", d.h. segmented Model API übersetzt in flat
Model-API.
Protected Mode Treiber
Protected Mode BIOS-Zugriff
EMS- und XMS-fähig
Betrieb nur im Ring 0 ==> Keine Code Protection
Limit: 512 MB
Prozessor: Mindestens 80386
Windows NT/2000/XP/2003
Wie Windows 9x, aber:
Betrieb in allen Ringen ==> Code Protection.
Limit: 4 GB pro Task
Prozessor: Mindestens 80386
Hauptspeichermanagement mit Paging
Einleitung zum Paging
Was ist denn das schon wieder? Schon wieder Speicher in Bröckchen? Pages waren doch schon bei EMS und XMS da. Ach ja, und
überhaupt war der Speicher die ganze Zeit in 64K-Blöcke aufgeteilt. Waren wir das im 32-Bit-Mode nicht endlich los?
Nein. Es wird noch schlimmer. Es geht hier nicht um 64K-Happen, sondern um 4K-Häppchen...
Das Paging-System wurde mit dem 80386 eingeführt. Es hat nichts mit dem Deskriptoren-Modell des Protected-Mode zu tun, sondern
löste dieses quasi ab. Aus Kompatibilitätsgründen kann man beide simultan betreiben (damit 16-Bit-Software wie das gute alte MS
13.11.2014 11:48
31 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Word6, auf dem gerade diese Zeilen entstehen, auch noch auf einem 80386 laufen), aber beim 80386 hat das Deskriptorenmodell keine
Taskverwaltungsfunktion mehr.
Das Prinzip des Paging-Systems des 80386 wurde bei allen Prozessoren bis heute beibehalten. Es ist auch so in etwa in der AMD64und IA64-Architektur enthalten. Das, was gerade so auf uns zukommt, nämlich die 4 GB-Schwelle, ihre Limits und Nicht-Limits, die
Erweiterungen (PSE, PAE) und dass 64 Bit kein 64 Bit ist, kann man nur auf Basis des Pagings verstehen.
Die Hauptspeicherverwaltung eines modernen PC's muss auf zwei Ebenen stattfinden. Zum einen gibt es die Möglichkeit,
Hauptspeicher ins Filesystem auszulagern, den s.g. Swap-Space. Manchmal spricht man hier auch von "virtuellem" Hauptspeicher. Das
"Virtuell" möchte ich hier aber vermeiden, weil es zur Verwirrung mit der später anzusprechenden virtuellen Adresse kommen könnte.
Beide haben nichts miteinander zu tun.
Hauptspeicher besteht also vor der ersten Ebene aus Swap-Space und RAM. Beides muss zu einem gemeinsamen Adressraum
zusammengeführt werden. Das ist die eine Aufgabe. Die zweite ist es, diesen "technischen Speicher" dann an die einzelnen Tasks zu
verteilen. Und zwar so, dass die Tasks virtuelle Adressen sehen und nur der Speichermanager der CPU, die s.g. MMU, diese in eine
Adresse des gemeinsamen Adressraums übersetzen kann, also weiss, wohin was gehört.
Beide Aufgaben gleichzeitig werden dadurch erschlagen, dass die MMU den Speicher in Pages aufteilt. Sowohl die virtuellen
Speicherräume als auch den technischen Adressraum. Ausser in ein paar Ausnahmefällen, auf die ich hier nicht eingehe, sind diese
Pages bei x86-Prozessoren 4K gross. Fordert ein Task Speicher an, so bekommt er immer mindestens 4K. Daher hat man die Pages
nicht grösser gemacht: Man will den "Verschnitt", die Grösse des eigentlich gar nicht benutzten Speichers, nicht zu gross werden
lassen.
Die Pages werden von der MMU in einer Tabelle verwaltet, der s.g. Page Table. Ein Eintrag in dieser Tabelle ist 32-Bit breit. Die MMU
benötigt aber nur 20 Bit, da alle Pages im technischen, gemeinsamen, 32-Bit grossen Adressraum logischerweise bei Vielfachen von 4K
beginnen.
Die Adresse innerhalb einer Task besteht also aus zwei Teilen: Die unteren 12 Bit sind sozusagen der echte Page-Offset im technischen
Adressraum. Die oberen Bits geben an, die um welche Page in der Page Table es sich handelt. Und erst dort stehen die fehlenden 20
Bit der eigentlichen Adresse. Daher haben die Pointer-Adressen in modernen 32-Bit-Systemen meist viele führende Nullen: Da die
Tasks in der Regel nur ein paar Megabyte ihres 4 GB-Adressraums brauchen, werden nur die ersten der ca. 1 Mio. möglichen Pages
angesprochen. Und da jeder Task seine eigene Page Table hat, (wir erinnern uns: Wie beim 16-Bit-Protected Mode jeder Task seine
eigene Local Descriptor Table hatte...), stehen die Einträge alle fein säuberlich hintereinander.
Page Table Directories
Ein technisches Detail ist, dass 4 GB "ein Mega" = 1,048 Mio. Einträge in der Page Table benötigen. Ein Eintrag benötigt selbst 4 Byte,
so dass die Page Table in diesem Fall 4 MB Speicher benötigt. Das heisst, sie benötigt selbst 1024 Pages. Wo stehen aber diese Pages
im "technischen Adressraum"? Dazu muss es wiederum eine besondere Page Table geben und die hiesst "Page Table Directory".
13.11.2014 11:48
32 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Also: Jede Task bekommt bis 1024 Page Tables und ein Page Table Directory zugewiesen, über das die MMU ermitteln kann, welche
Adresse des virtuellen Adressraums jeweils dem "technischen" Adressraum entspricht.
Entsprechend werden die oberen 20 Bit für den Page Table-Eintrag in zweimal 10 Bits aufgespalten: Die obersten 10 Bit verweisen auf
den zuständigen Eintrag im Page Table Directoy, die mittleren 10 Bit auf den Eintrag in der jeweiligen Page Table und die unteren 12 Bit
stellen eben den Adress-Offset dar.
4 GB or not 4 GB
Damit kommen wir langsam zu der spannenden Frage, wo denn die Speichergrenzen bei 32-Bit-Systemen liegen. Wir sehen auf alle
Fälle, dass es mehrere Adressräume gibt und jeder von ihnen ein begrenzender Faktor darstellt:
Die Breite eines Pointers im virtuellen Adressraum: 32 Bit
Die Anzahl der Bits, die dazu dienen, Einträge im Page Table-System darzustellen: 32 Bit. (Das könnten theoretisch auch
weniger sein) ==> Virtueller Adressraum
Anzahl der Bits eines Page Table Entries plus Page-Offset: 32 Bit ==> Technischer Adressraum
Breite der Adresse innerhalb eines Speichersystems: 32 Bit oder 64 Bit beim Filesystem und 32 Bit bei 80386-Pozessoren bis
Pentium, 36 Bit bei x86-Architektur ab PentiumPro.
Die Grösse des technischen Adressraums bestimmt, wieviel Speicher alle Tasks zusammen belegen dürfen. Die Grösse des virtuellen
Adressraums, wieviel Speicher eine Task belegen kann. Die Breite eines Pointers besagt nur, wie breit Adressangaben innerhalb der
Programme sein müssen, ohne etwas darüber auszusagen, wieviel Bits davon wirklich interpretiert werden. Wir hatten das beim 808x
auch schon: Die Heap-Pointer waren 32 Bit, interpretiert wurden nur 20 Bit.
Task-Limits
Somit müsste ein Task 4 GB belegen können. Oder zumindest annähernd 4 GB, da ja der technische Adressraum auch auf 4 GB
beschränkt ist und das Betriebssystem auch noch Speicher braucht.
Wenn man das Experiment macht, stellt man enttäuscht fest, dass nach 2 GB bereits Schluss ist. Warum? Nun, wir hatten uns weiter
vorne mit der 640K-Grenze beschäftigt. In Diskussionsforen pflegt man heute den Kopf zu schütteln vor soviel Beschränktheit, damals
dieses 640K-Limit so fest verankert zu haben. Kann man eigentlich nur mit der technischen Rückständigkeit der damaligen Zeit
erklären, oder?
Nun, das 2 GB-Limit ist nicht viel anderes als das 640K-Limit des technischen Adressraums. Oberhalb der 2 GB-Grenze blendet die
MMU die Adressen des technischen Adressraums sozusagen 1:1 in den virtuellen Adressraum ein. Warum? Aus genau den gleichen
Gründen, aus denen man vor 20 Jahren die UMA freigehalten hat: Damit Peripherie-Hardware feste Adressen zugewiesen werden
können. So sitzt hier der Adressraum des PCI-Busses, des AGP-Busses, der Schnittstellen usw. Darüberhinaus sitzen hier aber auch
13.11.2014 11:48
33 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
die Routinen des Betriebssystem-Kernels. Man hat diese Adressen nicht dem Paging unterworfen, weil sonst die
Zugriffsgeschwindigkeit auf die entsprechenden Speicherbereiche durch den MMU-Übersetzungsvorgang drastisch zurückgegangen
wäre.
Im "Normalfall" ist man also auf 2 GB pro Task beschränkt. Die Betriebssystem-Kernel von Linux und Windows können allerdings auch
in einem s.g. 3/1-Modus arbeiten: Task=3 GB, Kernel=1 GB Adressraum. Dazu muss man den Linux-Kernel neu kompilieren. Bei
Windows klappt dieser 3/1-Betrieb nur mit speziellen Server-Versionen von WindowsNT/2000 (Enterprise, bzw. Enterprise,Datacenter)
und mit Windows2003. Hier müssen Parameter in der boot.ini angegeben werden.
Theoretisch 8 GB
Nach der bisherigen Darstellung ist der technische Adressraum aus RAM und Swap zusammen 4 GB gross. Warum eigentlich nicht 8
GB? Schliesslich müssen die 20-Bit-Adressen in den Page Table-Einträgen, die s.g. Frame-Adressen, da sie auf verschiedene
physische Speicher verweisen, nichts miteinander zu tun haben. Und schliesslich dient ein Attributflag dazu, festzustellen, ob eine Page
ausgelagert ist oder nicht, also als Unterscheidung zwischen den beiden Adressräumen. Mithin müsste der technische Adressraum
33-Bit-Adressen besitzen. Die Frage ist lediglich, ob es nicht für Betriebssysteme ratsam ist, für den Swap Space zum RAM disjunkte
Adressen zu verwenden. Ein Beispiel mit lediglich zwei RAM- und vier Swap-Pages, wo dies nicht so ist, ist in der folgenden Abbildung
dargestellt.
13.11.2014 11:48
34 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Leider habe ich kein System, mit dem ich das mal ausprobieren könnte und habe darüber auch bisher nichts gefunden, so dass ich
nicht sagen kann, ob ein PentiumPro(+) im Standardbetrieb (also ohne PAE, siehe weiter unten) für alle Tasks gemeinsam 4 GB oder 8
GB technischen Adressraum bereithält.
Jenseits der 32 Bit
Es liegt nahe, an der Schwelle zur 64-Bit-Zeit zu fragen, ob sich der Übergang ähnlich schwierig gestalten wird, wie der Übergang von
der 16- in die 32-Bit-Welt. Wird es eine 4GB-Segmentierung geben? Und ein 40 GB-Limit, so wie es ein 640K-Limit gab?
Nun, das Zeitalter jenseits 4 GB ist längst schon eröffnet. Zu einer Zeit, in der selbst Power-Anwender kaum an die 4 GB-Grenze
stossen werden. Lediglich in dem Bereich, der 1980 "Grossrechnerbereich" geheissen hätte, also im Bereich z.B. von Datenbanken
grosser Unternehmen und den entsprechenden Servern oder im Bereich von professioneller Animationsproduktion und
Videoverarbeitung dürfte die 4 GB-Grenze schon ein Thema sein.
Ca. 1994 brachte Intel den ersten Prozessor der Linie P6 heraus, den Pentium Pro. Prozessoren dieser und späterer Linien haben
einen 36-Bit breiten physikalischen Adressbus. Obwohl der Befehlssatz weiterhin mit 32-Bit-Adressen arbeitet. Wir haben also quasi die
umgekehrte Situation wie früher: Nicht breitere logische Adressen als physische Adressbreite (32 Bit und 20 Bit beim 8088/86), sondern
umgekehrt.
Physisch kann ein PentiumX, X=Pro,II,III,4 also 64 GB adressieren. Aber natürlich gibt es heute ähnliche Schwierigkeiten, an den
Speicher heranzukommen, wie vor 15 Jahren an den 16MB-Speicher eines 80286. Aus genau dem gleichen Grund: Kompatibilität, der
eine Veränderung des Befehlssatzes auf 64 Bit untergeordnet wird. Hätte Intel den Befehlssatz beim PentiumX geändert, würde kein
Binary mehr auf einem Pentium UND einem PentiumX laufen. Sondern nur entweder oder. Das sollte vermieden und der
386-Befehlssatz beibehalten werden. Hurra, wir dürfen wieder basteln!
PSE36
Die erste Lösung, die sich Intel hat einfallen lassen, um die 36 Adressbeinchen einer modernen Pentium-CPU auch einem Zweck
zuzuführen, nennt sich PSE36. Hier wird kurzerhand festgelegt, dass jeder Page-Table-Eintrag nicht eine 4K-Page, sondern eine
4M-Page adressiert. Damit kann ein Page-Table-Eintrag mit seinen 20 Bit natürlich nicht nur 4 GB adressieren, sondern 4 TB. Die
virtuelle Adresse wird dann in 10 plus 22 Bits aufgeteilt, für die "Ausleuchtung" eines 4 GB-Adressraums sind nur noch 2^10 Pages
notwendig, die natürlich alle in eine 4M-Page gehen - ein Page Directory ist nicht mehr notwendig.
Der Nachteil des Verfahrens ist auch klar: Enorm viel ungenutzter Speicher. Jede Task, auch wenn sie nur 10K Speicher anfordert,
kriegt 4 MB zugesprochen. Sind 50 Tasks am Laufen, (für ein Multitasking-Betriebssystem mit seinen Diensten völlig normal) sind 200
MB Hauptspeicher gleich mal so weg. OK, auf der anderen Seite: Man wird PSE36 nur benutzen, wenn man mehr als 2 GB
Hauptspeicher hat und dann sind 200 MB auch nicht die Welt...
Unter Windows ist PSE36 nur mit der Enteprise-Edition von NT verfügbar.
13.11.2014 11:48
35 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
PAE
PAE ist die wesentlich elegantere Lösung: Die Page Table-Breite wird von 32 Bit auf 64 Bit erweitert. Auf diese Art und Weise können
volle 16 EB technischer Adressraum verwaltet werden. Schwierigkeit: Die Table braucht doppelt soviel Platz. Und damit haben nur noch
halb soviele Pages in einer 4K-Page Platz. Auf der anderen Seite braucht man dann aber auch nur noch 9 statt 10 Bit der virtuellen
Adresse, um einen Page Table-Eintrag anzusprechen. Es bleiben also 2 Bits am "oberen Ende" der virtuellen Adresse übrig, die man
dazu verwenden kann, ein drittes Page Table-Level einzuführen. So dass man nun bis zu 4 Directories und bis zu 4 mal 512 Page
Tables pro Task hat.
LINUX kann mit der PAE-Option kompiliert werden. Bei Windows sind die PAE-tauglichen Versionen die Enterprise- und DataCenterVersionen von Win2000, sowie Win2003 Server und WindowsXP, SP2.
Paging in der IA32-Architektur mit PAE:
13.11.2014 11:48
36 von 43
http://www.askos.de/ram/index.html#msdos
13.11.2014 11:48
Wie kriege ich Hauptspeicher?
37 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
AWE
AWE heisst "Adress Windows Extension" und ist ein Feature, um einzelnen Tasks unter IA32 die Nutzung von mehr als 3 GB Speicher
zu erlauben. Mit AWE sind wir da, wo wir vor 20 Jahren schon mal waren: Beim XMS des Jahres 2000. Damit kann ein Programmierer
bis zu 64 GB (in den bisherigen Releases nur bis 32 GB) ansteuern, die Speicherverwaltung mit eingeblendeten Fenstern usw. muss er
sich allerdings selbst schreiben.
Von 36 auf 64 Bit
Im s.g. Workstation-Markt (der Name wurde mit dem Aufkommen der SUN-Desktop-Computer Mitte der 80er geprägt und bedeutete:
Maschine, die preislich und leistungsmässig eindeutig oberhalb der Alltags-PCs liegt, hauptsächlich im Bereich professioneller Grafik,
Filmtechnik, Numerik, CAD usw. angewendet wird, aber ein Desktopcomputer ist, der weithingehend nur von einer Person simultan
genutzt wird) gab es schon seit Mitte der 90er-Jahre 64-Bit-Prozessoren. Hauptsächlich aus Gründen der Rechengeschwindigkeit und
nicht so sehr aus Gründen der 4GB-Grenze.
Die x86-Architektur
In 2001 und 2003 kamen zwei neue Prozessorenfamilien auf den Markt, deren Befehlssätze nicht nur Erweiterungen der Befehlssätze
des 80386 sind, sondern völlig eigenständig und inkompatibel zum Befehlssatz: Der Itanium von Intel und der Opteron von AMD. Es ist
klar, dass mittelfristig einer von beiden der Nachfolger der 386-Familie sein wird.
Kurz ein Rückblick: Wenn nun etwas abgelöst wird, was wird eigentlich abgelöst?
Wir hatten bisher folgende Architekturen und damit Befehlssätze:
8086 64K-segmentierte Adressierung, 1 MB-Adressraum.
80286/Protected 64K-segmentierte Adressierung, 16 MB-Adressraum.
80386/Protected Flache Adressierung, 4 GB-Adressraum.
Alle Prozessoren seit dem 80386 haben keine neuen Befehlssätze und damit keine neuen Betriebsmodi der Prozessoren mehr
gebracht, sondern lediglich Erweiterungen des Befehlssatzes: MMX (Pentium/Pentium II), SSE (Pentium III) und SSE2 (Pentium 4),
bzw. 3DNow (Athlon).
Zu jedem der drei x86-Architekturen, die es gegeben hat, gehören entsprechende Betriebssystem-Generationen:
8086: DOS
80286/Protecetd: OS/2 und Windows 3.x
13.11.2014 11:48
38 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
80386/Protected: Linux und Windows NT
Wenn man sich das mal genau anschaut und sich vergegenwärtigt, dass Windows XP das erste Windows-Betriebssystem "für alle" ist,
dem der NT-Kernel zugrundeliegt, dann heisst das, dass eben gerade erst in 2002/2003 die breite Masse anfängt, 32-Bit-Prozessoren
als solche zu nutzen. Das muss man sich auf der Zunge zergehen lassen!
Die Itanium-Architektur
Etwa 1997 startete die Firma Intel ihr 64-Bit-Prozessorenprojekt, zusammen mit der Firma Hewlett-Packard. Zuerst war man sehr
gespannt auf den Nachfolger der Pentiumbaureihe und nahm die Hinweise, dass es sich bei dem Prozessor in erster Linie um einen
Workstation-Prozessor handeln solle, nicht besonders ernst. Als sich die Entwicklungsarbeiten jedoch jahrelang hinzogen, begriffen die
Aussenstehenden, dass Intel tatsächlich wohl kein grosses Interesse haben würde, den Massenmarkt zu beliefern. So stellt sich die
Situation auch heute, einige Jahre nach Auslieferung der ersten Itaniumserien dar. Es wird wohl noch bis zu 5 Jahre dauern, bis die
Itaniums - wenn überhaupt jemals - in die PCs der oberen bis mittleren Kategorie diffundiert sind. Es lässt sich noch überhaupt nicht
sagen, ob der Itanium einmal eine ähnliche Verbreitung finden wird, wie die 386-Prozessoren.
Der Itanium ist ein reiner 64-Bit-Prozessor, dessen Befehlssatz nichts mehr mit dem 386er-Befehlssatz zu tun hat und zu diesem völlig
inkompatibel ist.
Um dennoch 32-Bit-Programme (386er-Protected-Mode) ausführen zu können, hat er eine Emulation eingebaut, die diesen Mode in
seine eigentlichen Befehle übersetzt. Vorerst (Anfang 2004) ist er dabei ziemlich langsam und erreicht dabei nicht annähernd die
Leistung der aktuellen 32-Bit-Prozessoren.
16-Bit-Programme (Real- und 286-Protected) kann er gar nicht mehr ausführen. Was heisst, dass man eine Itaniummaschine nicht unter
DOS booten kann - jedoch unter 32-Bit-Linux.
Die AMD64-Architektur
Diese unterscheidet sich grundlegend vom Itanium. Auch hier ist noch überhaupt nicht zu sagen, welche Verbreitung diese Architektur
einmal haben wird. Wenn man die Geschichte betrachtet, hat diese Architektur die besseren Karten als die Itanium-Architektur, das hat
das Experiment Intels mit dem 80186 und iAPX-432 gezeigt: Kompatibilität ist alles. Und Kompatibität des Itanium ist dürftig. Auf der
anderen Seite dürfte es schwer sein, die Marktmacht von Intel zu brechen. Hier wird die Haltung von Microsoft sowie der weitere Erfolg
von Linux eine grosse Rolle spielen.
Die AMD64-Architektur ist ähnlich wie die 80386-Architektur aufgebaut: Der Prozessor beherrscht alle Abwärtsmodi und dann noch
seinen eigenen "Protected Mode". Zunächst unterscheidet man bei AMD64
1. den Legacy-Mode
2. den 64-Bit-Mode
13.11.2014 11:48
39 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
Man kann ein Betriebssystem nur in einem der beiden Modes starten. Startet es im Legacy-Mode, verhält sich der Prozessor ganz und
gar wie ein 32-Bit-Athlon, d.h. 386er. Das heisst, ein AMD64 kann auch mit DOS oder Win3.x gebootet werden, wenn einem danach ist.
Im 64-Bit-Mode muss das Betriebssystem ein 64-Bit-Betriebssystem sein, da es mit 64-Bit-Adressen und -Registern umgehen können
muss. Es ist aber durchaus möglich, innerhalb des 64-Bit-Systems 32- oder 16-Bit-Programme laufen zu lassen, d.h. Programme, deren
Adressierung und Befehlssatz einem 8086/286-Protected oder 386-Protected entspricht.
Machen diese Programme ausser Speicheranforderungen keine weiteren Betriebssystemaufrufe, dann laufen sie innerhalb des 64-BitBetriebsystems ohne weitere Vorrichtungen. Die meisten Programme machen aber Betriebssystemaufrufe, um ans Dateisystem oder an
die API zu kommen. Dazu braucht es dann einen Layer, der diese Aufrufe von der alten API mit 32-Bit-Adressierung in die neue mit
64-Bit-Adressierung übersetzt. Linux 9.0 und die erste Version von WindowsXP für AMD64 haben solche Layer für 32-Bit-Programme,
jedoch nicht für 16-Bit, also Real- oder 286-Protected-Mode-Programme. Bei Linux ist das Fehlen (fast) trivial: Es gab nie ein 8086oder 80286-Linux. Bei Windows wird sich zeigen, wie einfach oder schwierig es ist, die NTVDM (der 16-Bit-Layer für WindowsNT) bei
Bedarf vorzuschalten, um mit diesem doppelten Layer die Übersetzung 16 Bit nach 64 Bit zu schaffen.
AMD64: Wieviel Adressraum gibt's denn nun eigentlich?
In den Programmen im 64-Bit-Modus sind die Pointer 64 Bit breit, die virtuellen Adressen allerdings nur 48 Bit. Sie werden in 4 mal 9 Bit
Zeiger auf eine 4-Level-Page-Table-Struktur und 12 Bit Page-Offset aufgeteilt. Insgesamt kann ein Task damit 256 TB Speicher
ansprechen, alle zusammen haben einen technischen Adressraum von 16 EB. Das RAM ist bei den derzeitigen Prozessoren mit 40 Bit
angebunden. Das dürfte auch reichen: Um 1 TB Speicher zusammenzubekommen, müsste man 512 2GB-Module implementieren, was
Kosten in der Höhe von einer halben Million Dollar verursachen würde. 1 TB virtueller Speicher ist allerdings gar nicht mehr so
illusorisch; schliesslich kostet ein Array aus drei 400 GB-Platten Mitte 2004 gerade mal um die 1000 Dollar.
Brüche
Die nächsten Brüche sind also bei AMD64 noch weit: Sollte der Adressraum von 1 TB nicht mehr ausreichen, braucht AMD nur ein paar
Beinchen mehr an den Prozessor zu hängen, am Betriebssystem oder gar den Programmen müsste man nichts ändern. Reichen die
256 TB virtuelle Adressierung nicht mehr aus, müsste man das Betriebssystem updaten, in der Art, wie jetzt das SP2 für WindowsXP
herauskommt. Für die Programme wären keine Änderungen notwendig. Die kämen erst, wenn dann auch die 64 Bit-Pointer nicht mehr
reichten. Dann geht's mit XMS für 64-Bit los...;-)
Die Grenze von 16 ExaByte und das 64-Bit-XMS dürften nur noch die jüngere heutige Generation erleben: Bei linearer Fortschreibung
in ca. 50 Jahren.
Übergänge
Man sieht: Technisch spielt sich heute am Übergang vom 32-Bit ins 64-Bit-Zeitalter Ähnliches ab, wie einstmals beim Übergang vom 16ins 32-Bit-Zeitalter. Doch aus verschiedensten Gründen bleibt der Programmierer von den Auswirkungen viel stärker abgeschottet, als
13.11.2014 11:48
40 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
vor 15 Jahren:
1. Der Übergang zum breiteren Bus vollzieht sich ein einer Zeit, in der noch weithingehend keine Speichernot herrscht.
2. Speicherzugriffe des Prozessors sind heute keine Direktzugriffe mehr, sondern werden über eine MMU abgewickelt, weswegen
Programm-Adresse und physische Adresse nicht mehr sehr eng verkoppelt sein müssen. Wenn heute für den
Leistungsanwender ein Speicherproblem auftaucht, dann hauptsächlich nicht dadurch, dass ein Programm mehr als 4 GB
fordert, sondern 10 Programme zusammen mehr als 4 GB. Letzteres Problem ist durch die Verwendung von MMU's
konzeptionell keines mehr. Und selbst Programme können ja in mehrere Prozesse aufgeteilt werden, was den Speicherzugriff
zwar etwas verlangsamt, aber vielleicht sogar einfacher macht, als mittels AWE realisiert.
3. Heutige Programme sind keine Assembler-Handstrickprodukte mehr, sondern Konstruktionen aus Bibiliotheksbausteinen, die z.T.
nicht einmal Bestandteil des Programms selbst, sondern anderer Programme oder des Betriebssytems sind. Falls sie Bestandteil
des eigenen Programms sind, gibt es sie im Quellcode. Der Weg, sie auf 64 Bit umzurüsten, ist straight forward: Einfach neu
kompilieren und linken und fertig. Wir sehen heute schon, daß in dem Moment, in dem die ersten 64-Bitter auf den Markt
kommen, auch schon die ersten Betriebssysteme und Distributionen dafür bereitstehen.
4. Das Mittel zur Downward-Kompatibilität lautet inzwischen nicht mehr "Bank Switching" oder "Segmentierung", sondern
"Emulation". Man simuliert quasi das alte Betriebssystem innerhalb des neuen. Das hat Apple beim Übergang vom Motorola zum
Power-Prozessor mit MacOS vorgemacht, das funktioniert auch bei NT/2000 bzgl. 16-Bit-Software und das wird auch ein 64-BitWindows bzgl. 32-Bit-Anwendungen können. Und von Fremdherstellern wird es sicher bald auch die 8/16-Bit-Emulation auf
64-Bit-Systemen geben.
Eine gewisse Herausforderung schien mir Anfang 2000 der Übergang für Linux darzustellen. Für abwärtsinkompatible
Prozessoren wie den Itanium gilt: Solange die Linux-Gemeinde nicht eine Virtual Machine für 32-Bit-Linux auf die Beine stellt,
wird sich die Linux-Programme-Welt in zwei Teile spalten: In 32-Bit-Linux und 64-Bit-Linux. Aber erstens reduziert die ADM64Architektur dieses Problem auf die Erstellung eines entsprechenden Layers - und das ist wohl schon erfolgreich geglückt. Und
zweitens wird Linux die Open Source-Philosophie entgegenkommen: Kaum ein liebgewonnenes Utility, für das nicht die Source
gleich mitgeliefert wird, so dass für eingefleischte "Pinguins" bei der Anschaffung einer 64-Bit-Maschine im schlechtesten Fall
Neukompilieren auf dem Tagesplan stehen, aber sie nicht wirklich auf ihre Schätze verzichten müssen, die nicht ohnehin schon
als 64-Bit-Binaries auf den Distributionen-CDs oder im Internet zu finden sind.
Beim Übergang von 32 nach 64 Bit kein Problem. Dann wiederum an die Geschichte zurück gefragt: Warum hat es von 16 nach
32 Bit soviel Probleme gegegen? Warum wurde nicht die gleiche Methode angewandt wie heute: Emulation? Ganz einfach: Nicht
nur die Größenordnung an Speicherplatz ist in den letzten Dekaden angestiegen, sondern auch die Größenordnung an
Rechenleistung. Ein Emulator frisst beides: Speicherplatz und Rechenzeit. Während dieser Verbrauch heute allerdings unter 5
Prozent der Maschinenleistung liegt, waren es auf einem 8088 eher 50 Prozent oder mehr. 1981 die Rechenleistung eines
13.11.2014 11:48
41 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
teueren PC mit einem CP/M-Emulator so herunterzubremsen, dass die Maschine langsamer schlich als das 8-BitKonkurrenzprodukt, das war keine ernstzunehmende Alternative.
Es gibt aber noch einen weiteren Unterschied zwischen 2001 und 1981: 1981 war der Speicherplatz, den der maximale
Adressraum zur Verfügung stellte, einfach knapp. Die Programmierer waren Künstler darin, Bytes und Bits einzusparen (siehe TP
1.0) und programmierten oft deshalb in Assembler. Und trotzdem waren 64K damals ein enges Korsett. Das kann man heute
über 4 GB nicht sagen. Genauer gesagt wissen die Programmierer eigentlich nicht so recht, wie sie 128 MB sinnvoll füllen sollen.
Manchmal habe ich das Gefühl, da wird absichtlich erstmal blind Speicher alloziiert, den das Programm in Endeffekt gar nicht
braucht. Es ist ja kein Problem, ein Programm mit einem Stack von 10 MB auszustatten und die entsprechende
Compileroptimierung auszuschalten, so daß tatsächlich 10 MB reserviert werden, obwohl das Proggy mit 1 MB auch
ausgekommen wäre. Da werden komplette Bibliotheken doppelt und dreifach gelinkt, so daß eine simple Icon-Leiste (z.B. OfficeLeiste) auf 4 MB anschwillt. (Das ist der komplette Umfang von MS Word 5.0 für DOS!) Wirklich knapp wird's vielleicht hier und
da im Multimedia-Bereich. Und Spiele kriegen noch jeden Hauptspeicher voll. Aber auch hier reicht nicht einmal die Phantasie,
sich vorzustellen, wie man 4 GB sinnvoll füllen könnte, geschweige denn, wie sie zu knapp werden könnten. Oder umgekehrt
formuliert: Hätten wir heute ein 64 MB-Limit, könnte m.E. noch soviel speicheroptimiert werden, daß erst um 2005 herum die
Softwareentwicklung ernsthaft gebremst würde. Und wenn die Bremswirkung einer 4 GB (64 GB)-Grenze einsetzen würde, wird
es 32-Bit-Software nur noch auf ausrangierten PCs in verstaubten Kellern geben.
Doch: Wird dann auch das 64K-Limit völlig verschwunden sein?
Literatur zum Thema
Matthias Withopf:
UltrAWEit
Wie Linux und Windows bislang mit großem Speicher umgehen
c't 13/01, Seite 147
Andreas Stiller
Speicherschieber
Vom mühevollen Weg der Daten zwischen Prozessor und Speicher
c't 3/00, Seite 260
Links zum Thema
Overview of Memory-Management Functionality in MS-DOS (Q95555)
13.11.2014 11:48
42 von 43
http://www.askos.de/ram/index.html#msdos
Wie kriege ich Hauptspeicher?
msdos memory types
Memory Use By Windows
Developer Information: memory
OSRC: Protected Mode
XMS memory
Phil Storrs PC Hardware book
MS Windows Version History
Die Geschichte von Turbo Pascal und Delphi
In the Museum: Turbo Pascal v1.0
13.11.2014 11:48
43 von 43