
|
INFO - FAQ - CC2-Forum - CCPro-Forum |
|
||
|
' ---------------------------------------------------------------------------- ' Assemblerkurs für die OM-Mikrocontroller - Teil 3 ' In OCBASIC 1.11a für die Open-Macro von Dietmar Harlos am 10. Februar 2018 ' ---------------------------------------------------------------------------- ' Dieser Teil des Assemblerkurs demonstriert die verschiedenen Stackarten. ' Eine Erklärung, was ein Stack ist, gibt es beim Befehl PUSH in der ' "Bedienungsanleitung zur Open-Macro und Open-Maxi" auf der OM-Infosite: ' http://om.dharlos.de ' Auf der OM gibt es drei verschiedene Stacks: Den Rechenstack des Betriebs- ' systems, den GOSUB-Stack des Betriebssystems und den Hardware-Stack des ' Mikrocontrollers. ' Die Original-C-Control ("C-Control I Version 1.1") kennt beim Rechenstack ' kein richtiges POP. Der Top-Of-Stack-Eintrag kann beliebig häufig gelesen ' werden, ohne daß der Stack über- oder unterläuft. Stackfehler wirken sich ' also nicht aus. Das wird zum Beispiel beim BEEP-Befehl ausgenutzt. FwPush, ' FwPop, PUSH, POP und REMOVETOS sind Befehle für den Rechenstack. ' Der GOSUB-Stack ist dagegen ein gewöhnlicher Stack. Stackfehler wirken sich ' also aus. GOSUB und RETURN sind Befehle für den GOSUB-Stack. ' Der Hardware-Stack ist ebenfalls ein gewöhnlicher Stack. Stackfehler wirken ' sich also aus. Die Assemblerbefehle PSHA, PULA, PUSHA, POPA, BSR, JSR, RTS, ' usw. sind Befehle für den Hardware-Stack. Der Hardware-Stack kann also nur ' in Assembler sinnvoll verwendet werden. ' ---------------------------------------------------------------------------- INCLUDE "omac.def" 'Definitionen für die Open-Macro DIM wert BYTE 'eine Bytevariable im RAM ' ---------------------------------------------------------------------------- ' Das Hauptprogramm in OCBASIC: ' Auf der Seriellen Schnittstelle wird Folgendes ausgegeben: ' 101 ' 124 ' 165 wert=42 'Variable auf Wert setzen. PRINT asm(123) 'Assemblerroutine aufrufen, dabei Wert auf dem Rechenstack übergeben und den auf ' dem Rechenstack zurückgegebenen Wert auf der Seriellen Schnittstelle ausgeben. ' Das entspricht einem "GOSUB asm(123)" und anschließendem "PRINT POP". REMOVETOS 'Top-Of-Stack-Eintrag vom Rechenstack entfernen. PRINT POP 'Den zweiten auf dem Rechenstack zurückgegebenen Wert ausgeben. PRINT wert 'Den dritten in der Variable zurückgegebenen Wert ausgeben. End2Host=ON 'Nach Programmende in den Host-Modus END 'Programmende ' ---------------------------------------------------------------------------- FUNCTION asm INLASM 'Assemblerroutinen müssen durch das Schlüsselwort INLASM gekennzeichnet werden ' ---------------------------------------------------------------------------- ' 1. Beispiel: Übergabeparameter an die Assemblerroutine durch das Betriebssystem ' Als besonderen Komfort übergeben die OM-Betriebssysteme an eine Assemblerroutine den Top-Of-Stack-Eintrag ' des Rechenstacks im Akkumulator (A). Der Eintrag wird allerdings nicht vom Stack entfernt (UNREALPOP). ' Außerdem wird im X-Register die Adresse von FREERAM (Zeiger auf freien RAM-Bereich für Assembler, 5 Bytes) übergeben. ' Zusätzlich werden die Flags für einen Vergleich gesetzt (TSTA-Befehl). ! add wert 'Addiere die Variable "wert" zum Akkumulator (A) (123+42=165) ! sta wert 'Speichere Akkumulator (A) in der Variable "wert" ' ---------------------------------------------------------------------------- ' 2. Beispiel: Rechenstack ' Stackfehler wirken sich nicht aus. ' In Assembler-Interruptroutinen steht der Rechenstack nicht zur Verfügung. ! jsr FwPop 'Wert (Top-Of-Stack-Eintrag) vom Rechenstack lesen und entfernen, Rückgabe vom Byte im Akkumulator (A) ! inca 'eins addieren (123+1=124) ! jsr FwPush 'Byte auf dem Rechenstack speichern, Übergabe vom Byte im Akkumulator (A) ' ---------------------------------------------------------------------------- ' 3. Beispiel: Hardware-Stack ' Der Hardware-Stack der 68HC08-Mikrocontroller arbeitet nach dem LIFO-Prinzip. Stackfehler wirken sich aus und ' lassen das System abstürzen. Es ist also immer darauf zu achten, daß jeder auf dem Stack gespeicherte ("gepushte") ' Wert wieder vom Stack entfernt ("gepoppt") wird. ' Auch in Assembler-Interruptroutinen steht der Hardware-Stack zur Verfügung. ! lda #100 'Lade Akkumulator (A) mit Wert 100 ! pusha 'Speichere Akkumulator (A) auf dem Hardware-Stack (Alternativsyntax: PSHA) ! inc 1,sp 'Erhöhe den gerade gepushten Wert auf dem Hardware-Stack um eins (100+1=101) ! popa 'Hole den gepushten Wert wieder vom Hardware-Stack (Alternativsyntax: PULA) ! jsr FwPush 'Byte auf dem Rechenstack speichern, Übergabe vom Byte im Akkumulator (A) ' Die Reihenfolge ist entscheidend, wenn man die zwischengespeicherten Werte wieder korrekt zurückholen will: ! pusha 'Speichere Akkumulator (A) auf dem Hardware-Stack (Alternativsyntax: PSHA) ! pushx 'Speichere X-Register (X) auf dem Hardware-Stack (Alternativsyntax: PSHX) ! pushh 'Speichere H-Register (H) auf dem Hardware-Stack (Alternativsyntax: PSHH) ! clra 'Setze A, X und H auf Null (oder einen anderen Wert). ! clrx ! clrh 'Nach dem Zurückholen mittels POPH, POPX und POPA haben die Register wieder ihren alten Wert. ! poph 'Hole den gepushten Wert wieder vom Hardware-Stack (Alternativsyntax: PULH) ! popx 'Hole den gepushten Wert wieder vom Hardware-Stack (Alternativsyntax: PULX) ! popa 'Hole den gepushten Wert wieder vom Hardware-Stack (Alternativsyntax: PULA) ' ---------------------------------------------------------------------------- ! rts 'Rücksprung zum Betriebssystem ' ---------------------------------------------------------------------------- END FUNCTION ' ---------------------------------------------------------------------------- INCLUDE "om_fw.pro" 'INCLUDE-Datei für Firmwareroutinen ' --------------------------------------------------------------------------- Passender Link: Assemblerkurs für die OM-Mikrocontroller (Teil 3) als ZIP-Archiv Meine Homepage: http://ccintern.dharlos.de |
| Antwort schreiben |