Der Nachfolger des WDR-Computerclub mit Wolfgang Back und Wolfgang Rudolph - ...und immer ein Bit übrigbehalten!


Das Forum zur C-Control-1
Welche C-Control-Varianten existieren?
Übersicht - Suchen - Neueste 50 Beiträge - Neuer Beitrag - Login - Registrieren
INFO - FAQ - CC2-Forum - CCPro-Forum 

 Assemblerkurs für die OM-Mikrocontroller - Teil 3 Kategorie: Open-Micro/Open-Mini/Open-Midi/Open-Macro/Open-Maxi (von Dietmar, Homepage - 11.02.2018 23:25)
Dietmar nutzt:  Open-Micro, Open-Mini, Open-Midi, Open-Macro, Open-Maxi, Open-Mini M-Unit, Open-Mini Station
' ----------------------------------------------------------------------------
' 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

Bisherige Antworten: