Registerwert zu 16Bit Pointer addieren AVR Assembler

Gast #1034963
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
Gast #1034974
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?
#1035302
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
#1035313
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren