# High Memory Area

Der Begriff High Memory Area (HMA, englisch teils auch verkürzt himem area) bezeichnet bei einem x86-kompatiblen Prozessor im 16-Bit-Betriebsmodus Real Mode die ersten 65520 Byte oberhalb der 1-MiB-Grenze. Die HMA ist ab dem Intel 80286 verfügbar. Die deutsche Übersetzung hoher Speicherbereich ist inzwischen ungebräuchlich geworden. Ursprünglich eingeführt wurde dieser Hack unter der Bezeichnung HIMEM.

## Entstehungsgeschichte

Der ursprüngliche IBM PC nutzte einen 8088-Prozessor, der nur einen Mebibyte an Speicher direkt adressieren kann. Dieser Betriebsmodus wird ab dem 80286 als englisch Real Mode bezeichnet, der durch den neuen Betriebsmodus Protected Mode abgelöst werden sollte. Als Intel den 80286 entwarf, war noch nicht klar, welchen Erfolg die PC-Plattform mit dem darauf dominierenden Betriebssystem MS-DOS und PC DOS haben würde. Der Protected Mode ist daher nicht mit der bestehenden Software kompatibel, die weiterhin den Real Mode nutzte. In diesem laufen auch alle neueren x86-Prozessoren im 8086-komaptiblen Modus, in dem nur 1 MiB RAM direkt adressierbar bleibt.
Im 80286 können 16 MiB Arbeitsspeicher im Protected Mode genutzt werden, ab dem 80386 sind es 4 GiB (4096 MiB). Dieser Speicher liegt unter 8088/8086-kompatiblen reinen 16-Bit-Systemen wie anfangs PC-kompatiblem DOS allerdings brach, denn im Real Mode kann nicht darauf zugegriffen werden. Erst mit der Extended Memory Specification, kurz XMS, konnte dieser „Erweiterte Speicher“ auch unter 16-Bit-Betriebssystemen im Real Mode, allen voran DOS, genutzt werden.
Der HIMEM-Trick nutzt die Art und Weise aus, wie der Real Mode ab dem 80286 emuliert wird. Der Zugriff auf den RAM wird dabei in Segmente aufgeteilt, das sind 16 sich nicht überlappende Speicherseiten à 64 kB. Beim 8088/8086 endet der Speicher bei 1 MiB (1024 kB) und es kommt zu einem Überlauf, wenn Speicher über dieser Grenze angesprochen wird. Dieser Umstand wurde von vielen DOS-Programmen ausgenutzt, um sie schneller zu machen. Beim PC/AT musste sich IBM daher einen Mechanismus ausdenken, damit sich auch der 286er wie der originale IBM PC verhält, und hat die A20-Leitung eingeführt. Diese kann ein- und ausgeschaltet werden, sodass es auch möglich wird, keinen Überlauf hervorzurufen. Da die Segmentadressen im Regelfall 16 Bytes groß sind, werden diese beim HIMEM-Trick in den letzten 16 Bytes, die innerhalb des 1 MiB vom Real Mode zugreifbaren Speicherbereichs liegen, abgelegt. Der darin definierte Speicherabschnitt liegt damit 64 kB, minus den 16 Bytes, im Erweiterten Speicherbereich oberhalb der 1-MB-Grenze des Real Mode, und wird vom 80286 und nachfolgenden Prozessoren auch korrekt angesprochen, während der Prozessor dennoch im Real Mode verbleibt.
Dieser Programmiertrick findet sich unter anderem im Taskswitcher DESQview von Quarterdeck. Microsoft griff dieselbe Technik mit Windows 2.1 auf, das erstmals mit HIMEM.SYS ausgeliefert wurde.
Unter DOS kann die HMA dazu genutzt werden, Teile von sich selbst in diesen Bereich zu verschieben, um mehr Konventionellen Speicher für Programme zur Verfügung zu haben.

## HIMEM.SYS / HIDOS.SYS

Da zu MS-DOS auf dem IBM PC kompatibles DOS ursprünglich nur das erste Mebibyte des Hauptspeichers verwaltete, traten Probleme auf, sobald mehr als ein Programm oder Treiber die HMA nutzen wollten. Um dieses Problem zu lösen, wurden in den Speichermanager HIMEM.SYS, der den Zugriff auf den Erweiterten Speicher regelt, Funktionen aufgenommen, die die Reservierung und Freigabe der HMA regelten.

## Nutzung der HMA

