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.
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.
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.
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.
; 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.
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. |