Wie jede normale Programmiersprache verfügt auch Assembler über die
Möglichkeit, Variablen unterschiedlichen Typs zu deklarieren. Das geht sogar
so weit, daß man sich selbst Datentypen bauen kann (wie z. B.
struct
in C oder der Record
in Pascal), um dann
Variablen dieses Typs anzulegen.
Dieses Kapitel zeigt Ihnen, wie Sie mit Assembler Variablen verwenden.
TASM verfügt über die folgenden eingebauten Datentypen:
Datentypen
TASM-Bezeichnung |
ausgesprochen |
Größe in Bits |
Wertebereich mit/ohne Vorzeichen |
DB |
Byte/Char |
8 |
-128 bis +127 / 0 bis 255 |
DW |
Word |
16 |
-32768 bis +32767 / 0 bis 65535 |
DD |
DoubleWord |
32 |
-2.147.483.648 bis +2.147.483.647 / 0 bis 4.294.967.295 |
DQ |
QuadWord |
64 |
-2^63 bis +2^63-1 / 0 bis 2^64-1 |
DP / DF |
FarPointer |
48 |
-2^47 bis +2^47-1 / 0 bis 2^48-1 |
TByte |
TenByte |
80 |
-2^79 bis +2^79-1 / 0 bis 2^80-1 |
packed BCD |
gepackte BCD |
80 |
0 bis 99.999.999.999.999.999.999 |
Üblicherweise wird ein FarPointer für das verwendet, wovon er seinen Namen hat -
als Adresszeiger. Aus diesem Grunde gilt in aller Regel eine vorzeichenlose
Interpretation als Adresse.
Die Bezeichnung TenByte ist von mir erfunden - ein TByte ist normalerweise immer
nur ein TByte.
Die gepackte BCD ist lediglich eine andere Interpretation eines TByte. Die
beiden Datentypen spielen beim mathematischen Koprozessor eine Rolle.
Wie immer spielt Groß/Kleinschreibung keine Rolle.
Wie schon in Kapitel über die Register besprochen, belegen Code, Daten und
Stack eigene Segmente. Demzufolge müssen wir unsere Variablen (Daten) in ein
Datensegment schreiben. Wie wird jetzt ein Datensegment angelegt? Ganz
einfach: mit der Anweisung DATASEG (vergleichbar mit VAR in PASCAL). Alles,
was hinter dieser Anweisung steht, wird als Datenvereinbarung betrachtet,
solange, bis ein anderes Segment angelegt wird (z. B. für Code).
Die allgemeine Form einer Variablendeklaration sieht in Assembler so aus:
[VarName] Datentyp {[count dup] (? | Vorbelegung)}
|
Dröseln wir diese allgemeine Form auseinander:
Wie Sie sehen, ist der Variablenname optional, was bei mehrzeiligen
Deklarationen ganz nützlich ist. Zudem können Sie auf diese Weise auch Daten
ins Codesegment schreiben, beispielsweise einen Befehl, den ihr Assemblierer
noch nicht kennt.
Der Datentyp ist eine der kurzen Buchstabenfolgen aus obiger Tabelle, also
DB, DW usw.
In Assembler haben Sie die Möglichkeit, Variablen sofort bei ihrer
Deklaration zu initialisieren (Zahlenwerte können in allen möglichen
Zahlensystemen angegeben werden). Dies wird durch den Teil geregelt, der in
geschweiften Klammern steht.
Möchten Sie die Variable unitialisiert belassen, dann muß nach dem Datentyp
ein Fragezeichen stehen, also zum Beispiel.
Wird das Programm später gestartet, erhält MyVar den Wert, der gerade an der
Stelle im Speicher steht, an die MyVar geladen wird.
Um MyVar gleich mit dem ASCII-Wert des Zeichens 'A' (65) zu initialisieren, ist
folgender Code nötig:
oder
Diese Doppelinitialisierung mit Zeichen funktioniert allerdings nur beim
Datentyp DB. Zum zweiten wird hier gezeigt, daß der Assemblierer keinen
Unterschied zwischen Zahlenwerten im Byte-Bereich und deren Repräsentation
als Zeichen macht.
Man kann bei einer Deklaration auch gleich mehrere Initialwerte angeben,
beispielsweise:
MyVar db 65,115,115,101,109,98,108,101,114
|
oder
oder
MyVar db 'A','s','s','e','m','b','l',101,114
|
oder
MyVar dw 45665,12315,6215,7801,43109,48
|
Um noch eine mehrzeilige Deklaration zu zeigen:
MyVar dw 45665
dw 12315
dw 6215
dw 7801
dw 43109
dw 48
|
Über den Variablennamen wird dann jeweils das erste Element der Wertefolge
angesprochen. Diese Konstrukte sind also mit einem Array vergleichbar.
Wie Sie sehen können, ist auch eine Mischinitialisierung möglich (Zeichen und
Zahlen).
Um nun eine Reihe von Daten mit dem gleichen Wert zu initialisieren, gibt es
folgendes beispielhaftes Konstrukt:
oder
Es wird also ein 12 bzw 24 Byte großer Speicherbereich angelegt, der über
den Namen MyVar angesprochen werden kann und entweder komplett
uninitialisiert ist oder komplett aus dem Buchstaben 'm' besteht.
Um innerhalb des Programmcodes auf den Variableninhalt zugreifen zu können, ist
es nötig, den Variablennamen in eckige Klammern einzuschließen. Dies ist eine
Eigenheit des IDEAL-Mode, die in meinen Augen die Lesbarkeit des Quelltextes
erhöht. Beispielsweise wird so die Verwechselung mit Konstanten vermieden.
Beispiel:
Ist MyVar vom Typ DB, dann wird ihr der Inhalt 'E' zugewiesen (ist MyVar
eine Zeichenkette, dann wird der erste Buchstabe verändert).
Ist MyVar nicht vom Typ DB (sondern vielleicht DW), dann gibt es eine
Fehlermeldung. In diesem Fall müßten Sie den neuen Inhalt 'casten', also eine
Datentypumwandlung vornehmen, doch dazu später mehr.
Variablen im Datensegment sind für das gesamte Programm verfügbar und können an
jeder Stelle verwendet werden.
Um eine Variable für andere Programme verfügbar zu machen, ist eine zusätzliche
Angabe notwendig
DATASEG
msg db 20 dup(?)
PUBLIC msg
|
Damit ein anderes Programm auf diese Variable zugreifen kann, ist folgendes
notwendig:
Zusätzlich zu PUBLIC und EXTRN gibt es noch die Direktive GLOBAL:
DATASEG
GLOBAL msg:byte anz:word
anz dw 800
|
GLOBAL arbeitet so, dass alles, was im gleichen Modul definiert ist, als PUBLIC
gesetzt wird, alles, was nicht im gleichen Modul definiert ist, wird als EXTRN
behandelt