Forum: Mikrocontroller und Digitale Elektronik Allgemeine Fragen zum Stack


von NiOs (Gast)


Lesenswert?

Hi!

Ich habe auf der AVR-Checklistenseite folgendes gelesen:
http://www.mikrocontroller.net/articles/AVR_Checkliste#Stackpointer_initialisiert.3F_.28Nur_in_Assembler_relevant.29

Nun in der Schule haben wir soweit mir bekannt, noch nie den 
Stackpointer initialisiert. Bedeutet das jetzt, dass das 
Assemblercodestück fehlerhaft ist? Aber wieso funktionieren unsere 
Programme, obwohl wir Interrupts,... verwenden? Gibt es da Spezialfälle 
wo dann Fehler auftreten?

Was passiert wenn die Anzahl an push und pop beim Interrupt ungleich 
sind?
Bei Interrupt muss ich den CPU_SREG sichern, allerdings welche 
Informationen beinhaltet dieses Register?

Warum kann ich ein Interrupt nicht mit ret beenden und muss stattdessen 
reti verwenden?

von Peter II (Gast)


Lesenswert?

NiOs schrieb:

> Bedeutet das jetzt, dass das
> Assemblercodestück fehlerhaft ist?
es gibt neuere Atmels wo die Hardware die Initialisierung macht - steht 
im Datenblatt.

> Was passiert wenn die Anzahl an push und pop beim Interrupt ungleich
> sind?

die Rückspruch klappt nicht, weil er auf die falschen Daten zugreift
 ->Absturz

> Bei Interrupt muss ich den CPU_SREG sichern, allerdings welche
> Informationen beinhaltet dieses Register?
steht auch im Datenblatt

> Warum kann ich ein Interrupt nicht mit ret beenden und muss stattdessen
> reti verwenden?
du kannst beides machen, nur beim reti werden aber die Interrupts wieder 
aktiviert. Der Unterschied steht auch im Datenblatt.

von (prx) A. K. (prx)


Lesenswert?

NiOs schrieb:
> Nun in der Schule haben wir soweit mir bekannt, noch nie den
> Stackpointer initialisiert. Bedeutet das jetzt, dass das
> Assemblercodestück fehlerhaft ist?

Neuere AVRs setzten den Stackptr automatisch. Alte nicht.

> Was passiert wenn die Anzahl an push und pop beim Interrupt ungleich
> sind?

Programm fliegt bei nächsten Return weg.

von Falk B. (falk)


Lesenswert?

@ NiOs (Gast)

>Nun in der Schule haben wir soweit mir bekannt, noch nie den
>Stackpointer initialisiert.

Dann warst du entweder gerade Kreide holen oder in eurem 
Kurs/Programiersprache/Beispiel ist das anders schon gemacht.

>Was passiert wenn die Anzahl an push und pop beim Interrupt ungleich
>sind?

Dann ist in wenigen Millisekunden deine CPU angestürzt, weil sie zuviel 
oder zu wenig Daten vom Stack holt und der dann überläuft.

>Bei Interrupt muss ich den CPU_SREG sichern, allerdings welche
>Informationen beinhaltet dieses Register?

Datenblatt?

>Warum kann ich ein Interrupt nicht mit ret beenden und muss stattdessen
>reti verwenden?

Weil es ein Interrupt ist und keine normale Funktion.

von LFU (Gast)


Lesenswert?

Siehe hier: Beitrag "SREG -Register"

Status Register (SREG)
C : Carry flag in status register => Überlauf der letzten
Rechenoperation
Z : Zero flag in status register => Ergebnis der letzten
Rechenoperation ist Null
N : Negative flag in status register => Ergebnis der letzten
Rechenoperation ist negativ (Bit 7 des Ergebnis ist 1)
V : Two's complement overflow indicator => Überlauf Zweierkomplement
S : N [+] V, For signed tests => Vorzeichentest negativ und
Zweierkomplement
H : Half Carry flag in the status register => Überlauf des unteren
Nibbles (untere 4 Bit im Ergebnis), für BCD-Berechnungen verwendet
T : Transfer bit used by BLD and BST instructions => beliebig nutzbares
Bit, um sich einen Zustand zu merken
I : Global interrupt enable/disable flag => schaltet Interrupts ein /
aus, damit können schnell alle Interrupts während einer kritischen
Operation gesperrt werden

