Forum: Mikrocontroller und Digitale Elektronik Registerwert zu 16Bit Pointer addieren AVR Assembler


von pacer (Gast)


Lesenswert?

Hallo,

ich bin gerade dabei Unterprogramm für eine Displayansteuerung in 
Assembler schreiben. Am Ende des Programms habe ich einen Datenbereich 
zu stehen, in dem die Texte stehen, die auf dem Display angezeigt werden 
sollen.
Nun bin ich auf das Problem gestoßen, dass ich den z-Vektor beim 
Aufrufen des Unterprogramms auf die ensprechende Stelle zeigen lassen 
muss. Dazu möchte ich einen Registerwert zu dem Z-Pointer addieren. 
Dieser Registerwert muss beim Aufruf des Unterprogramms mit übergeben 
werden.

Nun finde ich aber keinen Befehl, der einen Registerwert direkt zu dem 
z-Pointer addiert. Wie muss es dann aussehen wenn man den einfachen 
Add-Befehl nimmt?

Die Einsprungmarke für den Datenbereich beim Aufruf des Unterprogramms 
mit zu übergeben wird wohl nicht gehen. Wäre halt nur ne Idee, wenn es 
gehen würde, könnte man für jeden Text eine eigene Einsprungmarke 
definieren und bräuchte die dann nur noch aufzurufen ohne dass man 
nachzählen muss um wieviel der z-Pointer verbogen werden muss.

Ich hoffe ich hab mich verständlich ausgedrückt, Ziel ist es einfach, 
dass man das UP aufrufen kann einen Text definert und ein paar Werte mit 
übergibt.

Gibts sonst noch alternative Vorschläge?

Gruß, pacer

von Falk B. (falk)


Lesenswert?

@ pacer (Gast)

>Nun finde ich aber keinen Befehl, der einen Registerwert direkt zu dem
>z-Pointer addiert.

Dann suchst du schlecht.

AVR Arithmetik
AVR-Tutorial: Mehrfachverzweigung

>Die Einsprungmarke für den Datenbereich beim Aufruf des Unterprogramms
>mit zu übergeben wird wohl nicht gehen.

Warum? Das geht prima.

MfG
Falk

von pacer (Gast)


Lesenswert?

danke für die schnelle Antwort.
Bei der Addition würde ich einen 8Bit-Wert auf ein 16bit-Register 
addieren.
Laut Tutorial wird aber ein 16Bit-Wert addiert
add   r16, r20
adc   r17, r21

in meinem Unterprogramm steht folgendes:
ldi     ZL,low(Sprungtabelle*2)
ldi     ZH,high(Sprungtabelle*2)
Nun müsste ich aber je nach Aufruf des Unterprogramms den Platzhalter 
Sprungtabelle durch die richtige Marke ersetzen. Wie würde man das 
anstellen, ich habe keinen Plan?

von pacer (Gast)


Lesenswert?

also das mit der Addition hab ich jetzt gefunden:
add     ZL,r16
ldi     r16,0
adc     ZH,r16
müsste dann so funktionieren, gell?

von Philipp B. (philipp_burch)


Lesenswert?

jep.

von pacer (Gast)


Lesenswert?

supi, hab es jetzt zum laufen bekommen, würde mich aber interessieren 
wie das mit Labeln funktionieren soll.

von spess53 (Gast)


Lesenswert?

Hi

>supi, hab es jetzt zum laufen bekommen, würde mich aber interessieren
>wie das mit Labeln funktionieren soll.

??? oder meinst du so etwas:
ldi ZL,Low(Label)
ldi ZH,High(Label)  ?

MfG Spess

von pacer (Gast)


Lesenswert?

yep, genau das hab ich in meinem Unterprogramm drinstehen.
Wenn ich das Unterprogramm aber aufrufe, muss ich das Label anpassen 
können.
Ich weiß nur nicht wie

von Falk B. (falk)


Lesenswert?

@  pacer (Gast)

>yep, genau das hab ich in meinem Unterprogramm drinstehen.

Was schon mal falsch ist.

>Wenn ich das Unterprogramm aber aufrufe, muss ich das Label anpassen
>können.
>Ich weiß nur nicht wie

Das Zauberwort heisst Parameter. Der Z-Pointer wird vor dem Aufruf 
geladen. Dort schreibt man immer die jeweiligen Labels rein.

So.

http://www.mikrocontroller.net/articles/AVR-Tutorial:_ADC#Ausgabe_als_Spannungswert
1
]
2
    ldi     ZL,low(Tabelle*2)  
3
    ldi     ZH,high(Tabelle*2)
4
    rcall   meine_Funktion
]

MFG
Falk

von Michael U. (amiga)


Lesenswert?

Hallo,

eine vor mir öfter genutzte Variante:

Du übergibst in YL eine Funktionsnummer, anhand dieser wird in der 
Tabelle der passende Text gesucht und dessen Start nach X geholt und die 
Funktion mit ijmp aufgerufen. Die Funktione kehrt dann mit ret zur 
Aufrufstelle von ca__funktion zurück.

Eine Funktion hat immer eine Aufrufadresse in der Tabelle funktionen und 
einen Text in der Tabelle texte.

call_funktion:         // YL enthält die Funktionsnummer, benutzt X, Y, 
Z
  ldi ZL,low(texte*2)
  ldi ZH,high(texte*2)

  clr YH
  lsl YL               // * 2, da Adressen 16 Bit sind
  rol YH
  add ZL,YL
  adc ZH,YH            // Z zeigt jetzt auf den Platz der Adresse Text

  lpm XH,Z+            // in X ist jetzt der Zeiger auf den Text
  lpm XL,Z

  ldi ZL,low(funktionen*2) // in Y ist immernoch der Offset der 
Menünummer
  ldi ZH,high(funktionen*2)
  add ZL,YL
  adc ZH,YH            // Z zeigt jetzt auf den Platz der Adresse 
Funktion

  mov ZH,YH            // Startadresse der Funktion jetzt nach Z
  mov ZL,YL
  ijmp                 // indirekt jmp (Z) zur Funktion

  die Funktionen müssen mit ret enden

funktionen:
 .dw  funktion_1, funktion_2, funktion_3

texte:
 .dw  text_1, text_2, text_3

text_1:
 .db "Das ist Text 1",0

text_2:
 .db "Das ist Text 2",0

text_3:
 .db "Das ist Text 3",0

Gruß aus Berlin
Michael

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.