mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Assembler - AVR Frage


Autor: Armin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
ich arbeite mich zur Zeit auf einem ATMEGA32 in Assembler ein (bin also 
Anfänger). Bei einem kleinen Progrämmchen habe ich nun ein Problem 
festgestellt. Die Fehlerursache habe ich ansich erkannt, weiß aber nicht 
wie ich es besser machen kann. Daher meine Frage an euch, ob Ihr mir 
weiterhelfen könnt.

Folgende Situation, ich versuche eine Uhr mittels Assembler zu 
programmieren. Vorhandene Beispielcodes in der Codesammlung habe ich 
angeschaut, dass eigentliche Problem konnte ich damit aber nicht lösen. 
Wie lasse ich das Programm bedingt in ein Unterprogramm springen, also 
wie löst man sowas in Assembler?
Zur Erläuterung was ich im Hinterkopf habe, ein kurzes Beispiel in C 
(ich weiß, dass dies 1:1 in Assembler nicht möglich ist, es dient also 
nur der Erläuterung was ich erreichen möchte):

//var=Laufvariable, wird "irgendwo" hochgezählt
if (var==x) // var identisch mit x?
{
  unterprogramm();
}

Ich habe nun folgendes geschrieben  (Auszug aus meinem Programm):

loop:
     cpi sekunde,60 //compare register & Konstante
     breq min       //verzweige zu "min" wenn z flag gesetzt
     rjmp loop

min:
    ldi sekunde, 0
    inc minute
    ret

(Hinweis: am Programmanfang habe ich ".def sekunde = R19" & ".def minute 
= R20" stehen , sind also beides register wie es sein sollte)

Mit meinem JTAG Debugger habe ich gemerkt, dass bei "breq min" der PC 
anscheinend nicht auf dem Stack gesichert wird (Adresse verkleinert sich 
nicht...), beim anschliessenden ret springt er dann wohl ins nirwana, 
JTAG ICE warnt dabei vor invalid value (0x7FFFFFFF) und mein Programm 
fängt ganz von vorne an. Offensichtlich ist breq (wohl auch brne etc.) 
nicht dafür geeignet, weil der PC nicht gesichert wird, richtig?

Einen Rücksprung aus einer Interruptroutine habe ich probiert, weiß also 
wie es aussehen müsste (was Stack und PC angeht).

Wie muss ich es stattdessen lösen?
Für ein kurzes, kommentiertes Beispiel wäre ich dankbar.

Danke und Gruß
Armin

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
breq macht einen relativen Sprung. Das hat nix mit ret zu tun. 
Unterprogrammaufrufe gehen mit call bzw. rcall. Schau Dir den 
Befehlssatz mal genauer an. Du müsstest, wenn Du mit der obigen 
Bedingung springen willst, was in der Art

    cpi sekunde, 60
    brne weiter
    call min

weiter:
    ;weiter im Programm

min:
    ldi sekunde, 0
    inc minute
    ret

Dann springt das Programm bei ret wieder zurück (also nach "weiter")

Autor: unsichtbarer WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"call" dürfte dich interessieren.

Es dürfte dann auf ein Konstukt hinauslaufen, dass die beiden Variablen 
vergleicht und bei "negativem" Ergebnis die folgende Anweisung 
überspringt.
In diesem Fall wäre die Anweisung dann das "call".

Pseudocode: (ich kann Asm lesen, aber nicht schreiben...)
anfang:
.
.
.

compare X,Y
skip if equal
call ungleich
allgemeines Weitermachen
.
.
.
jmp anfang


ungleich:
.
.
.
ret

Autor: unsichtbarer WM-Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Da war ich etwas langsamer...

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...Oder mit der Schleife von oben:

loop:
    cpi sekunde, 60
    brne loop
    call min

min:
    ldi sekunde, 0
    inc minute
    ret

Autor: Armin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke, besonders @johnny m., habe deinen ersten Tip verwendet, da ja 
hier noch ein Unterprogramm Stunde, u.a. kommen wird. Hat auf Anhieb 
funktioniert und habs auch verstanden...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.