von mpt (Gast)


Lesenswert?

Peter II schrieb:
> es gibt neuere Atmels wo die Hardware die Initialisierung macht - steht
> im Datenblatt.

Stimmt:
After
reset, the stack pointer (SP) points to the highest address in the 
internal SRAM.

Falk Brunner schrieb:
> Dann warst du entweder gerade Kreide holen oder in eurem
> Kurs/Programiersprache/Beispiel ist das anders schon gemacht.

Kreide wird in dieser Lehrveranstaltung nicht benutzt. Stattdessen 
benutzt der Lektor sein Tablet und beamt es auf die Leinwand xD

Falk Brunner schrieb:
> Weil es ein Interrupt ist und keine normale Funktion.

Peter II schrieb:
> du kannst beides machen, nur beim reti werden aber die Interrupts wieder
> aktiviert. Der Unterschied steht auch im Datenblatt.

habs geunfden:
The RET (subroutine return) instruction cannot be used when returning 
from the interrupt handler
routine, as this will not return the PMIC to its correct state.

Danke euch allen für die schnelle Hilfe!

von c-hater (Gast)


Lesenswert?

mpt schrieb:

> habs geunfden:
> The RET (subroutine return) instruction cannot be used when returning
> from the interrupt handler
> routine, as this will not return the PMIC to its correct state.

Was natürlich Unsinn ist. Wo stammt denn dieser grenzdebile Schwachsinn 
her?

Nein, natürlich kann man auch mit ret aus einer ISR zurückkehren. Man 
muß halt nur dafür sorgen, daß vorher SREG_I bereits wieder enabled 
ist.

Das ist ganz einfach und oft auch nützlich, um ISRs in einen (kurzen) 
exklusiv zu bearbeitenden Teil und einen (mitunter ziemlich länglichen) 
Teil zu zerlegen, der durch andere ISRs unterbrechbar ist.

isr_whatever:
  push flagsafe        ;register für backup der flags retten
  in flagsafe,SREG     ;flags in dieses Register retten

;exklusiver Teil der ISR

  sbr flagsafe,1<<SREG_I  ;I-Flag in Backup setzen
  out SREG,flagsafe    ;Interrupts erlauben

;unterbrechbarer Teil der ISR

  out SREG,flagsafe    ;wiederherstellen aller Flags, mit I schon 
gesetzt
  pop flagsafe         ;register wiederherstellen
  ret                  ;einfach nur return, das geht! Tatsächlich macht 
ret
                       ;exakt dasselbe wie reti, einziger Unterschied 
ist,
                       ;daß halt zusätzlich das I-Flag in SREG gesetzt
                       ;wird, was hier bereits vorher passiert ist


Alternativ geht auch, läuft letztlich auf dassselbe hinaus:

isr_whatever:
  push flagsafe        ;register für backup der flags retten
  in flagsafe,SREG     ;flags in dieses Register retten

;exklusiver Teil der ISR

  sei

;unterbrechbarer Teil der ISR

  sbr flagsafe,1<<SREG_I  ;I-Flag in Backup setzen
  out SREG,flagsafe    ;wiederherstellen aller Flags, mit I schon 
gesetzt
  pop flagsafe         ;register wiederherstellen
  ret                  ;einfach nur return, das geht! Tatsächlich macht 
ret
                       ;exakt dasselbe wie reti, einziger Unterschied 
ist,
                       ;daß halt zusätzlich das I-Flag in SREG gesetzt
                       ;wird, was hier bereits vorher passiert ist

von mpt (Gast)


Lesenswert?

c-hater schrieb:
> Was natürlich Unsinn ist. Wo stammt denn dieser grenzdebile Schwachsinn
> her?

stammt vom XMEGA A Manual Seite 126

@Offtopic: in und out kannte ich nicht, weil wir bis jetzt sts und lds 
verwendet haben. Danke :)

von Sven P. (Gast)


Lesenswert?

c-hater schrieb:
>> habs geunfden:
>> The RET (subroutine return) instruction cannot be used when returning
>> from the interrupt handler
>> routine, as this will not return the PMIC to its correct state.
>
> Was natürlich Unsinn ist. Wo stammt denn dieser grenzdebile Schwachsinn
> her?
Das ist kein Unsinn.
Die PMIC in den ATXmega kann etwas mehr, als das Interruptsystem im 
normalen AVR.

von Reinhard Kern (Gast)


Lesenswert?

c-hater schrieb:
> Was natürlich Unsinn ist. Wo stammt denn dieser grenzdebile Schwachsinn
> her?

Wenn man so überhaupt keine Ahnung hat, raushalten. Schon bei 
Uralt-prozessoren wie Z80 passiert meim RETI mehr als nur EI, ein EI RET 
hinterlässt das Interrupt-System in einem inkorrekten Zustand.

Und was ist eigentlich an der Aussage "Rückkehr vom Interrupt mit RETI" 
so unverständlich? Oder ist das eine Einschränkung der künstlerischen 
Freiheit? Die ist beim Programmieren völlig fehl am Platz.

Falls es dir noch nicht aufgefallen ist, es gibt mehr als einen, sogar 
viele Prozessoren, und die Maschinenbefehle sind sehr verschieden.

Gruss Reinhard

von c-hater (Gast)


Lesenswert?

Reinhard Kern schrieb:

> Falls es dir noch nicht aufgefallen ist, es gibt mehr als einen, sogar
> viele Prozessoren, und die Maschinenbefehle sind sehr verschieden.

Ach, das haut mich jetzt echt weg. Was man nach 25 Jahren gelebter 
Asm-Praxis auf ca. 20 verschiedenen Maschinen doch noch alles an neuen 
Weisheiten lernen kann.

Nur...

Wo, zum Teufel, ist im OP ist eigentlich von einem XMega die Rede? Ich 
lese da nur AVR...

von Sven P. (Gast)


Lesenswert?

c-hater schrieb:
> Wo, zum Teufel, ist im OP ist eigentlich von einem XMega die Rede? Ich
> lese da nur AVR...

Spätestens da, wo er in der von dir zitierten Textpassage die PMIC 
erwähnt.

von c-hater (Gast)


Lesenswert?

Sven P. schrieb:

> Spätestens da, wo er in der von dir zitierten Textpassage die PMIC
> erwähnt.

Das war im OP?

Nein, es war in einer Antwort, die ganz offensichtlich am Thema des OP 
vorbeiging. Also wie dargestellt: Schwachsinn. Ganz sicher jedenfalls im 
Sinne der ursprünglichen Fragestellung.

Aber ja: ich gebe zu, daß mir "PMIC" nichts gesagt hat. Habe nie die 
Notwendigkeit gesehen, einen XMega zu verwenden. Falls sich irgendwann 
die Notwendigkeit dazu ergeben sollte, werde ich ganz sicher auch innert 
kürzester Zeit wissen, was PMIC ist und tut, versprochen!

Aber auch ohne jemals einen Blick in das DB eines XMega getan zu haben, 
würde ich wetten, daß es auch bei diesem Teil eine Möglichkeit geben 
wird, mit einem ret sauber aus einer ISR rauszukommen, sie mag nur etwas 
komplizierter sein als bei einem AVR.

Um was wollen wir wetten? Ich biete die Staatschulden der BR 
Deutschland. Quote natürlich 1:1, es soll ja fair sein. Was bietest du?

von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
> Aber auch ohne jemals einen Blick in das DB eines XMega getan zu haben,
> würde ich wetten, daß es auch bei diesem Teil eine Möglichkeit geben
> wird, mit einem ret sauber aus einer ISR rauszukommen, sie mag nur etwas
> komplizierter sein als bei einem AVR.

Dann schau ins Manual rein und erleuchte uns, wie du ein demgemäss nur 
per RETI rücksetzbares Statusbit ohne RETI zurücksetzt. Ohne nebenbei 
gleich den ganzen Controller mit zurückzusetzen.

: Bearbeitet durch User
von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

A. K. schrieb:
> Dann schau ins Manual rein und erleuchte uns, wie du ein demgemäss nur
> per RETI rücksetzbares Statusbit ohne RETI zurücksetzt.

das schafft er ohne weiteres mit " 25 Jahren gelebter
Asm-Praxis auf ca. 20 verschiedenen Maschinen", er kennt halt  alle 
geheimen unbekannten Befehle!

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

A. K. schrieb:

> Dann schau ins Manual rein und erleuchte uns, wie du ein demgemäss nur
> per RETI rücksetzbares Statusbit ohne RETI zurücksetzt. Ohne nebenbei
> gleich den ganzen Controller mit zurückzusetzen.

Ganz einfach:

Ich hatte niemals ausgeschlossen, reti zu verwenden. Ich wollte nur per 
ret die ISR verlassen. Da kann ich ja beliebig vorher reti verwenden, 
oder nicht?

Also ungefähr sowas sollte mindestens möglich sein (ich habe immer noch 
kein XMega-DB gelesen, also bitte nicht nerven mit falscher Byte-Order 
der Adresse oder ähnlichem unwichtigen Schwachsinn, es geht rein um's 
Prinzip):

ISR:
pop BackupRetH
pop BackupRetL
push Low(continue_ISR)
push High(continue_ISR)
reti

continue_ISR:
; print "A.K. is a boring rookie"
push BackupRetL
push BackupRetH
ret

Falls du das weiter ausdiskutieren willst, wirst du dich bis irgendwann 
morgen gedulden müssen. Aber Vorsicht: bis dahin werde ich so ein 
XMega-DB tatsächlich mal gelesen haben...

von Reinhard Kern (Gast)


Lesenswert?

Wegstaben Verbuchsler schrieb:
> das schafft er ohne weiteres mit " 25 Jahren gelebter
> Asm-Praxis auf ca. 20 verschiedenen Maschinen"

Eben, Erfahrung und Intuition ist alles, Datenblätter sind nur für 
Angsthasen. Deshalb rät er ja jedem hier davon ab, sich nach den Angaben 
in den Manuals zu richten. Da kommt ja eh nur immer das gleiche heraus: 
funktionierende Programme. Wie langweilig.

Gruss Reinhard

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

c-hater schrieb:
> Nein, natürlich kann man auch mit ret aus einer ISR zurückkehren. Man
> muß halt nur dafür sorgen, daß vorher SREG_I bereits wieder enabled
> ist.

Korrekt.

Man kann auch mit RJMP zurückspringen, wenn man danach immer an einer 
definierten Stelle beginnen will. Den Fall hatte ich schon.

Und: man braucht auch gar nicht zurückspringen. Nämlich dann, wenn es 
kein Hauptprogramm gibt und die Anwendung rein ereignisgesteuert läuft. 
Dann nämlich schreibt man ans Ende der ISR nur ein SEI und viele NOPs, 
dahinter dann zur Sicherheit ein RJMP PC.

In dem Fall braucht man den Stackpointer nicht zu initialisieren, 
natürlich sollte man dann das SRAM besser nicht verwenden – es wird 
sonst lustig.

Macht man aber nur dann, wenn man das letzte bisschen Leistung aus einem 
ATtiny10 rausquetschen will. :-)

von Sven P. (Gast)


Lesenswert?

Markus Weber schrieb:
> c-hater schrieb:
>> Nein, natürlich kann man auch mit ret aus einer ISR zurückkehren. Man
>> muß halt nur dafür sorgen, daß vorher SREG_I bereits wieder enabled
>> ist.
>
> Korrekt.
Gut, dann sind wir jetzt bei akademischer Ddiskussion angekommen.

Markus Weber schrieb:
> Und: man braucht auch gar nicht zurückspringen. Nämlich dann, wenn es
> kein Hauptprogramm gibt und die Anwendung rein ereignisgesteuert läuft.
> Dann nämlich schreibt man ans Ende der ISR nur ein SEI und viele NOPs,
> dahinter dann zur Sicherheit ein RJMP PC.
Wie programmiert man denn einen Mikroprozessor ohne Hauptprogramm?
Außerdem:

Markus Weber schrieb:
> In dem Fall braucht man den Stackpointer nicht zu initialisieren,
> natürlich sollte man dann das SRAM besser nicht verwenden – es wird
> sonst lustig.
Jo, und dei den Sprüngen in die ISR schreibt man sich irgendwann 
sukzessive die Arbeitsregsiter platt, weil die ganz unten im SRAM liegen 
und der Stackzeiger irgendwann überläuft und wieder unten ankommt. Super 
Deal.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Sven P. schrieb:
> Markus Weber schrieb:
>> c-hater schrieb:
>>> Nein, natürlich kann man auch mit ret aus einer ISR zurückkehren. Man
>>> muß halt nur dafür sorgen, daß vorher SREG_I bereits wieder enabled
>>> ist.
>>
>> Korrekt.
> Gut, dann sind wir jetzt bei akademischer Ddiskussion angekommen.

Das sind durchaus Fälle aus der Praxis...

> Wie programmiert man denn einen Mikroprozessor ohne Hauptprogramm?

Naja: Initialisierung, dann nur noch viele NOPs und ein RJMP PC.
Wenn du die Initialisierung als Teil des Hauptprogramm verstehst, dann 
ändere ich die Aussage besser in "ohne Hauptprogramm-Rumpf".

>> In dem Fall braucht man den Stackpointer nicht zu initialisieren,
>> natürlich sollte man dann das SRAM besser nicht verwenden – es wird
>> sonst lustig.
> Jo, und dei den Sprüngen in die ISR schreibt man sich irgendwann
> sukzessive die Arbeitsregsiter platt, weil die ganz unten im SRAM liegen
> und der Stackzeiger irgendwann überläuft und wieder unten ankommt. Super
> Deal.

Richtig, das hatte ich auch zuerst gedacht, aber es kommt auf die 
Implementierung der Hardware an. Bei allen mir bekannten AVRs z.B. ist 
es so, dass das Adressregister "SPH/SPL" nicht vollständig realisiert 
ist, das heißt, dass es erstens gar keine 16 Bit breit ist und zweitens 
die Zugriffsmöglichkeiten auf die ins SRAM gemappten Register gar nicht 
in Hardware umgesetzt wurden. Wozu auch? Wird ja für die normale 
Stack-Funktion nicht benötigt und kostet nur Platz auf dem Chip.

von Sven P. (Gast)


Lesenswert?

Markus Weber schrieb:
>> Wie programmiert man denn einen Mikroprozessor ohne Hauptprogramm?
>
> Naja: Initialisierung, dann nur noch viele NOPs und ein RJMP PC.
> Wenn du die Initialisierung als Teil des Hauptprogramm verstehst, dann
> ändere ich die Aussage besser in "ohne Hauptprogramm-Rumpf".
Joa. Die NOPS kann man sich dann aber auch sparen und man schreib in die 
ISR nur noch 'sei' und 'rjmp PC'.
Der Stack läuft dann aber dennoch zu, d.h. man hat faktisch keinen 
Arbeitsspeicher mehr.

Edit: Es sei denn, man poppt die Rücksprungadrese manuell herunter. Dann 
kann man sich die Spielerei aber auch schenken und mit ret/i ins (leere) 
Hauptprogramm springen.

>>> In dem Fall braucht man den Stackpointer nicht zu initialisieren,
>>> natürlich sollte man dann das SRAM besser nicht verwenden – es wird
>>> sonst lustig.
>> Jo, und dei den Sprüngen in die ISR schreibt man sich irgendwann
>> sukzessive die Arbeitsregsiter platt, weil die ganz unten im SRAM liegen
>> und der Stackzeiger irgendwann überläuft und wieder unten ankommt. Super
>> Deal.
>
> Richtig, das hatte ich auch zuerst gedacht, aber es kommt auf die
> Implementierung der Hardware an. Bei allen mir bekannten AVRs z.B. ist
> es so, dass das Adressregister "SPH/SPL" nicht vollständig realisiert
> ist, das heißt, dass es erstens gar keine 16 Bit breit ist
Der ATmega8 hat z.B. einen 11-Bit-Stackzeiger. Das reicht allemal, um 
die 96 Bytes Arbeitsregister/IO-Register plus 1kB SRAM 
durchzuadressieren (11 Bit = 2kB). Beim ATmega324 und ATmega128 ist der 
Stackzeiger dann 16 Bit breit, erreicht also das gesamte SRAM.

> und zweitens
> die Zugriffsmöglichkeiten auf die ins SRAM gemappten Register gar nicht
> in Hardware umgesetzt wurden. Wozu auch? Wird ja für die normale
> Stack-Funktion nicht benötigt und kostet nur Platz auf dem Chip.
Das Registerfile mit den 32 Arbeitsregistern liegt an den Adressen 
0x00..0x20. Danach kommen bis 0x60 die normalen IO-Register. Bei den 
neueren/größeren Typen kommen dann bis 0xFF die erweiterten IO-Register 
und ab da kommt das SRAM.

Im Datenblatt wird ausdrücklich beschrieben, dass alle 
Speicherstellen mit allen Adressierungsarten verwendet werden können. 
Das heißt insbesondere, du kannst die Arbeitsregister und alle 
IO-Register auch mit lds/sts bedienen. Es heißt außerdem, dass der 
Stackzeiger problemlos die IO- und Arbeitsregister plättet.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Sven P. schrieb:
> Joa. Die NOPS kann man sich dann aber auch sparen und man schreib in die
> ISR nur noch 'sei' und 'rjmp PC'.

Kann man. Die NOPs sind zur Optimierung da, weil sie nur einen 
CPU-Zyklus brauchen (RJMP braucht zwei). Während eines Befehls kann der 
Ablauf nicht per Interrupt unterbrochen werden. Das heißt, mit vielen 
NOPs hast du die Chance auf kürzere Reaktionszeiten der ISR.

Sven P. schrieb:
> Edit: Es sei denn, man poppt die Rücksprungadrese manuell herunter. Dann
> kann man sich die Spielerei aber auch schenken und mit ret/i ins (leere)
> Hauptprogramm springen.

Mit weniger Zyklen geht es, wenn man OUT SPL,rxx verwendet und so den SP 
immer wieder zurücksetzt. Aber –  wie schon gesagt – wenn man das SRAM 
nicht braucht, ist das Zurücksetzen nicht notwendig.

> Der ATmega8 hat z.B. einen 11-Bit-Stackzeiger. Das reicht allemal, um
> die 96 Bytes Arbeitsregister/IO-Register plus 1kB SRAM
> durchzuadressieren (11 Bit = 2kB). Beim ATmega324 und ATmega128 ist der
> Stackzeiger dann 16 Bit breit, erreicht also das gesamte SRAM.

Das mag stimmen, aber Register und IO-Bereich sind über den SP trotzdem 
nicht adressierbar, obwohl beide numerisch im Wertebereich des SP 
liegen. Es gibt auf dieser Relation schlicht keine Leitungen, über die 
die Daten dann fließen könnten.

> Das Registerfile mit den 32 Arbeitsregistern liegt an den Adressen
> 0x00..0x20. Danach kommen bis 0x60 die normalen IO-Register. Bei den
> neueren/größeren Typen kommen dann bis 0xFF die erweiterten IO-Register
> und ab da kommt das SRAM.

Völlig korrekt. Für die SP-Adressierung trotzdem nicht zugreifbar.

> Im Datenblatt wird ausdrücklich beschrieben, dass alle
> Speicherstellen mit allen Adressierungsarten verwendet werden können.
> Das heißt insbesondere, du kannst die Arbeitsregister und alle
> IO-Register auch mit lds/sts bedienen. Es heißt außerdem, dass der
> Stackzeiger problemlos die IO- und Arbeitsregister plättet.

Korrekt im Bezug auf LDS und STS. Für den Stackpointer gilt das aber 
nicht (siehe oben).

Denk dir nichts dabei, ich hab mich damals auch sehr gewundert, weil es 
auf den ersten Blick unlogisch erscheint. :-)
Letztlich ist es aber einfach nur wirtschaftlich, in der Hardware auf 
Adressierungsmöglichkeiten zu verzichten, die man im regulären Betrieb 
gar nicht braucht, die sogar schädlich sein können.

von Sven P. (Gast)


Lesenswert?

Markus Weber schrieb:
> Das mag stimmen, aber Register und IO-Bereich sind über den SP trotzdem
> [...]
Und das kannst du in irgendeiner Form belegen, oder basiert das nur 
auf Spekulationen und/oder deinen Versuchen?

Es ist sehr mutig, sich auf etwas zu verlassen, was nicht spezifiziert 
ist.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Sven P. schrieb:
> Und das kannst du in irgendeiner Form belegen, oder basiert das nur
> auf Spekulationen und/oder deinen Versuchen?

Ein Versuch ist doch der beste Beleg, den man liefern kann. Wie man 
sieht, ist das Ergebnis sogar ausführlicher als das Datenblatt. ;-)

Aus Konstruktionssicht ist das auch logisch nachvollziehbar. Warum 
sollte man auch etwas einbauen, was nicht genutzt wird...

Du brauchst diese praktische Eigenschaft der AVRs ja nicht zu nutzen, 
aber du solltest dich im Gegenzug auch nicht darauf verlassen, dass du 
per SP auf die Register zugreifen kannst, das klappt nämlich nicht.

von Sven P. (Gast)


Lesenswert?

Markus Weber schrieb:
> Du brauchst diese praktische Eigenschaft der AVRs ja nicht zu nutzen,
> aber du solltest dich im Gegenzug auch nicht darauf verlassen, dass du
> per SP auf die Register zugreifen kannst, das klappt nämlich nicht.
Das war auch andersherum gemeint:

Du darfst dich nämlich auch nicht darauf verlassen, dass der 
Stackzeiger die IO- und Arbeitsregister verschont. Das ist nämlich 
ebensowenig spezifiziert.


Edit: Das ist die Krux dabei, denn hier liefert ein praktischer Versuch 
keinen 'verwertbaren' Beleg. Irgendwann könnte sich Atmel z.B. 
überlegen, den Stackzeiger zu vervollständigen, sodass er IO- und 
Arbeitsregister erreicht. Aus welchen Gründen auch immer. Darf Atmel ja 
auch, denn es wurde nie Gegenteiliges spezifiziert und daher auch gehen 
keinerlei Inkompatibilitäten damit einher. Aber du als Entwickler, der 
sich auf ein Versuchsergebnis verlässt, landest dann auf der Nase...

Habe ich in dieser Form, nicht konkret bei AVRs, schon mehrfach erlebt. 
Sollte man nicht tun, auf unspezifizierte Eigenschaften zu bauen. Wer 
einen Z5U-Kondensator als frequenzbestimmendes Bauteil nimmt, nur weil 
er im Versuch herausgefunden hast, dass er um 0,1% vom Nennwert abweicht 
und damit sehr genau ist, ist auch selbst schuld wenns nachher knallt.

von (prx) A. K. (prx)


Lesenswert?

Markus Weber schrieb:
> Aus Konstruktionssicht ist das auch logisch nachvollziehbar. Warum
> sollte man auch etwas einbauen, was nicht genutzt wird...

Solche Eigenschaften ergeben sich oft als Nebeneffekt interner 
Strukturen von Bussen und Multiplexern. In diesem Fall könnte eine 
Optimierung des CALL Befehls dafür verantwortlich sein. Aufgrund der 
eigene Datenpfade von Adresse und Daten zum RAM bestehen könnten.

Zur Beschreibung einer möglichen AVR Mikroarchitektur siehe
http://web.engr.oregonstate.edu/~dambrosi/classes/cs271/Chapter4V4.pdf
Die Erklärung von IN und OUT ist m.E. fragwürdig, generell fehlen dort 
die I/O-Module, deren Adressierung und Datenpfade. Aber zur Sache mit SP 
und dessen Adressierung passt diese µArch.

Eine Veränderung der Mikroarchitektur kann so ein Verhalten ändern.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

In diesem Zusammenhang interessant: RCALL benötigt bei den normalen 
Megas/Tinys bis 64KW Flash 3 Takte, bei den Schrumpf-AVRs wie dem Tiny4 
aber 4 Takte. Diese Zwerge, wie auch die Xmegas mit 2 Takten bis 64KW, 
haben also eine im Ablauf anders arbeitende µArch, könnten sich also 
anders verhalten.

von Sven P. (Gast)


Lesenswert?

Markus Weber schrieb:
> [...]
Noch ausführlicher ist das Ticked beim Atmel-Support.

Zu finden bei Atmel unter Ticket#764174:
> >[...]
> >(1) Will the stack pointer overflow to some value when a value is popped
> >off the empty stack?
>
> Yes, the Stack pointer will be incremented(overflow) and will point to the
> location in the External SRAM please refer 'SRAM Data Memory' under AVR
> memories in the datasheet.
>
> >(2) When continuously pushing values onto the stack, will the stack
> >pointer eventually reach the I/O registers and the register file, possibly
> >overwriting, e.g. special function registers?
>
> Yes, when continuously the values are pushed onto the stack and the stack
> pointer is decremented and now it points to location in the extended I/
> O space where the peripheral registers resides.

von (prx) A. K. (prx)


Lesenswert?

Da steht nur, dass der SP darauf zeigt. Nicht aber, dass die Daten auch 
dort landen. Es ist auch vorstellbar, dass je nach Implementierung nicht 
die gepushten Daten, sondern irgendwelcher Schrott in den I/O-Registern 
landet, wenn nämlich die korrekten Daten nicht auf dem entsprechenden 
Bus liegen, sondern nur direkt am RAM. Undefined behaviour eben.

: Bearbeitet durch User
von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Sven P. schrieb:
> Noch ausführlicher ist das Ticked beim Atmel-Support.
>
> Zu finden bei Atmel unter Ticket#764174:

Danke, interessant! Das muss ich mir selber mal durchlesen. Kann gut 
sein, dass die dort gegebenen Antworten falsch sind.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Markus Weber schrieb:
> Sven P. schrieb:
>> Noch ausführlicher ist das Ticked beim Atmel-Support.
>>
>> Zu finden bei Atmel unter Ticket#764174:
>
> Danke, interessant! Das muss ich mir selber mal durchlesen. Kann gut
> sein, dass die dort gegebenen Antworten falsch sind.

Kannst du mir bitte einen Link dazu geben? Ich kann anscheinend nicht 
auf dieses Ticket zugreifen.

von Sven P. (Gast)


Lesenswert?

Ein letztes Mal, der Vollständigkeit halber:

A. K. schrieb:
> Da steht nur, dass der SP darauf zeigt. Nicht aber, dass die Daten auch
> dort landen.

Zweite Antwort auf mein Ticket bei Atmel:
> >When further pushing onto the stack, will the stack pointer also reach the
> >regular I/O space and the working register file (R0..R31)?
> >
> >
> >Furthermore, will the stack pointer not only point to those peripheral
> >registers but will it also overwrite them?
>
> Yes, on further pushing onto the stack, the stack pointer will reach the
> regular I/O space and will also overwrite them


Markus Weber schrieb:
> Kannst du mir bitte einen Link dazu geben? Ich kann anscheinend nicht
> auf dieses Ticket zugreifen.
Ich weiß nicht, ob du das überhaupt kannst, oder ob diese Tickets privat 
sind. In jedem Fall müsstest du dich bei Atmel anmelden.

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Hallo Sven, danke für deine Geduld. :-)

> Zweite Antwort auf mein Ticket bei Atmel:
>> >When further pushing onto the stack, will the stack pointer also reach the
>> >regular I/O space and the working register file (R0..R31)?
>> >
>> >
>> >Furthermore, will the stack pointer not only point to those peripheral
>> >registers but will it also overwrite them?
>>
>> Yes, on further pushing onto the stack, the stack pointer will reach the
>> regular I/O space and will also overwrite them

Scheint so, als wäre diese Auskunft von Atmel schlicht falsch. So wie es 
geschrieben steht, wäre ja mit Sicherheit davon auszugehen, dass genau 
das auch passiert. Das ist aber zumindest in den Fällen, die ich kenne, 
nicht der Fall.

> Ich weiß nicht, ob du das überhaupt kannst, oder ob diese Tickets privat
> sind. In jedem Fall müsstest du dich bei Atmel anmelden.

OK, klingt logisch. Vielleicht mache ich selbst ein Ticket auf und hake 
genauer nach. Die Tickets werden bei Atmel im Allgemeinen recht 
kompetent beantwortet, aber in diesem Fall gehts schon sehr in die 
Tiefe, so dass der Bearbeiter tief ins Design blicken muss.

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.