8051-Mikrocontroller

 

Home

Grundlagen8051Programmierung

On-ChipSpeicherSFRsAssemblerBefehlsartenBefehlslisteUnterprogsInterrupts

Banner Text Befehlsaufbau und Adressierungsarten

Befehlsaufbau PDF

Einzelne Programmanweisungen oder Operationen (=Maschinenbefehle) werden im Mikrocomputer als Binärwerte im Programmspeicher abgelegt. Man unterscheidet zwischen Operationen zum Datentransport, Arithmetikoperationen, logischen Operationen und Programmsteueroperationen. Je nach Art und Verwendung benötigt ein vollständiger Maschinenbefehl 1, 2 oder 3 Byte Speicherplatz. Das erste Byte enthält dabei immer den Operationscode (kurz: Opcode). Im Befehlsumfang eines 8-Bit µC gibt es maximal 256 Opcodes. Jeder Befehlszyklus beginnt immer mit dem Lesen und dekodieren des Opcodes, anhand dessen das Steuerwerk die weiteren Befehlsschritte steuert. Bei 2- oder 3-Byte-Befehlen veranlasst das Steuerwerk, dass weitere Bytes aus dem Programmspeicher gelesen werden. Diese werden als Operanden bezeichnet und enthalten bei einem Transportbefehl zum Beispiel Ziel- und Quelladresse für die zu transferierenden Daten.

Beispiel: Ein 8-Bit Eingangsbyte an Port 1 (Adresse 90h) des Controllers soll in die Speicherstelle mit der Adresse 6Eh im internen RAM geschrieben werden. Der Assembler-Befehl hierzu lautet:

  • mov 6Eh,90h               ; 6Eh = Zieladresse, 90h = Quelladresse

Übersetzt in den binären Maschinencode lautet dieser Befehl:

Hier steht zunächst der Quell- und anschließend der Zieloperand. In der mnemonischen Darstellung gilt die umgekehrte Reihenfolge.
Zur Anzeige werden die binären Maschinencodes in einen Hexcode umgewandelt. Für das Beispiel ergibt sich folgender Hexcode:     85 90 6E

Aus dem Programmspeicher wird zunächst der Opcode und anschließend Quell- und Zieladresse der Daten gelesen. Das Speichermapping zeigt die Anordnung der drei Befehlsbytes im Programmspeicher. Der Programmzähler (PC) zeigt nach der Befehlsausführung auf den Opcode des nachfolgenden Befehls.


 


 

Adressierungsarten PDF

Zum Zugriff auf Speicherstellen, Register und On-Chip-Peripherie kennt der 8051-Controller fünf verschiedene Adressierungsarten. Sie unterscheiden sich in der Anzahl benötigter Befehls-Bytes, der Befehlsausführungszeit und den möglichen Zugriffszielen:

1. Direkte Adressierung

Der Operand besteht aus einer Speicheradresse im internen RAM. Diese Adresse wird als Hex-Code oder symbolisch angegeben (siehe oben).

Beispiel:  mov  48h,0A0h                      ; Inhalt von Port2 ins int. RAM
               mov  48h,P2                          ; dito. Mit symbolischer Adresse

Für die direkte Adressierung wird je Operand ein Byte im Programmspeicher benötigt.

2. Register-Adressierung

Bei der Register-Adressierung besteht der Operand aus einem der besonderen Register: R0 ... R7, A, B, DPTR (16 Bit), CY (1 Bit).

Beispiel:  mov  A,R4                               ; Kopiert den Inhalt des Registers R0 in den                                                                ; Akku

Da diese speziellen Register im 8051 sehr häufig benötigt werden, sind Sie direkt in den Opcode integriert. Für den obigen Befehl gibt es daher insgesamt 8 Opcodes, je nachdem welches der Register R0 ... R7 als Operand verwendet wird: 

Befehl

Opcode

mov A,R0

E8h

mov A,R1

E9h

mov A,R2

EAh

