Dockers DEV Site


Updates · Faq · Home 

1.3.3 Nutzung von EMS

Mit den obengenannten FAR- bzw. HUGE- Pointern kann die 64 KB Segmentschranke überwunden werden. Ein Problem, den Speicherbedarf eines Programmes zu decken, existiert jedoch noch immer: Die Begrenzung des Speicherbereiches auf 1 MB! Wie weiter oben bereits erwähnt wurde, ist die physische Adresse 20 Bit breit, d.h. maximal kann 1 MB adressiert werden.

Expanded Memory Specification (EMS)

Der adressierbare Speicherbereich von 1 Megabyte wird durch das Video-RAM, durch Hardwareerweiterungen und durch das BIOS noch weiter, auf 640 KB, reduziert. Da sich diese 640 KB bald als Grenze für anspruchsvollere Programme erwies, fanden sich die Firmen Lotus, Intel und Microsoft 1985 zusammen, um den nach ihnen benannten LIM-Standard für Speichererweiterungen zu schaffen.

Dabei handelt es sich in erster Linie um ein Verfahren, den Hauptspeicher eines PCs mit Hilfe einer Erweiterungskarte um bis zu 8 MB zu erhöhen und den so zur Verfügung gestellten Speicher "seitenweise" in den adressierbaren 1 MB Adressraum einzublenden. Von diesen 8 MB können dabei jeweils 64 KB in ein Speicherfenster, das als "Page-Frame" bezeichnet wird, abgebildet werden. Dieses "Page-Frame" muß im adressierbaren Speicherbereich von 1 MB liegen. Meistens wird dabei das Segment ab der Segmentadresse E000h verwendet.

Weiterhin findet eine feinere Unterteilung des 64 KB Segmentes in 4 Blöcke zu jeweils 16 KB statt. Dabei kann der physische Inhalt dieser Blöcke überall im Expanded Memory (also auf der Erweiterungskarte) liegen. Expanded Memory darf dabei nicht mit Extended Memory verwechselt werden. Abb. 1.3 stellt die Einblendung von logischen Speicherseiten dar.

Einblenden logischer Speicherseiten
Abb. 1.3: Einblenden von logischen Speicherseiten in den 1MB Adressraum

Neben der Hardware in Form einer Eweiterungskarte existiert eine weitere Komponente, die für den Speicherzugriff notwendig ist, die Softwareschnittstelle. Dabei handelt es sich um einen Gerätetreiber (den sogenannten "Expanded Memory Manager", kurz EMM), der einem Anwendungsprogramm Funktionen für den Zugriff auf das Expanded Memory zur Verfügung stellt und dadurch die direkte Programmierung der Erweiterungskarte übernimmt.

Anmerkung: Neben der ursprünglich geplanten Nutzung einer Erweiterungskarte zur Bereitstellung von Expanded Memory, existiert ab der Version 4.0 des LIM / EMS Standards die Möglichkeit, Expanded Memory durch Extended Memory (Speicher über dem 1MB-Adressraum) zu simulieren. Diese Möglichkeit soll an dieser Stelle jedoch noch nicht betrachtet werden, da diese Memory Manager auf dem Paging Mechanismus aufbauen. Siehe auch Kapitel 3.1 Paging. Obwohl die Quelle des Speichers in diesem Fall eine andere ist, sind die bereitgestellten Funktionen die gleichen.

Bereitgestellte Funktionen

Die Funktionen eines EMM werden über den Interrupt 67h aufgerufen, wobei das Register AH eine gültige Funktionsnummer enthalten muß. Tritt bei der aufgerufenen Funktion ein Fehler auf, so liefert der EMM einen Fehlercode in AH, sonst ist AH nach dem Aufruf zurückgesetzt (AH = 0).

Mögliche Fehlercodes finden Sie unter EMM-Fehlercodes.

Im folgenden soll anhand von zwei Beispiel-Routinen die Benutzung der bereitgestellten Funktionen demonstriert werden. Dabei dient die erste Routine dazu, festzustellen ob ein EMM installiert wurde und eine zweite Routine ermittelt die aktuelle Versionsnummer.

Eine Aufstellung aller, durch die Version 3.0 des EMS-Standards zur Verfügung gestellter Funktionen, finden Sie unter EMM-Funktionen.

1. Feststellen, ob ein Expanded Memory Manager (kurz: EMM) installiert wurde:

Der EMM gehört zur Klasse der Gerätetreiber und besitzt daher einen Treiberkopf, in dem der Name des Treibers festgehalten wird. Nach dem LIM/EMS Standard muß sich an der Offsetadresse 10d des Treibers die Kennung 'EMMXXXX0' befinden. Die Adresse dieser Zeichenfolge kann über die Segmentadresse der zum Interrupt 67h gehörenden Routine und der Offsetadresse 0Ah (10d) ermittelt werden. Handelt es sich bei der Zeichenfolge um den obengenannten String: 'EMMXXXX0', so steht ein Expanded Memory Manager zur Verfügung.

Vergleichen Sie auch mit folgender Assembler-Routine:

; Feststellen ob ein EMM installiert wurde
ems_check   proc
            push ds si es di

    ; Segmentadresse der Interruptroutine (Int 67h) ermitteln
            mov ah,35h
            mov al,67h
            int 21h

    ; es= Segmentadresse
    ; bx= Offsetadresse der Routine (wird nicht benötigt)

    ; testen ob es:000Ah die Kennung 'EMMXXXX0' enthält
            push es
            pop ds
            mov si,0Ah

            mov di,seg EMM_STRING
            mov es,di
            mov di,offset EMM_STRING	; es:di -> auf Erkennungsstring 'EMMXXXX0'

            mov cx,8
            repe cmpsb
            jcxz gefunden

    nicht_gefunden:
            mov ax,0
            jmp quit

    gefunden:
            mov ax,1

    quit:
            pop di es si ds
            ret
            endp

Konnte die obengenannte Zeichenkette gefunden werden, liefert die Funktion in AX den Wert 1 (TRUE). Im Fehlerfall übergibt sie der aufrufenden Routine den Wert 0 in AX (FALSE).

2. Versionsnummer ermitteln:

Über die Funktion 46h stellt der EMM seine Versionsnummer im Register AL zur Verfügung (BCD-Format). Dabei handelt es sich bei den oberen 4 Bit in AL um die Hauptversionsnummer. Die Nummer der Unterversion befindet sich in den unteren 4 Bit.

Die folgende Assemblerroutine erwartet als Parameter einen FAR-Zeiger auf einen WORD Speicherplatz, in dem die Versionsnummer in ungepackter BCD-Code Darstellung festgehalten wird. Wenn kein Fehler in der Kommunikation mit dem EMM-Treiber auftritt, liefert die Funktion TRUE (AX=1), ansonsten FALSE (AX=0).

ems_version proc ver:dword
            push es ds di

    ; es:di = Zeiger auf Version
            les di,ver

    ; Versionsnummer ermitteln
            mov ah,46h
            int 67h

    ; EMM-Fehler aufgetreten (ah <> 0) ?
            cmp ah,0
            je version_ok

    ; Hier kann eine Fehlerbehandlung durchgeführt werden

    ; FALSE zurückliefern, Funktion fehlgeschlagen
            mov ax,FALSE
            jmp version_quit

    version_ok:

    ; gepackten BCD-Code(al) in ungepackten BCD-Code in ax umwandeln und ...
            and ax,0FFh
            shl ax,4
            shr al,4

    ; unter <ver> speichern
            stosb
            mov al,ah
            stosb

    ; Funktion erfolgreich, TRUE liefern
            mov ax,TRUE

    version_quit:
            pop di ds es
            ret
            endp

Auf ähnliche Weise läßt sich auch die Adresse des Page-Frames ermitteln. Nach Aufruf der Funktion 41h befindet sich in BX die Segmentadresse des Page-Frames.

3. Mit dem EMS- Speicher arbeiten:

Belegen / Reservieren von Speicher:

Funktion 43h ist für die Reservierung von EMS-Speicher zuständig.

Dazu wird der Funktion in BX die Anzahl der zu belegenden Seiten übergeben (eine Seite umfaßt dabei einen Speicherbereich von 16 KB). Falls bei der Reservierung dieser Speicherseiten kein Fehler aufgetreten ist, liefert die Funktion im Register DX ein Handle auf den reservierten Speicher.

Alle weiteren Funktionen (Einblenden von Speicherseiten, Speicher freigeben, etc.) benötigen dieses Handle, um auf den EMS-Speicher zugreifen zu können. Das Handle muß vom entsprechenden Anwenderprogramm selbst verwaltet werden!

Speicherseiten in Page-Frame einblenden:

Über die Funktion 44h stellt der EMM eine Möglichkeit bereit, Speicherseiten (jeweils 16 KB) aus dem EMS in den 1MB Speicherbereich einzublenden. Dazu muß der Funktion im Register DX ein gültiges EMS-Handle, im Register BX die Nummer der logischen ("Quell-") Page im EMS und im Register AL die Nummer der physischen Seite innerhalb des durch die Page Frame Adresse festgelegten Segmentes (0 bis 3) übergeben werden (siehe auch Abb 1.4).

Einblenden logischer Seiten (Mapping)
Abb. 1.4: Einblenden logischer Seiten in den 1MB Adressraum (Mapping)

Speicher freigeben

Falls der EMS-Speicher nicht mehr benötigt wird, so sollte er über die Funktion 45h freigegeben werden. Wird der Speicher nicht freigegeben, so bleibt er für andere Anwendungen bis zu einem Neustart des Rechners als belegt gekennzeichnet und ist somit nicht mehr verfügbar.

Die beiden beschriebenen Routinen befinden sich zusammen mit einigen anderen, für den Zugriff auf das Expanded Memory notwendigen Routinen, in der Datei ems.asm. Zusammen mit den Routinen aus den C-Testprogrammen emstst1.c und emstst2.c sollen sie das Prinzip bei der Nutzung des EMS-Speichers verdeutlichen.

Index
weiter >>
<< zurück ||

Last change 27/11/2022 by Docker Rocker.
This page uses no cookies, no tracking - just HTML.
Author: "Docker Rocker" ~ 2022 · [Public Git]