home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
assemblr
/
library
/
lib4a86
/
doc
/
memory.doc
< prev
next >
Wrap
Text File
|
1992-02-11
|
13KB
|
336 lines
─────────────────────────────────────────────────────────────────────────────
Dokumentation zur Datei: MEMORY.INC
─────────────────────────────────────────────────────────────────────────────
MEMORY.INC - Routinen zur Benutzung der Speicherverwaltung von DOS
(für den Assembler A86)
(c) Bernd Schemmer 1992
Letzter Update: 11.02.1992
■ Routinen:
-----------
CalcBytes - Rechnet Paragraphen in Bytes um
CalcParagraphs - Rechnet Bytes in Paragraphen um
GetBlockSize - Ermittelt die Größe und den Besitzer eines
Speicherblocks
SetBlockSize - Verändert die Größe eines Speicherblocks
GetMemoryBlock - Allociert einen Speicherblock
FreeMemoryBlock - Gibt einen Speicherblock wieder frei
GetMemoryStrategy - Ermittelt die akt. Speicherbelegungsstrategie
SetMemoryStrategy - Ändert die akt. Speicherbelegungsstrategie
SetBlockName - Markiert einen Speicherblock mit einen Namen
GetOwnerName - Ermittelt den Namen eines Speicherblockes
SearchMemoryBlock - Sucht einen bestimmten Speicherblock
TestMemoryBlock - Überprüft einen Speicherblock
ab DOS 5.0:
-----------
GetUMBLinkStatus - Ermittelt, ob die UMBs eingebunden sind
SetUMBLinkStatus - Einbinden oder rausnehmen der UMBs
Die Routinen benutzen das Register AX als Arbeitssregister.
Fast alle Routinen benutzen die undokumentierten MCBs.
■ Fehlernummern der Routinen
----------------------------
Alle Fehlernummern der Routinen haben das Format 81xx, wobei xx die
Nummer des eigentlichen Fehlers ist. Neben diesen werden auch die
DOS-Fehlernummern im Format 00xx zurückgeliefert (normalerweise nur
die Fehlernummern 01h, 07h, 08h und 09h).
Name Nummer Bedeutung
----------------------------------------------------------------------
00xxh ; DOS-Fehlernummern
; zusätzliche Fehlernummern der Routinen
; --------------------------------------
MemoryBlockError EQU 08101h ; falsche Blockadressse angegeben
InvalidBlockLength EQU 08102h ; falsche Blockgrösse angegeben
BlockIsFree EQU 08103h ; Block ist frei
BlockBelongstoDOS EQU 08104h ; Block gehört DOS
BlockIsNoMainBlock EQU 08105h ; Block ist kein Hauptblock
InvalidBlockName EQU 08106h ; falscher Name für den Block angegeben
BlockNotFound EQU 08107h ; Block nicht gefunden
----------------------------
CalcParagraphs
Funktion: Umrechnen von Bytes in Paragraphen
Eingabe: DX:AX = Wert in Byte
Ausgabe: BX = Wert in Paragraphen
Bes.: Der Wert wird auf die nächste Paragraphengrenze aufgerundet.
(Benutzt nicht den DIV-Befehl)
Da für das Ergebnis nur ein Register benutzt wird, ist der
maximal mögliche Wert in DX:AX gleich 0FFFF0h.
----------------------------
CalcBytes
Funktion: Umrechnen von Paragraphen in Bytes
Eingabe: BX = Wert in Paragraphen
Ausgabe: DX:AX = Wert in Byte
Bes.: Da für den Wert in Paragraphen nur ein Register benutzt
wird, kann das Ergebnis maximal 0FFFF0h betragen.
----------------------------
SearchMemoryBlock
Funktion: Sucht einen Speicherblock mit einem bestimmten Namen
Eingabe: DS:SI -> String mit dem Namen (max. 8 Zeichen)
Ausgabe: CF = 0 ->> Okay
ES = Segment des Blocks
CX = Nummer des Speicherblocks
CF = 1 ->> Fehler
AX = Fehlernummer
speziell:
AX = BlockNotFound
->> Block nicht vorhanden
CX = Anzahl Speicherblöcke
ES = Segment des letzten Blocks
Bes.: DOS 4+ wird vorrausgesetzt (falls ein Programm nicht selber
seinen Speicherblock mit einen Namen markiert, wie es z.B.
meine speicherresidenten Programme tun).
Das Directionflag wird gelöscht
Die Groß- und Kleinschreibung des Namens ist signifikant.
Benutzt die undokumentierte Funktion 52h des Interrupt 21h
und den undokumentierten DOS-Info-Block.
----------------------------
TestMemoryBlock
Funktion: Testet, ob das Register ES das Segment eines
Speicherblocks enthält
Eingabe: ES = Segment des Blocks
Ausgabe: CF = 0 ->> okay
CF = 1 ->> Fehler
AX = Fehlernummer
----------------------------
SetBlockName
Funktion: Markiert einen Speicherblock mit einem Namen
Eingabe: ES = Segment des Speicherblocks (Hauptblock)
DS:SI = String, es werden nur die ersten 8 Zeichen des
Strings berücksichtigt
(Pascal-Format also mit Längenbyte)
Ausgabe: CF = 0 ->> okay, Block markiert
BX = Länge des eingetragenen Namens
CF = 1 ->> Fehler
BX = undefiniert
AX = Fehlernummer
Bes.: Unter DOS 4+ ist diese Routine nicht mehr nötig, da
DOS selber die Speicherblöcke mit dem Namen markiert.
----------------------------
GetOwnerName
Funktion: Ermittelt den Namen des Besitzers eines Speicherblocks
Eingabe: ES = Segment des Speicherblocks
ES kann auf einen beliebigen Speicherblock zeigen,
es wird immer der Name aus dem zugehörigem Hauptblock
ermittelt.
DS:SI = Puffer für einen String mit bis zu 8 Zeichen
(Pascal-Format also mit Längenbyte)
Ausgabe: CF = 0 ->> okay, Puffer gefüllt
BX = Länge des Namens des Besitzers
AL = 0 ->> Block ist ein Hauptblock
AL = 1 ->> Block ist KEIN Hauptblock
CF = 1 ->> Fehler
AX = Fehlernummer
BX = undefiniert
Der String für den Namen ist gelöscht.
Bes.: DOS 4+ wird vorrausgesetzt (falls ein Programm nicht selber
seinen Speicherblock mit einem Namen markiert, wie es z.B.
meine speicherresidenten Programme tun).
----------------------------
GetUMBLinkStatus
Funktion: Ermittelt die akt. Behandlung der UMBs
Eingabe: -
Ausgabe: CF = 0 ->> okay
AL = 0 ->> UMBs nicht eingebunden
AX = 1 ->> UMBs eingebunden
CF = 1 ->> Fehler
AX = Fehlernummer
Bes.: Benutzt die undokumentierte (?) Funktion 58h des Interrupt 21h.
DOS 5+ wird vorrausgesetzt!
----------------------------
SetUMBLinkStatus
Funktion: Ändert die Behandlung des UMBs
Eingabe: AX = neue Strategie:
Bit 0 von AX = 0 ->> UMBs einbinden
Bit 0 von AX = 1 ->> UMBs nicht einbinden
Ausgabe: CF = 0 ->> okay
CF = 1 ->> Fehler
AX = Fehlernummer
Bes.: Benutzt die undokumentierte (?) Funktion 58h des Interrupt 21h.
DOS 5+ wird vorrausgesetzt!
Die Speicherbelegungsstrategie wird vom DOS beim Programmende
NICHT automatisch restauriert! Jedes Programm, daß diese
Strategie ändert sollte daher die alte Strategie vor dem
Programmende wieder einsetzen!
----------------------------
GetMemoryStrategy
Funktion: Ermittelt die akt. Speicherbelegungsstrategie
Eingabe: -
Ausgabe: CF = 0 ->> okay, AX = Speicherbelegungsstrategie
AL = 0 ->> First Fit
AL = 1 ->> Last Fit
AL = 2 ->> Best Fit
ab DOS 5+ zusätzlich falls die UMBs eingebunden sind:
Bit 6 gesetzt: UMB only
Bit 7 gesetzt: UMB first
vor DOS 5:
AL > 2 ->> Best Fit
CF = 1 ->> Fehler
AX = Fehlernummer
Bes.: Benutzt die undokumentierte (?) Funktion 58h des Interrupt 21h.
DOS 3+ wird vorrausgesetzt!
----------------------------
SetMemoryStrategy
Funktion: Ändert die Speicherbelegungsstrategie
Eingabe: AX = neue Strategie:
AX = 0 ->> First Fit (von unten nach oben, Default)
AX = 1 ->> Last Fit (von oben nach unten)
AX = 2 ->> Best Fit (optimalsten Block suchen)
ab DOS 5+ zusätzlich falls die UMBs eingebunden sind:
Bit 6 gesetzt: UMB only
Bit 7 gesetzt: UMB first
vor DOS 5:
AL > 2 ->> Best Fit
Ausgabe: CF = 0 ->> okay
CF = 1 ->> Fehler
AX = Fehlernummer
Bes.: Benutzt die undokumentierte (?) Funktion 58h des Interrupt 21h.
DOS 3+ wird vorrausgesetzt!
Die Speicherbelegungsstrategie wird vom DOS beim Programmende
NICHT automatisch restauriert! Jedes Programm, daß diese
Strategie ändert sollte daher die alte Strategie vor dem
Programmende wieder einsetzen!
----------------------------
GetMemoryBlock
Funktion: Belegt einen Speicherblock
Eingabe: BX = Größe des Blocks in Paragraphen (BX > 0)
Ausgabe: CF = 0 ->> okay
AX = Segment des Blocks
CF = 1 ->> Fehler
AX = Fehlernummer
speziell:
AX = 08h : Speicherblock der angegebenen Größe
nicht verfügbar
BX = max. Größe für einen neuen Block
Bes.: .COM-Programme belegen nach dem Start den größten freien
Speicherblock komplett. Sie müssen daher normalerweise vor
der Anforderung eines neuen Speicherblocks ihren eigenen
Speicherblock verkleinern!
Zur Ermittlung des größten freien Speicherblocks kann die
Routine mit BX = 0FFFFh aufgerufen werden. Sie sollte in
diesem Fall immer mit dem Fehler 8 enden (d.h. in BX
steht nach der Rückkehr die max. Größe eines neuen Blocks)
----------------------------
FreeMemoryBlock
Funktion: Freigabe eines Speicherblocks
Eingabe: ES = Segment des Speicherblocks
Ausgabe: CF = 0 ->> okay
CF = 1 ->> Fehler
AX = Fehlernummer
----------------------------
SetBlockSize
Funktion: Verändert die Größe eines Speicherblocks
Eingabe: ES = Segment des Speicherblocks
BX = neue Blockgrösse in Paragraphen (BX > 0)
Ausgabe: CF = 0 ->> okay
AX = neue Größe des Speicherblocks in
Paragraphen
CF = 1 ->> Fehler, Speicherblock wurde NICHT verändert!
AX = Fehlernummer
speziell:
AX = 08h : Speicherblock kann nicht auf die
angegebene Größe gesetzt werden
BX = max. Größe für den Block
----------------------------
GetBlockSize
Funktion: Ermittelt die Größe eines Speicherblocks
Eingabe: ES = Segment des Speicherblocks
Ausgabe: CF = 0 ->> okay
BX = Größe des Speicherblocks in Paragraphen
AX = Besitzer des Speicherblocks
AX = 0 ->> Block ist frei
AX = 8 ->> Block gehört DOS
sonst ->> AX = PSP des Besitzers
ZF = 1 ->> Speicherblock IST der letzte Block
ZF = 0 ->> Speicherblock ist NICHT der letzte Block
CF = 1 ->> Fehler, ES enthält NICHT das Segment eines
Speicherblocks
AX = Fehlernummer