mov A,R3

EBh

mov A,R4

ECh

mov A,R5

EDh

mov A,R6

EEh

mov A,R7

EFh

Da sich alle Register des 8051 organisatorisch im SFR oder internen RAM wiederfinden, kann jedes dieser Register natürlich auch mit seiner Speicheradresse (direkt) angesprochen werden. Obiger Befehl lässt sich also auch so formulieren:

               mov  0E0h,04h                       ; E0 = Akkumulator,  04 = Register R4

Der Unterschied der beiden Adressierungsarten zeigt sich, wenn man den Speicherbedarf und die Ausführungszeit der Befehle vergleicht. Das erste Beispiel belegt nur 1 Byte Programmspeicher und ist in einem Maschinenzyklus bearbeitet. Mit direkter Adressierung werden drei Bytes und zwei Maschinenzyklen benötigt.

3. Unmittelbare (Immediate) Adressierung

Bei dieser Adressierungsart besteht der Operand aus einer Konstanten im Programmspeicher. Da der Programmspeicher nur bei der Programmierung, nicht aber während der Laufzeit geändert werden kann, ist eine solche Konstante natürlich nur als Quelloperand zulässig. Der Assembler erlaubt verschiedene Darstellungsarten für Konstanten. Diese werden aber immer durch das #-Symbol (Raute, Doppelkreuz oder Gartenzaun) gekennzeichnet. Die Zahl 65 kann somit in folgenden äquivalenten Formen dargestellt werden:

Konstante

Codierung

Grösse

#65

Dezimal

Byte

#65d

Dezimal

Byte

#41h

Hex

Byte

#01000001b

Binär

Byte

#101o

Oktal

Byte

#'A'

ASCII

Byte

Zur Adressierung können weiterhin Adresskonstanten definiert werden:

Konstante

Codierung

Grösse

#1F00h

Adresskonstante

Word

 

Beispiel:  mov  A,#0                           ; Löscht den Akku!
                mov  DPTR,#1F00h            ; setzt den Datenzeiger auf die Adresse 1F00h                                                             ; im Programmspeicher
                mov  P1,#01110111b          ; Die Bits von Port 1 werden entsprechend                                                             ; der Bitmaske belegt

4. Registerindirekte Adressierung

Hier wird die Adresse des Operanden nicht direkt im Befehl angegeben, sondern indirekt aus einem Hilfsregister gelesen. Als Hilfsregister dienen dabei R0 und R1 für Zugriffe ins interne RAM, sowie der Datenzeiger DPTR für Zugriffe ins eXterne RAM.

Beispiel:  mov R1,#2Eh                      ; R1 mit Adresskonstanten 2Eh laden
                mov  A,@R1                       ; Kopiert den Inhalt von 2Eh in den Akku

Die Registerindirekte Adressierung ermöglicht, dass der selbe Code mit unterschiedlichen Ziel- oder Quelloperanden ausgeführt werden kann.

5. Indizierte Adressierung (Basisadresse + Index)

Durch indizierte Adressierung kann sehr bequem auf Datentabellen, Datenfelder oder Textkonstanten im Programmspeicher zugegriffen werden. Auch hier ist natürlich nur ein lesender Zugriff möglich. Als Basisadresse wird der Datenzeiger (DPTR) oder der Programmzähler (PC) verwendet. Als Index (oder Offset) dient jeweils der Akkumulator. Das Holen eines Tabellenwertes aus dem Programmspeicher zeigt folgendes Beispiel:

Beispiel:   mov   DPTR,#02B3h                       ; Lädt die Adresskonstante 02B3h
                                                                       ; in den Datenzeiger (Basisadresse)
                mov    A,#02h                                  ; Index 02h in den Akku
                movc  A,@A+DPTR                       ; Tabellenwert aus 02B5h holen

Übung zu Befehlsaufbau und Adressierungsarten: PDF

 

      arrow6_L.gif    

9.1.2006

    arrow6_R.gif