Befehle zum Datentransfer / weitere Befehle

  PUSH und POP   XCH   MOVC   SWAP   NOP   Was noch zu sagen bleibt
Nicht nur der MOV-Befehl ist in der Lage, Bytes im Speicher des Controllers zu kopieren. Für Spezialaufgaben gibt es dazu Befehle, die hier erläutert werden sollen.

PUSH und POP

PUSH legt ein Byte auf dem Stack ab, POP liest ein Byte vom Stack zurück. Dabei wird jeweils der Stackpointer incrementiert oder wieder decrementiert.

Die Stack-Befehle können genutzt werden, um bestimmte Bytes kurzfristig zu sichern, ohne sich um die Adresse kümmern zu müssen, an der diese dann abgelegt werden. Durch die LIFO-Logik des Stacks sind die abgelegten Bytes in umgekehrter Reihenfolge zurückzulesen! Ausserdem können natürlich keine Bytes im Hauptprogramm abgelegt und im Unterprogramm ausgelesen werden, da bei einem Unterprogrammaufruf ja die Rücksprungadresse auch auf dem Stack abgelegt wird. Die PUSH- und POP-Befehle können nur mit direkt angegebenen Speicheradressen umgehen. Aus diesem Grunde müssen beim Sichern von Registern jeweils die Registeradressen angegeben werden, nicht die Register selber.

PUSH [Byte im RAM]
POP [Byte im RAM]

In diesem Beispiel werden in einem Unterprogramm die Register A, R0 und R1 verändert. Dies soll das Hauptprogramm aber nicht beeinträchtigen, darum werden diese Werte auf dem Stack zwischengespeichert.

	; Hauptprogramm
		call unterprogramm
	; ...
	
	unterprogramm:
		push Acc	; A, R0 und R1 sichern
		push 0
		push 1

		; ... beliebige Befehle ...

		pop 1		; R1, R0 und A zurücklesen
		pop 0
		pop Acc
		
		ret

zurück zum Anfang

XCH

XCH ist ein interessanter Befehl zur Optimierung der eigenen Programme: er arbeitet vom Prinzip her genauso wie ein MOV-Befehl, nur dass er nicht das Ziel-Byte mit dem Quell-Byte überschreibt, sondern beide Bytes austauscht. Dabei verbraucht er exakt genausoviel Programmspeicher und Maschinenzyklen wie der gleichlautende MOV-Befehl, obwohl er zwei dieser MOV's ersetzt. Leider ist XCH nicht allzuoft anwendbar, erst recht, da er nur mit dem A-Register als einem Operator implementiert ist.

XCH A,[Op] Operator
Rn @Rn Byte im RAM
A X X X

zurück zum Anfang

MOVC

MOVC ist der einzige Befehl, der nicht auf das RAM zugreift, sondern auf den Programmspeicher. Da dieser zur Laufzeit des Programms nur lesbar ist, kann es natürlich keinen MOVC-Befehl zum schreiben geben. Der Programmspeicher ist so groß, dass er nicht mehr mit einem einzelnen Byte adressierbar ist. Darum arbeitet MOVC mit der basisrelativen Adressierung.

MOVC A,@A+DPTR

Sehr nützlich ist MOVC zum Zugriff auf vorberechnete Tabellen. Möchte man beispielsweise oft A*3+6 berechnen, so benötigt man normalerweise eine Multiplikation (4 Maschinenzyklen), eine Addition (1 Zyklus) sowie mindestens 2 MOV-Befehle (je nach Ausführung 2 bis 4 Zyklen). Komplexere Funktionen können auch noch aufwendiger zu berechnen sein. Kommt es auf jeden Maschinenzyklus an, so kann eine vorher berechnete Tabelle und der MOVC-Befehl die selbe Aufgabe in nur 4 Maschinenzyklen erledigen. Wenn DPTR nicht im Programmverlauf geändert wird und daher nicht jedes Mal neu mit der Adresse versorgt werden muss, genügen sogar nur 2 Zyklen.

	; ermittelt A=A*3+6 mit vorberechneter Tabelle
		mov DPTR,#table	; Anfang der Tabelle 
		movc a,@A+DPTR
	; ...


	; Tabelle mit den vorberechneten Werten
	table:
		db 6	; A=0
		db 9	; A=1
		db 12	; A=2
		db 15	; A=3
		db ...

zurück zum Anfang

SWAP

SWAP vertauscht die Bits 0 bis 3 mit den Bits 4 bis 7 im A-Register. Damit kann man SWAP beispielsweise als effizienten Ersatz für 4 RR- oder RL-Operationen einsetzen. Auch in einigen anderen Fällen mag SWAP von Nutzen sein, unter anderem wenn man ein Byte bitweise umordnen muss.

SWAP A
	; Diese Operationen sind äquivalent:
		rr a		; Rotation nach rechts
		rr a
		rr a
		rr a
		
		swap a		; schnelles Vertauschen der Bits

zurück zum Anfang

NOP

Der sicherlich am einfachsten zu erklärende Befehl ist NOP (No operation)- er macht einfach nichts, bis auf einen Maschinenzyklus zu verbraten und 1 Byte im Programmspeicher zu belegen. Daher wird NOP oft für Warteschleifen eingesetzt, oder als Lückenfüller in Codetabellen, wie sie für JMP @A+DPTR verwendet werden können.

NOP

zurück zum Anfang

Was noch zu sagen bleibt

Das war nun die Aufstellung und Erläuterung zu den meisten Assemblerbefehlen, die der MCS-51 kompatible Kontroller zu bieten hat. Einige Befehle wurden bewusst ausgelassen, da sie von eher zweifelhaftem Nutzen sind und praktisch nie gebraucht werden, oder Einsteiger nur unnötig verwirren würden. Um mit dem 89C2051 arbeiten zu können, der hier als Lehrbeispiel gebraucht wird, ist diese Anleitung aber durchaus geeignet. Die nicht erläuterten Befehle: DA; XCHD A,@Rn; MOVX; MOVC A,@A+PC.


zurück zum Anfang
Seite zurück Startseite Seite vor
Erik Buchmann
EMail an: Owner@ErikBuchmann.de