Impressum
Inhalt Datentransport >

Adressierungsarten

Operanden von Assemblerbefehlen können unterschiedlich adressiert sein. Manche Befehle erlauben nur eine bestimmte Untermenge dieser Adressierungen und in einigen Fällen wird durch Wechsel der Adressierungsart auch ein anderer Speicher angesprochen. Doch bevor wird hierauf auf den folgenden Seiten näher eingehen, betrachten wir zuerst die einzelnen Adressierungsmöglichkeiten des 8051 Assemblers.

Immediate Adressierung

Konstanten werden in Assembler durch eine vorangestellte Raute (#) gekennzeichnet. Die Angabe #40 ist also der Wert 40. Die Konstanten können wie alle Werte in Assembler dezimal, hexadezimal oder binär angegeben werden. Bei hexadezimalen Zahlen wird der Zahl ein h und bei binären ein b hinten angehängt. So sind #40, #28h und #101000b dieselben Werte.
Konstanten sind immediate adressiert. Das englische Wort „immediate“ bedeutet umgehend. Bei einem konstanten Operanden folgt dem Befehlsbyte im ROM sofort der Wert des Operanden - der Wert muss also nicht in einem anderen Speicher „nachgeschlagen“ werden.

Direkte Adressierung

Bei der direkten Adressierung wird die Adresse einer Speicherzelle angegeben. Hier wird die Adresse angegeben ohne jegliches vorangestelltes Zeichen. So ist 40h die Speicherzelle, diese habe den Wert 10h. Mit mov A, 40h wird der Wert dieser Speicherzelle (also 10h) in den Akkumulator kopiert, während mov A, #40h den Wert 40h in den Akkumulator schreibt.
Direkt adressierbar ist das komplette SFR (80h bis FFh) und der untere Teil des internen RAMs (00h bis 7Fh).

Register Adressierung

Wird eins der Register R0 bis R7 als Parameter verwendet, so spricht man von Register Adressierung. Die Register liegen standardmäßig an der Adresse 0 bis 7 im RAM und können auch durch direkte Adressierung ausgelesen oder verändert werden.
Worin liegt also der Unterschied zwischen Register Adressierung und direkter Adressierug?
Der Speicherort der Register kann verändert werden. Mit den Bits RS1 und RS0 (Bit 4 und 3 im PSW) wird festgelegt, wo die Register im RAM liegen.
RS1RS0Adresse von R0-R7
0000h-07h
0108h-0Fh
1010h-17h
1118h-1Fh
Somit speichert mov R0, #3 den Wert 3 in Register 0. Dies kann an der Adresse 0h, 8h, 10h oder 18h sein.

Indirekte Adressierung

Bei der Register-Indirekten-Adressierung wird der Inhalt der Register R0 oder R1 als Adresse aufgefasst. Dies wird durch ein vorangestelltes @ gekennzeichnet. Wird mov A, @R0 angegeben, so wird der Inhalt von R0 zur Adresse und der Inhalt derselben wird in A kopiert.
Es wird hier also die Adresse indirekten angegeben, da man sie zuerst aus R0 auslesen muss, um den gewünschten Speicherort zu ermitteln.
Beispiel 1:
mov 20h, #3; Wert 3 in die Speicherzelle 20h schreiben
mov R0, #20h; Den Wert 20h in R0 schreiben
mov A, @R0; In R0 steht 20h, deshalb wird der Wert aus 20h in A kopiert - also 3
Register indirekt lässt sich der komplette interne RAM adressieren und der Erweiterungsspeicher (von 00h bis FFh) adressieren. Der große Vorteil der indirekten Adressierung ist, dass man mit dem gleichen Code einen ganzen Speicherbereich beschreiben kann.
Beispiel 2:
mov R0, #20h; Den Wert 20h in R0 schreiben
schleife:mov @R0, #0FFh; den Wert 0FFh an @R0 schreiben
inc R0 ; R0 um 1 erhöhen
cjne R0, #40h, schleife; So lange in R0 nicht 40h steht: weiter bei schleife
Dieses Code-Fragment beschreibt den internen RAM von 20h bis 3Fh mit dem Wert 0FFh. Hierzu wird zuerst 20h in R0 geschrieben und dann mittels indirekter Adressierung die Speicherzelle 20h beschrieben.
Danach wird R0 um 1 erhöht, somit wird beim nächsten Durchlauf der Schleife mit mov @R0, #0FFh in die Speicherzelle 21h geschrieben.
Beim darauf folgenden Schleifendurchlauf in 22h,
Beim darauf folgenden Schleifendurchlauf in 23h,
...

Indirekte Adressierung über den DPTR

Wird auf den Erweiterungsspeicher zugegriffen, so reichen R0/R1 nicht aus, da der Erweiterungsspeicher 64kB groß sein kann. Es wird ein 16-Bit Register benötigt. Bei dem Befehl movx kann deshalb auch über den Datapointer (DPTR) indirekt adressiert werden (z.B. movx A, @DPTR). Näheres hierzu finden Sie bei den Erklärungen zum Befehlssatz.

Indirekte indizierte Adressierung

Hier setzt sich die Adresse aus der Summe zweier Werte zusammen. Bei @A+DPTR ergibt die Summe aus DPTR und A die Adresse des Operanden. Bei @A+PC wird der Programm-Counter und der Akkumulator addiert. Dieser Wert wird als Adresse verwendet.
Beispiel: Im DPTR steht der Wert 202h und im Akku steht 04h so liest movc A, @A+DPTR den Wert an der Stelle 202h+04h=206h im ROM aus und schreibt in den Akkumulator.

Bitadressierung

Der 8051 bietet die Möglichkeit, einzelne Bits zu adressieren. Durch diese Eigenschaft sind viele Probleme einfacher und komfortabler zu lösen als dies z.B. beim Z80 der Fall war (hier mussten einzelne Bits anhand von Masken mit and, or, xor, shift herausgeschnitzt werden).
Bitadressen kann man durch Byte-Adresse.Bit-Nummer (z.B. 80h.3) angeben. Da dies allerdings in eine 8-Bit Zahl umgewandelt (80h.3=83h) wird, sind nicht alle Bytes im RAM bzw. SFR bit-adressierbar. Einzelne Bits lassen sich im RAM von den Bytes 20h bis 2Fh (Bitadressen 00h bis 7Fh) und im SFR alle Speicherzellen, welche hexadezimal auf 0 oder 8 enden (80h, 88h, 90h, 98h, A0h, ...) mit den Bitadressen 80h bis FFh.