Ab DR DOS Version 5.0 (1990) und MS-DOS Version 5.0 (1991) war DOS in der Lage, seinen eigenen Systemkern in die HMA zu verlagern, wenn HIDOS.SYS bzw. HIMEM.SYS geladen war. Dies wurde durch die Option HIDOS=ON bzw. DOS=HIGH in der Konfigurationsdatei CONFIG.SYS erreicht. Damit wurde weniger „konventioneller Speicher“, also Speicher unterhalb der 640-KiB-Grenze, vom DOS-Kern belegt, was bei der chronischen Speicherknappheit unter DOS vorteilhaft war.
Bei DR DOS konnte nicht nur ein Teil des Systemkerns selbst in die HMA verschoben werden, sondern auch der residente Teil des Kommandozeileninterpreters COMMAND.COM (mit Option/MH), Teile der Pufferverwaltung (HIBUFFERS) und ab DR DOS 6.0 eine ganze Reihe von speziell dafür ausgelegten Treibern wie KEYB, NLSFUNC und SHARE (jeweils mit Option/MH), wodurch weiterer konventioneller Speicher für Anwendungen und normale Treiber frei wurde.
Ab DR-DOS 7.02 erlaubte der Parameter SIZE=xxxx der Konfigurationsdirektive SHELLHIGH= eine Feineinstellung der Präallokation für den residenten Teil des Kommandozeilenprozessors, womit insbesondere bei der Verwendung von alternativen Kommandozeilenprozessoren wie 4DOS einer Fragmentierung der HMA vorgebeugt werden konnte (etwa mit SHELLHIGH SIZE=20 c:\4dos.com ... in CONFIG.SYS), so dass insgesamt noch mehr zusammenhängender freier Speicherplatz für HMA-fähige Treiber nutzbar wurde.
Obwohl eine möglichst weitreichende Nutzung der HMA durch Treiber erstrebenswert war, machten insgesamt nur vergleichsweise wenige Treiber davon Gebrauch und wenn, dann in der Regel nur exklusiv, ohne dass dann gleichzeitig auch noch Teile des Betriebssystems oder andere Treiber in die HMA hochgeladen werden konnten.
Aufgrund der Tatsache, dass die Adressleitung A20 über das A20-Gate jederzeit von anderen laufenden Prozessen maskiert werden konnte, wodurch die HMA temporär nicht mehr erreichbar war, konnten nur Programmteile in die HMA verlagert werden, die über kurze Funktionen (sogenannte stubs) im konventionellen Speicher angesprungen wurden, in denen sichergestellt wurde, dass die A20-Leitung temporär wieder aktiviert wurde, bevor Code oder Daten in der HMA angesprochen wurden, also z. B. keine Interruptroutinen. Auch der Aufruf von externen Unterroutinen (mit nicht immer vollständig bekannten Seiteneffekten durch TSRs) aus der HMA heraus oder die Unterbrechung durch Interrupts war nicht unkritisch und erforderte besondere Vorsorgemaßnahmen in der Implementierung, da sich dabei sonst der Zustand des A20-Gates „scheinbar zufällig“ ändern konnte. Da von Seiten des Betriebssystems hierfür nur rudimentäre APIs zur Verfügung gestellt wurden und für eine sichere Implementierung etliche nicht sofort offensichtliche Race Conditions zu beachten waren, war eine Hochlademöglichkeit für manche Treiber je nach Aufgabe technisch prinzipiell nicht erreichbar, für andere zumindest aufwendig zu realisieren. Erst 386-Speichermanager wie EMM386, die unautorisierte Zugriffe auf das A20-Gate abfangen und softwaretechnisch entsprechend verarbeiten konnten, schafften hier betriebssystemseitig mehr Sicherheit in der Verwendung der HMA. Auch auf Rechnern, bei denen die A20-Leitung nicht maskierbar ist, war man vor solchen Problemen gefeit.
Ein weiterer Punkt war jedoch die Adressierung des Codes innerhalb der HMA selbst. Bei einer Relokation in die Upper Memory Area (UMA), wie sie für normale Treiber möglich war, wurde normalerweise die Segmentadresse an das Zielsegment angepasst, im Falle der HMA stand die Segmentadresse jedoch fest auf FFFE$_{hex}$ oder FFFF$_{hex}$, so dass, wenn mehrere Software-Komponenten gleichzeitig in die HMA geladen werden sollten, sich stattdessen die Offset-Adressen ändern mussten, da zum Zeitpunkt der Kompilierung noch nicht feststand, an welcher Stelle innerhalb des HMA-Segments gerade noch Platz für den hochzuladenden Code sein würde. Diese Intra-Segment-Offset-Relokation erforderte jedoch spezielle Ladetechniken, bei denen alle Offsetbezüge innerhalb des Codes beim Laden entsprechend angepasst wurden, und die Anwendung verschiedener Programmiertricks, die nur wenige Programmierer beherrschten.

## Begriffsverwirrung

In den deutschsprachigen MS-DOS-Versionen, die die HMA unterstützten, wurde diese als „oberer Speicherbereich“ bezeichnet. Als die Unterstützung für Upper Memory Blocks hinzukam, verwendete man dann für diese den Namen „hoher Speicherbereich“. Die Benennung war also im Deutschen gerade umgekehrt gehandhabt wie im Englischen, was zusammen mit der insgesamt schweren Verständlichkeit der MS-DOS-Speicherverwaltung zu viel Verwirrung bei den Anwendern führte. Erst unter Windows 95 wurden die deutschen Begriffe vertauscht, so dass sie nun den Englischen direkt entsprachen.