www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Erklärung des Sinn des Pointers


Autor: Dennis Brenzel (danrulz81)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich lese mich gerade durchs AVR-ASM-Tut und wundere mich bei diesen 
Codezeilen:
.include "m8def.inc"
 
    ldi     R16, 0xFF
    out     DDRB, R16               ; Port B: Ausgang
 
    ldi     ZL, LOW(daten*2)        ; Low-Byte der Adresse in Z-Pointer
    ldi     ZH, HIGH(daten*2)       ; High-Byte der Adresse in Z-Pointer
 
    lpm                             ; durch Z-Pointer adressiertes Byte
                                    ; in R0 laden
    out     PORTB, R0               ; an PORTB ausgeben
 
ende:   
    rjmp ende                       ; Endlosschleife
 
daten:
    .db 0b10101010

Wieso wird nicht einfach das Register R16 mit der Binärzahl gefüllt und 
dann an PORTB ausgegeben? Wieso wird das über den Pointer gemacht? z.B. 
so:
 
.include "m8def.inc"
 
    ldi     R16, 0xFF
    out     DDRB, R16               ; Port B: Ausgang
 
    ldi     R16, 0b10101010        
                                    
    out     PORTB, R16               ; an PORTB ausgeben
 
ende:   
    rjmp ende                       ; Endlosschleife
Macht doch das Programm kürzer. Was genau ist eigentlich der Sinn des 
Pointers? Irgendwie hab ich das aus dem Tutorial nicht ganz verstanden.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist mir jetzt zu aufwändig die exakte Stelle im Tutorial zu suchen. 
Eine Motivation könnte sein:

Vielleicht um zu erklären wie man mit Zahlen aus dem SRAM statt mit 
Konstanten arbeitet?

Stell dir vor, eine andere Routine speichert regelmäßig Werte an die 
RAM-Adresse Daten und der Code oben soll die Werte ausgeben. Das geht 
mit deiner zweiten Lösung ganz schlecht, weil du die Werte ja noch nicht 
kennst...

Autor: heinzwurst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der sinn ist, das du die daten aus dem programm memory liest, soll ja 
nur ein beispiel sein.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

das Tutorial bietet Beispiele, mehr nicht. ;)

Dein Version ist kürzer und solange nur ein Wert ausgegeben werden soll 
auch sinnvoll.

Jetzt erweitern wir das mal.

Ausgabe von 40 Bitmustern nacheinander ausgegeben werden:

.include "m8def.inc"
 
    ldi     R17, 40                 ; Anzahl der Werte

    ldi     R16, 0xFF
    out     DDRB, R16               ; Port B: Ausgang
 
    ldi     ZL, LOW(daten*2)        ; Low-Byte der Adresse in Z-Pointer
    ldi     ZH, HIGH(daten*2)       ; High-Byte der Adresse in Z-Pointer
 
loop:    
    lpm     R0, Z+                  ; durch Z-Pointer adressiertes Byte
                                    ; in R0 laden und Z erhöhen

    out     PORTB, R0               ; an PORTB ausgeben

    dec     R17                     ; Zähler -1
    brne    loop

ende:   
    rjmp ende                       ; Endlosschleife
 
daten:
    .db 0b10101010


wäre Deine Version dann auch noch kürzer?

Es kommt letztlich auf das Ziel an, welchen Weg man wählt.

Gruß aus Berlin
Michael

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu dem Thema Pointer gibt es übrigens einen guten, allerdings 
englischsprachigen Podcast

Security Now 237: The Power of Pointers
An introduction to the use of "indirection" in computer science, 
security news, and more.
http://www.twit.tv/sn237

In der gleichen Serie werden in loser Folge die Innereien einer CPU von 
Anfang an erklärt.

Security Now 233: Let's Design A Computer
Security Now 235: Machine Language
Security Now 237: The Power of Pointers
Security Now 239: Stacks, Registers, and Recursion
Security Now 241: Hardware Interrupts

Eine Folge dauert ca. 1,5h. Man kann bei den Sendungen Live zusehen 
(Aufzeichnung Mittwochabend) oder die Tage drauf als MP3 oder Video 
downloaden. Heute abend müsste eigentlich mit #243 wieder eine Sendung 
aus der Reihe kommen.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Muß mich noch korrigieren, Edit ging nicht mehr...
daten:
    .db 0b10101010
    .db 0b11110000

usw. hier müssen jetzt batürlich die 40 Werte als Tabelle hin

