Speicher oberhalb der 1 MB Grenze wird als Extended Memory bezeichnet. Dieser Speicher kann jedoch von einem Prozessor im Realmode aus dem oben bereits angegebenen Grund, Begrenzung des max. Speicherraums auf 1MB, nicht genutzt werden.
Intel Prozessoren (ab dem 80286) kennen jedoch einen weiteren Betriebsmodus, in dem der maximale Speicherbereich auf mindestens 16 MB ausgedehnt werden kann, den Proteced-Mode. Da DOS zu diesem Modus nicht kompatibel ist und sich andere, neue Betriebssysteme nur schwer durchsetzen konnten, blieb dieser Modus sowie das Extended Memory aufgrund fehlender Softwareschnittstellen für die meisten Programme ungenutzt.
(Es existieren Möglichkeiten, um auch von DOS aus auf das Extended Memory zuzugreifen, z.B. Interrupt 15h Funktionen 87h-89h. Leider machen auch viele Software Utilities von diesen Möglichkeiten Gebrauch, um z.B. Extended Memory für eine RAM-Disk bereitzustellen. Das Ergebnis dieser unterschiedlichen und relativ unkontrollierten Nutzung des Extended Memory führte zwangsläufig zu Kompatibilitätsproblemen zwischen einzelnen Programmen.)
Aus diesen Gründen wurde 1988 von den Firmen Lotus, Intel und Microsoft, in Zusammenarbeit mit AST Research ein weiterer Standard geschaffen, der es Speicherverwaltungssoftware, Utilities und Anwendungsprogrammen gleichermaßen erlauben sollte, ohne Kompatibilitätsprobleme XMS-Speicher zu nutzen.
Der XMS-Standard unterstützt dabei die folgenden Speicherobjekte:
SpeicherobjekteUMB (Upper Memory Blocks) sind freie, ungenutzte Speicherblöcke, die zwischen 640 und 1024 KB liegen.
Sie werden beispielsweise unter DOS benutzt, um Gerätetreiber und sogar Teile des DOS selbst aufzunehmen, um so mehr konventionellen Speicher für Programme bereitzustellen.
Neben dem wohl bekanntesten XMS-Treiber HIMEM.SYS, der von Microsoft mit den verschiedenen DOS-Versionen und auch mit Windows ausgeliefert wird, existieren XMS-Treiber auch in Speicherverwaltungen für 80386- oder 80486-Rechner. Beispiele dafür sind QEMM-386 von Quaterdeck oder 386-To-The-Max von Qualitas.
Ist ein XMS-Treiber im System verfügbar, so stehen die in Tabelle 1.1 dargestellten Funktionen zur Verfügung.
Fkt. | Aufgabe |
---|---|
00h | Versionsnummer ermitteln |
01h | High-Memory-Area (HMA) in Besitz bringen |
02h | HMA freigeben |
03h | Globale Aktivierung der Adressleitung A20 |
04h | Globale Schließung der Adressleitung A20 |
05h | Lokale Freigabe der Adressleitung A20 |
06h | Lokales Sperren der Adressleitung A20 |
07h | Status der Adressleitung A20 abfragen |
08h | Größe des freien Extended Memory abfragen |
09h | Allokieren eines Extended-Memory-Blocks (EMB) |
0Ah | Freigabe eines allokierten Extended-Memory-Blocks (EMB) |
0Bh | Kopiere Speicher |
0Ch | Sperrt einen Extended-Memory-Block (EMB) gegen seine Verschiebung |
0Dh | Gesperrten EMB entsichern |
0Eh | Informationen über einen EMB einholen |
0Fh | EMB-Größe verändern |
10h | Upper Memory Block (UMB) allokieren |
11h | Allokierten UMB wieder freigeben |
Tabelle 1.1: XMS-Funktionen
Im Gegensatz zum EMM werden die Funktionen eines XMS-Treibers nicht über einen Interrupt, sondern über einen FAR-Call aufgerufen. Die FAR-Call Adresse liefert der Interrupt 2Fh, der auch von vielen residenten Programmen, wie z.B. SHARE, APPEND oder PRINT benutzt wird.
Bevor die Einsprungsadresse ermittelt werden kann, muß festgestellt werden, ob ein XMS-Treiber installiert wurde. Dazu wird der Interrupt 2Fh mit dem Funktionscode 4300h im Register AX aufgerufen. Befindet sich ein XMS-Treiber im System, so kehrt die Interruptroutine mit dem Wert 80h im Register AL zurück.
Konnte ein XMS-Treiber identifiziert werden, kann mit dem Wert 4310h im Register AX und dem Aufruf des Interrupt 2Fh die Adresse des XMS-Treibers ermittelt werden. Diese befindet sich nach Ausführung des Interrupts in den Registern ES und BX.
FunktionenAlle obengenannten XMS-Funktionen können jetzt über die ermittelte Adresse angesprochen werden. Dazu wird die Funktionsnummer grundsätzlich im Register AH und andere funktionsabhängige Parameter in den übrigen Prozessor-Registern übergeben.
Viele XMS-Funktionen liefern in AX den Statuscode 0001h zurück, wenn sie erfolgreich ausgeführt werden konnten. Trat bei der Ausführung ein Fehler auf, so enthält AX den Wert 0000h. In diesem Fall enthält das Register BL einen Fehlercode. Mögliche Fehlercodes befinden sich unter XMS-Fehlercodes.
Von den in Tabelle 1.1 (XMS-Funktionen) genannten Funktionen werden die für den Zugriff auf den Extended Memory benutzten Funktionen im folgenden kurz vorgestellt.
Funktion 00h: XMS-Versionsnummer ermitteln Aufruf mit AH= 00h Rückgabe AX= XMS-Versionsnummer (ungepackter BCD-Code: AH= Hauptversionsnummer, AL= Unterversionsnummer) BX= Interne Revisionsnummer (ungepackter BCD-Code: siehe oben) DX= Status der HMA (0: HMA ist nicht verfügbar, oder 1: HMA ist verfügbar) Funktion 08h: Freies XMS ermitteln Aufruf mit AH= 08h Rückgabe AX= Länge des größten freien Blockes in KByte DX= Gesamtgröße des freien XMS in KByte Funktion 09h: Allokiere einen Extended Memory Block Aufruf mit AH= 09h DX= Größe des angeforderten Bereichs in KByte Rückgabe AX= 0001 - Funktion fehlerfrei ausgeführt 0000 - Fehler aufgetreten (Fehlercode in BL) DX= Handle zum Zugriff auf den EMB Funktion 0Ah: Freigabe eines allokierten EMB Aufruf mit AH= 0Ah DX= Handle Rückgabe AX= 0001 - Funktion fehlerfrei ausgeführt 0000 - Fehler aufgetreten (Fehlercode in BL) Funktion 0Bh: Kopiere Speicher Diese Funktion dient dazu, Speicherinhalte zwischen dem konventionellen RAM und dem Extended Memory zu kopieren. Sie kann auch genutzt werden, um Speicherblöcke innerhalb des konventionellen oder innerhalb des Extended-Memory zu kopieren. Aufruf mit AH= 0Bh DS:SI=Zeiger auf die nachfolgende Struktur Rückgabe AX= 0001 - Funktion fehlerfrei ausgeführt 0000 - Fehler aufgetreten (Fehlercode in BL) Struktur: Adr. Inhalt Typ +00h Länge des zu kopierenden Bereiches 1 DWORD (muß geradzahlig sein) +04h Handle des Quell-Blocks 1 WORD +06h Offset innerhalb des Quell-Blocks (ab dem 1 DWORD kopiert wird) +0Ah Handle des Zielblocks 1 WORD +0Ch Offset innerhalb des Zielblocks (zu dem 1 DWORD kopiert wird) Länge: 16 Byte
Um aus oder in das konventionelle RAM (< 1 MB) zu kopieren, muß das entsprechende Handle (Quell- oder Zielhandle) auf 0 gesetzt werden. Das folgende DWORD muß dann die entsprechende Realmodeadresse in der Form Segment:Offset (ERST Offset-, DANN Segmentadresse) enthalten.
1. Im folgenden soll eine Assembler-Routine vorgestellt werden, die feststellt, ob überhaupt ein XMS-Treiber installiert wurde. Falls ein Treiber identifiziert werden konnte, ermittelt sie die Einsprungsadresse für den Aufruf der XMS-Funktionen. ; XMS-Treiber über Interrupt 2Fh identifizieren mov ax,4300h int 2fh ; al = 80h Treiber installiert ; al <> 80h Treiber nicht vorhanden cmp al,80h jne check_quit_false ; Treiber vorhanden, Einsprungsadresse ermitteln mov ax,4310h int 2fh ; es:bx = Einsprungsadresse, unter XMS_ADR im ; Datensegment speichern mov ax,@data mov ds,ax mov w [XMS_ADR+0],bx mov w [XMS_ADR+2],es ; Funktion mit Erfolgsmeldung verlassen mov ax,TRUE jmp check_quit check_quit_false: mov ax,FALSE check_quit: ret |
2. Die folgende Assemblerroutine demonstriert den Aufruf des XMS-Treibers über einen FAR-CALL. Sie ermittelt über die Funktion 08h die Gesamtgröße des freien Extended Memory in KByte. ; Funktion 08h: Freies XMS ermitteln, aufrufen mov ah,08h call [dword ptr XMS_ADR] ; Hier befindet sich in ; ax - Länge des größten freien EMB in KByte ; bx - Gesamtgröße des verfügbaren Extended Memory in KByte |
Die hier dargestellten Assemblerroutinen befinden sich mit weiteren, für den Zugriff auf das Extended Memory notwendigen Routinen, in der Datei xms.asm. Zusammen mit dem C-Beispielprogramm xmstst.c sollen sie als Beispiel für die Nutzung des Extended Memory dienen.