Gruß aus Berlin
Michael

Autor: MarioT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael U. schrieb:
> Jetzt erweitern wir das mal.
>
> Ausgabe von 40 Bitmustern nacheinander ausgegeben werden:

Mußt natürlich auch 40 Daten Anbieten.

Autor: Dennis Brenzel (danrulz81)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael U. schrieb:

>
> daten:
>     .db 0b10101010
>     .db 0b11110000
> 
>
> usw. hier müssen jetzt batürlich die 40 Werte als Tabelle hin
O.k. Das macht natürlich Sinn. Danke. Und warum erhöst du den Pointer um 
"1"? Erhöht sich dadurch die Adresse, auf die er zeigt um 1, oder wie 
muss ich mir das vorstellen? Werden dann die Daten immer von unten nach 
oben in den Speicher geschrieben?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:

> Vielleicht um zu erklären wie man mit Zahlen aus dem SRAM statt mit
> Konstanten arbeitet?

Korrektur: Dann müsste man dann dem Assembler noch mit der .DSEG 
Direktive beibringen, dass die Adresse Daten im RAM steht 
(http://www.mikrocontroller.net/articles/AVR-Tutorial:_SRAM)

Das Beispiel oben liest über den Pointer den Wert aus dem ROM.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis Brenzel schrieb:
>> [/avrasm]
>>
>> usw. hier müssen jetzt batürlich die 40 Werte als Tabelle hin
> O.k. Das macht natürlich Sinn. Danke. Und warum erhöst du den Pointer um
> "1"?

Damit er an das nächste 'Byte' rankommt

Am Anfang 'zeigt' der Z-Pointer hier hin

              daten:
--->                 .db 0b10101010
                     .db 0b11110000
                     .db 0b00111000
                     ....

der Wert von dort wird durch

   lpm     R0, Z+

nach R0 geholt  (R0 enthält dann 0b10101010) und gleichzeitig wird der 
Z-Pointer um 1 erhöht, so dass er hier hin zeigt

              daten:
                     .db 0b10101010
--->                 .db 0b11110000
                     .db 0b00111000
                     ....

beim nächsten

   lpm     R0, Z+

wird daher 0b11110000 nach R0 geladen, und gleichzeitig der Z-Pointer 
wieder um 1 Stelle weitergerückt.

              daten:
                     .db 0b10101010
                     .db 0b11110000
--->                 .db 0b00111000
                     ....

Beim nächsten lpm kommt dann der nächste Wert drann, usw, usw.

Autor: MarioT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis Brenzel schrieb:
> Und warum erhöst du den Pointer um
> "1"? Erhöht sich dadurch die Adresse, auf die er zeigt um 1, oder wie
> muss ich mir das vorstellen?

http://www.avr-roboter.de/controller/befehle/besch...

Dennis Brenzel schrieb:
> Werden dann die Daten immer von unten nach
> oben in den Speicher geschrieben?

Dennis Brenzel schrieb:
>>> daten:
>>     .db 0b10101010
>>     .db 0b11110000
>> >
Die Daten werden im Programmspeicher(Flash) beim Programmieren abgelegt.

Stefan B. schrieb
ROM?

Autor: Dennis Brenzel (danrulz81)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AAAAAAAAAAAHHHHHHHHHH, da geht mir ein Licht auf. Wieso wird das so 
nicht im Tutorial erklärt? Super verständliche Hilfe!
Kann ich statt dessen auch nen X- oder Y-Pointer nehmen?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis Brenzel schrieb:
> AAAAAAAAAAAHHHHHHHHHH, da geht mir ein Licht auf. Wieso wird das so
> nicht im Tutorial erklärt? Super verständliche Hilfe!

Weil genau unter der von dir kritisierten Codestelle ein Programm 
angegeben ist, welches genau das macht. Einmal mit der 'alten' Nur-lpm 
Variante, einmal mit den neueren 'lmp Z+,rr' Befehlen. Nur mit 
Textausgabe, aber ansonsten ist es genau das gleiche Prinzip.

> Kann ich statt dessen auch nen X- oder Y-Pointer nehmen?

Datenblatt schauen. Gibt es einen Befehl lpm X+, rr ?

Autor: Dennis Brenzel (danrulz81)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zu spät für nen Edit.
-->hab ich mir selber beantworten können. Laut Tutorial funktionieren X 
und Y Pointer gleich, mit einer Ausnahme: Mit dem X-Pointer ist kein 
Zugriff LDD/STD mit einem Displacement möglich.
Eine Frage bleibt noch? Muss ich den auch initialiesieren, wie bspw. den 
Stackpointer (btw: Warum muss man den eigentlich initialisieren?)?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis Brenzel schrieb:

> Eine Frage bleibt noch? Muss ich den auch initialiesieren,

Was verstehst du unter initialisieren?

Klar musst du dem Z-Pointer irgendwann einmal sagen, dass es bei daten 
losgeht. Du könntest ja 5 Tabellen im Programm haben und je nach 
Situation eine andere abarbeiten wollen.

> wie bspw. den
> Stackpointer (btw: Warum muss man den eigentlich initialisieren?)?

Bei neueren AVR muss man das auch nicht mehr. Nimm es einfach als 
gegeben hin, dass du beim Stackpointer für klare Verhältnisse sorgen 
musst.

Autor: Dennis Brenzel (danrulz81)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:

> Klar musst du dem Z-Pointer irgendwann einmal sagen, dass es bei daten
> losgeht. Du könntest ja 5 Tabellen im Programm haben und je nach
> Situation eine andere abarbeiten wollen.

Muss ich dem ZL und ZH dann erstmal "0" übergeben, damit er am Anfang 
los läuft? Oder ist das Adressspezifisch?

Autor: MarioT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
    ldi     ZL, LOW(welche_Daten_ins_LCD*2)        
    ldi     ZH, HIGH(welche_Daten_ins_LCD*2)

    lpm     R0, Z+
;usw

    ldi     ZL, LOW(Eingang_Text*2)        
    ldi     ZH, HIGH(Eingang_Text*2)

    lpm     R0, Z+
;usw

welche_Daten_ins_LCD:
.db 17 ,5 ,1 ,12

Eingang_Text:
.db "Kollektor Solar-VL  Solar-RL  W",0b11100001,"rmet.SekPuffer.o  Puffer.m  Puffer.u  Strahlung "
.db "Heizkr.RL WarmwasserHeizkr.VL Aussen    Temp.Raum --------- Durchf.SolKessel.VL "


Ich hoffe es ist Verständlich.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis Brenzel schrieb:
> Karl heinz Buchegger schrieb:
>
>> Klar musst du dem Z-Pointer irgendwann einmal sagen, dass es bei daten
>> losgeht. Du könntest ja 5 Tabellen im Programm haben und je nach
>> Situation eine andere abarbeiten wollen.
>
> Muss ich dem ZL und ZH dann erstmal "0" übergeben, damit er am Anfang
> los läuft? Oder ist das Adressspezifisch?

reden wir vom selben?

Hier:

    ldi     ZL, LOW(daten*2)        ; Low-Byte der Adresse in Z-Pointer
    ldi     ZH, HIGH(daten*2)       ; High-Byte der Adresse in Z-Pointer

lädst du den Z-Pointer mit der Startadresse der Daten. Oder um bei 
meinem graphischen Beispiel zu bleiben. Genau diese beiden Anweisungen 
'installieren' den ersten Pfeil in


             daten:
--->                 .db 0b10101010
                     .db 0b11110000
                     .db 0b00111000
                     ....

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
MarioT schrieb:

> Stefan B. schrieb
> ROM?

Ich bin ein älterer Herr und verstehe nur ganze Sätze. Wenn "ROM?" nicht 
nur ein rhetorisches Schmankerl ist, frag' einfach nochmal.

Autor: Dennis Brenzel (danrulz81)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denk mal ja, so hab ich es verstanden:

Der Wert in den Klammern (hier:welche_daten_ins_LCD und Eingang_Text) 
sagen dem Z-Pointer, bei diesem "Label" musst du den ersten Wert holen. 
Z+ erhöhen, um an den 2. Wert zu kommen usw. Richtig Verstanden?

Autor: MarioT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. schrieb:
> Ich bin ein älterer Herr und verstehe nur ganze Sätze. Wenn "ROM?" nicht
> nur ein rhetorisches Schmankerl ist, frag' einfach nochmal.

Entschuldige! Ich dachte Du hast Dich verschrieben und bemerkst den 
Fehler.
AVR haben kein ROM.

Autor: MarioT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dennis Brenzel schrieb:
> Richtig Verstanden?

Ja.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt, Flash (Datenblatt) oder Flash-ROM oder program space 
(avr-libc, Tutorial) ist gemeint.

Autor: Dennis Brenzel (danrulz81)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super, ich danke euch.

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.