Forum: Mikrocontroller und Digitale Elektronik ATmega328P: Höchste mögliche Adresse vom Stackpointer?


von Thomas T. (knibbel)


Lesenswert?

Hallo,

der Atmega328P hat einen "Internal SRAM"-Bereich von 2k, der von 0x0100 
bis 0x08FF reicht (2048 Bytes lang). Das ist auch in der entsprechenden 
Include-Datei unter RAMEND = 0x08FF genau so definiert.

Wenn ich mir nun im Datenblatt unter "Register Summary" das SPH- (und 
das SPL-) Register ansehe, dann haben die zusammen eine Breite von 11 
Bit. Das bedeutet, dass die höchste Adresse (bzw. nur das High-Byte 
betrachtet), die SPH aufnehmen kann, eine 0x07 ist. Also die höchste 
Adresse ist die 0x07FF.

Nochmal in Kurzform: SPH ist 3 Bit breit: Höchste darstellbare Zahl: 
0x07.

Wenn ich jetzt aber den Stackpointer auch auf das RAM-Ende setzen kann, 
dann brauche ich in SPH noch ein viertes Bit, d.h. das Datenblatt ist 
fehlerhaft.

Oder übersehe ich etwas?

Gruß,
Thomas

: Gesperrt durch Moderator
von (prx) A. K. (prx)


Lesenswert?

Thomas T. schrieb:
> d.h. das Datenblatt ist fehlerhaft.

Jau. Guckst Du in 7.5.1, da steht die relevante Inforation.

von chris (Gast)


Lesenswert?

der sram beginnt bei 100hex plus 7ff ist 8ff

siehe db seite 19 da ist es eindeutig erklärt

von c-hater (Gast)


Lesenswert?

Thomas T. schrieb:

> Nochmal in Kurzform: SPH ist 3 Bit breit: Höchste darstellbare Zahl:
> 0x07.
>
> Wenn ich jetzt aber den Stackpointer auch auf das RAM-Ende setzen kann,
> dann brauche ich in SPH noch ein viertes Bit, d.h. das Datenblatt ist
> fehlerhaft.

Nun, der Stackpointer ist groß genug, um den gesamten RAM addressieren 
zu können, das genügt prinzipiell.

Der Rest wird sicher per wrap-around-Mathematik erledigt. Die Frage ist 
nur, ob der Programmierer sich darum kümmern muß oder ob es die Hardware 
tut. Ich würde mal auf letzteres tippen, sonst hätte in der Anmerkung 
zum SPH-Register sicher etwas dazu gestanden.

Mit minimaler Eigeninitiative läßt sich das allerdings auch sehr einfach 
selbst herausfinden:

 cbi TESTPORT,TESTBIT  ;für TEST-LED zwischen Pin und GND
 sbi TESTDDR,TESTBIT

 ldi R16,Low(RAMEND)
 ldi R17,High(RAMEND)
 out SPL,R16
 out SPH,R17
 push R17
 push R16
 lds R16,RAMEND-1
 pop R17
 sub R16,R17
 lds R16,RAMEND
 pop R17
 sbc R16,R17
 brne stop
 sbi TESTPORT,TESTBIT

stop:
 rjmp stop

Wenn die LED leuchtet, kümmert sich mit sehr hoher Wahrscheinlichkeit 
die Hardware darum...

von Thomas T. (knibbel)


Lesenswert?

c-hater schrieb:
> Nun, der Stackpointer ist groß genug, um den gesamten RAM addressieren
> zu können, das genügt prinzipiell.
>
> Der Rest wird sicher per wrap-around-Mathematik erledigt.

Dein erster Satz ist definitiv falsch, wenn man sich nur auf das 
"Register Summary" bezieht: Dort hat der Stack 11 Bit und das reicht 
nicht aus!

Es wird auch nichts per irgendwelcher wrap-around-Mathematik gerechnet. 
Vielmehr scheint es wohl wirklich so zu sein, dass SPH mehr Bits hat, 
als im "Register Summary" vermerkt.

Ich habe mal auf die schnelle Folgendes probiert:

  LDI r16,$xx
  OUT SPH,r16
  NOP
  IN  r16, SPH
  OUT Port,r16

Also nacheinander SPH mit 0x01, 0x02, 0x04, 0x08, 0x10 und 0x20 geladen, 
den Wert in SPH wieder ausgelesen und auf einen Port ausgegeben.

Dabei ist im unteren Nibble alles in Ordnung, es werden alle vier 
unteren Bits korrekt ausgegeben, ab 0x10 ist der Port durchweg 0x00.

Das beweist wohl deutlich, dass im "Register Summery" auf Seite 624 das 
unbelegte Bit 3 vom SPH falsch markiert ist und eigentlich SP11 heißen 
sollte. Damit wären 12 Bits verfügbar und dann ist die Welt auch wieder 
in Ordnung...

Gruß,
Thomas

: Bearbeitet durch User
von Georg G. (df2au)


Lesenswert?

Im Text findet man
The AVR Stack Pointer is implemented as two 8-bit registers in the I/O 
space. The number of bits actually used is implementation dependent. 
Note that the data space in some implementations of the AVR architecture 
is so small that only SPL is needed. In this case, the SPH Register will 
not be present.

Herrlich mehrdeutig alles. Es gilt wie so oft: Sobald man weiß, wie es 
funktioniert, interpretiert man auch das Datenblatt richtig.

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


Lesenswert?

Georg G. schrieb:
> Herrlich mehrdeutig alles.

Manche Softwerker sagen, die beste Dokumentation sei immer der 
Quellcode. Das darf man wohl auch für Hardware sagen: Egal was im 
Datasheet steht, als eigentliche relevante Dokumentation taugt nur der 
VHDL/Verilog Quellcode, ersatzweise die reale Hardware.

Spannend wärs jetzt, das bei verschiedenen Typen einer Familie mal zu 
testen. Also die Mega48/88/168/328 mit 0,5/1/2 KB RAM. Ob da jede RAM 
Grösse genau ihre spezifischen SPH Bits hat, oder ob welche mit mehr 
Bits als RAM dabei sind.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Thomas T. schrieb:

> Dein erster Satz ist definitiv falsch, wenn man sich nur auf das
> "Register Summary" bezieht: Dort hat der Stack 11 Bit und das reicht
> nicht aus!

Natürlich reicht das aus. 11 Bit können 2^11 Adressen ansprechen. Wenn 
du das mal in irgendeinen vergurkten Taschenrechner eingibst, dann kommt 
was raus?

...2048

Und wie groß ist das SRAM eines Mega328P? 2048 Bytes. Was für ein 
Zufall...

> Es wird auch nichts per irgendwelcher wrap-around-Mathematik gerechnet.

Du bist definitiv ein Nixwisser/Nixkönner. Das allein ist noch nix 
Schlimmes, denn schließlich hat absolut jeder mal so angefangen. Auch 
ich übrigens.

Aber Unwissend/Unfähig und dann noch stolz darauf, das geht garnicht...

von (prx) A. K. (prx)


Lesenswert?

c-hater schrieb:
> Du bist definitiv ein Nixwisser/Nixkönner.

Es würde dir sicherlich etwas helfen, nicht nur schreiben, sondern auch 
lesen zu lernen. Die Oberkante des RAMs liegt bei AVRs bekanntlich 
oberhalb der 2K Grenze des Datenadressraums, weil darunter die Register 
und der I/O Bereich liegen. Was hier im Thread auch anfangs klar 
geschrieben steht.

: Bearbeitet durch User
von H.Joachim S. (crazyhorse)


Lesenswert?

Das hast du jetzt aber nett gesagt :-)

von chris (Gast)


Angehängte Dateien:

Lesenswert?

Thomas T. schrieb:
> Dein erster Satz ist definitiv falsch, wenn man sich nur auf das
> "Register Summary" bezieht: Dort hat der Stack 11 Bit und das reicht
> nicht aus!

doch das reicht dicke denn du vergisst die verdammte 0, sp0-sp10 sind 
und bleiben 11 bit.

0-9 = 10 Ziffern

unter 8.3 findest du ein simples bild welches es nochmal verdeutlicht wo 
der Ram anfängt und aufhört.

von Thomas T. (knibbel)


Lesenswert?

c-hater schrieb:
> Thomas T. schrieb:
>
>> Dein erster Satz ist definitiv falsch, wenn man sich nur auf das
>> "Register Summary" bezieht: Dort hat der Stack 11 Bit und das reicht
>> nicht aus!
>
> Natürlich reicht das aus. 11 Bit können 2^11 Adressen ansprechen. Wenn
> du das mal in irgendeinen vergurkten Taschenrechner eingibst, dann kommt
> was raus?
>
> ...2048
>
> Und wie groß ist das SRAM eines Mega328P? 2048 Bytes. Was für ein
> Zufall...
>
>> Es wird auch nichts per irgendwelcher wrap-around-Mathematik gerechnet.
>
> Du bist definitiv ein Nixwisser/Nixkönner. Das allein ist noch nix
> Schlimmes, denn schließlich hat absolut jeder mal so angefangen. Auch
> ich übrigens.
>
> Aber Unwissend/Unfähig und dann noch stolz darauf, das geht garnicht...

Passendes Beispiel eines Dunning-Kruger-Effekts ...

Diskussion ist bei diesem Niveau sinnlos.

Kein weiterer Text,
Thomas

von (prx) A. K. (prx)


Lesenswert?

chris schrieb:
> doch das reicht dicke denn du vergisst die verdammte 0, sp0-sp10 sind
> und bleiben 11 bit.

SP adressiert den Datenspeicher, nicht direkt das RAM-Array und wird 
deshalb qua Datasheet auf RAMEND initialisiert.

RAMEND = 0x08FF = 0000.1000.1111.1111
                       xxxx xxxx xxxx = 12 Bits

von chris (Gast)


Lesenswert?

A. K. schrieb:
> SP adressiert den Datenspeicher, nicht direkt das RAM-Array und wird
> deshalb qua Datasheet auf RAMEND initialisiert.
>
> RAMEND = 0x08FF = 0000.1000.1111.1111
>                        xxxx xxxx xxxx = 12 Bits

das ist ja richtig. die frage war aber warum der stack bei 8ff aufhört 
und nicht bei 7ff und wenn man sich das bild nur bezogen auf das sram 
anschaut und mal kurz durchrechnet kommt man auf die 7ff und somit 
brauch sph auch nur bis 0x07 "zählen".

von H.Joachim S. (crazyhorse)


Lesenswert?

Eben nicht. Der SP kann auch den I/O-Bereich und die Register 
adressieren. Sinnvoll ist das eher nicht, aber es ist so (zumindest war 
es bei den frühen AVRs so, und ich denke nicht, dass da was geändert 
wurde).
Lustige Sachen, wenn der stack in den Bereich wächst :-)

von (prx) A. K. (prx)


Lesenswert?

chris schrieb:
> brauch sph auch nur bis 0x07 "zählen".

Herrje. SP adressiert den Datenadressraum, ohne Adder, Offset oder 
irgendwelche Tricks. Nicht das SRAM Array. Deshalb steht anfangs 0x8FF 
drin und nicht 0x7FF. Und nun erzähl mir bitte, wie du den Wert 0x8FF in 
ein Register kriegst, das nur die unteren 11 Bits implementiert.

Klar liesse sich das anders machen. Atmel hätte zum SP jedes Mal 0x100 
dazu addieren können, bevor damit das RAM angesprochen wird. Machen sie 
aber nicht.

von (prx) A. K. (prx)


Lesenswert?

H.Joachim Seifert schrieb:
> Eben nicht. Der SP kann auch den I/O-Bereich und die Register
> adressieren.

Hat das eigentlich mal jemand ausprobiert? Also SP=0x000F 
beispielsweise, und dann zusehen, wie der Stack in R15 abwärts schreibt.

von chris (Gast)


Lesenswert?

ich seh es grade im simulator, dass das sph 4bit breit ist, war zu sehr 
auf den sp fixiert und die untere adressieung ausser acht gelassen.

soll i ma probiern?

von (prx) A. K. (prx)


Lesenswert?

Ein Simulator simuliert nominelles, nicht reales Verhalten. Es ist also 
nicht gewährleistet, dass sich der Simulator dabei wie die Hardware 
verhält.

von chris (Gast)


Lesenswert?

zumindest macht er es so wie du es beschrieben hast, fehlt halt 
vielleicht ne anwendung wo man dieses gebrauchen kann bzw mir fällt 
gerade nix ein 0.o

von der alte Hanns (Gast)


Lesenswert?

Um auch etwas zu dieser ulkigen Diskussion beizutragen:

> jemand ausprobiert?
Also meinen einzigen 328P reisse ich nicht aus seiner Umgebung, aber mit 
einem alten 168 geht es nicht, nachfolgendes Programm liefert an D 00.

.include "m168def.inc"
.def  tmp0  = r16
.org 0
  ldi  tmp0,$FF
  out  DDRD,tmp0
  ldi  tmp0,0
  out  SPH,tmp0
  ldi  tmp0,15
  out  SPL,tmp0
  ldi  tmp0,$A5
  push tmp0
  out  PORTD,r15
  rjmp  pc

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


Lesenswert?

chris schrieb:
> zumindest macht er es so wie du es beschrieben hast, fehlt halt
> vielleicht ne anwendung wo man dieses gebrauchen kann bzw mir fällt
> gerade nix ein 0.o

"Wir haben die Lösung! Jetzt suchen wir noch nach dem zugehörigen 
Problem." :-)

Es gibt tatsächlich Fälle, da will man den SP in einem Adressbereich 
haben, in dem er das RAM nicht beschreiben kann:
man benötigt das komplette RAM für Variablen oder als Puffer und man 
verwendet Interrupts.

Das ist aber schon arg speziell und wirklich selten.

von Thomas T. (knibbel)


Lesenswert?

Markus Weber schrieb:
> Es gibt tatsächlich Fälle, da will man den SP in einem Adressbereich
> haben, in dem er das RAM nicht beschreiben kann:
> man benötigt das komplette RAM für Variablen oder als Puffer und man
> verwendet Interrupts.

Dann lege ich mir den Stackpointer auf die unteren (hoffentlich nicht 
benutzten) Register und kann weiterhin Unterprogramme oder Interrupts 
benutzen...

Das könnte tatsächlich funktionieren. Ist aber etwas bizarr...

Gruß,
Thomas

von (prx) A. K. (prx)


Lesenswert?

Thomas T. schrieb:
> Das könnte tatsächlich funktionieren. Ist aber etwas bizarr...

Könnte wohl, tuts aber nicht, siehe grad eben 20:09.

Ist eine Frage der internen Busse bzw. Muxer. Wenn SP per Muxer direkt 
an den Adressen vom RAM hängt, dann geht das nicht. Dann wärs sogar 
denkbar, dass die geschriebenen 0xA5 an der Adresse 0x80F gelandet sind.

Im Simulator hingegen gehts. Siehe 19:41. Soviel zum Verhalten von 
Simulatoren ausserhalb ihres vorgesehenen Einsatzzwecks.

: Bearbeitet durch User
von der alte Hanns (Gast)


Lesenswert?

Wohingegen dieses:

  ldi  tmp0,$FF
  out  DDRD,tmp0
  ldi  tmp0,$00
  out  SPH,tmp0
  ldi  tmp0,15
  out  SPL,tmp0
  ldi  tmp0,$A5
  clr  r15
  push  tmp0
  pop  r15
  out  PORTD,r15

das $A5 auf D bringt; wo, bitte, wurde der Wert gespeichert?

(Oder liegt es am 168, date-code 0452?)

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


Lesenswert?

Thomas T. schrieb:
> Markus Weber schrieb:
> Dann lege ich mir den Stackpointer auf die unteren (hoffentlich nicht
> benutzten) Register und kann weiterhin Unterprogramme oder Interrupts
> benutzen...
>
> Das könnte tatsächlich funktionieren. Ist aber etwas bizarr...

Ja, schon etwas arg speziell. :-)

Die in den Adressbereich gemappten Register sind per SP übrigens nicht 
beschreibbar. Das ist allerdings nur durch praktische Versuche 
nachgewiesen, das Datenblatt schweigt sich dazu aus. Also vor dem 
Verwenden besser selber prüfen, es gibt keine Garantie dafür, dass es 
auf bei zukünftigen AVR so sein wird.

Interrupts lassen sich zwar verwenden, aber man sollte dann besser kein 
Hauptprogramm haben, das an der Unterbrechungsstelle fortgesetzt werden 
muss, diese Adresse geht nämlich verloren. Meine Anwendung war damals 
allein ereignisgesteuert und bestand nur aus Interrupt-Routinen 
(einschließlich Timer-Interrupts).

Unterprogrammaufrufe gehen, aber halt ohne Stack. Das heißt, man muss 
die Rücksprungadresse in ein Register legen. -> Makros zcall und zret.
Reicht für eine Unterprogrammebene, Verschachtelungen müssen manuell 
behandelt werden.

Wie gesagt, schon arg speziell und eher von wissenschaftlicher als von 
praktischer Bedeutung.

von (prx) A. K. (prx)


Lesenswert?

der alte Hanns schrieb:
> das $A5 auf D bringt; wo, bitte, wurde der Wert gespeichert?

Guck mal ins RAM. An Adresse 0x80F, oder 0x40F bei 1KB RAM. Wenn SP 
direkt am Adressmuxer vom RAM hängt und nicht dekodiert wird, weil bei 
den Typen ohne Support für externes RAM unnötig, dann landet das Byte 
genau dort.

: Bearbeitet durch User
von der alte Hanns (Gast)


Lesenswert?

Nein, auf Ihren Hinweis hin hatte ich schon unter $80F nachgeschaut, 
dort steht $00, ebenso $40F.

von (prx) A. K. (prx)


Lesenswert?

Dann käme noch ein floatender Datenbus in Frage, dessen Kapazität den 
Wert hält. Mach zwischen PUSH und POP mal was mit RAM, an einer 
existierenden Adresse und einem anderen Wert.

von der alte Hanns (Gast)


Lesenswert?

Treffer!
Nachfolgendes bringt $00:

  ldi  tmp0,$FF
  out  DDRD,tmp0
  ldi  tmp0,$00
  out  SPH,tmp0
  ldi  tmp0,15
  out  SPL,tmp0
  ldi  tmp0,$A5
  clr  r15
  push  tmp0

  ldi  tmp0,$66
  sts  $400,tmp0
  clr  ZH
   sbiw  ZL,1
  brne  pc-1

  pop  r15
  out  PORTD,r15
  rjmp  pc

Jetzt allerdings verabschiede ich mich, zumal mein alter 168 von vor 10 
Jahren sicher keine Rückschlüsse auf heutige Versionen erlaubt.

von der alte Hanns (Gast)


Lesenswert?

Da hatte ich Sie wohl falsch verstanden, also Nachtrag:
nur
  ldi  tmp0,$66
  sts  $400,tmp0

also ohne diese Zeitschleife bringt tatsächlich $66.

Treffer - versenkt !

von (prx) A. K. (prx)


Lesenswert?

der alte Hanns schrieb:
> zumal mein alter 168 von vor 10
> Jahren sicher keine Rückschlüsse auf heutige Versionen erlaubt.

Weshalb sollte sich da viel verändert haben? AVR hat seither zwar ein A 
und ein P dran gehängt, was mit Herstellungsprozess und Stromverbrauch 
zu tun hat, aber am Core hat sich m.W. nichts geändert. Das sind keine 
x86er.

Danke für die Bemühungen!

: Bearbeitet durch User
von der alte Hanns (Gast)


Lesenswert?

Da scheinen Sie der Fachmann zu sein, zu meinem Gebiet gehört dies 
nicht.
Aber ein wirklich merkwürdiges Verhalten.
Und wenn mir wieder einmal etwas spanisch vorkommt, werde ich mit 
doppeltem Eifer den Fehler in meinem Programm suchen - insofern konnte 
ich doch noch Nutzen aus dieser ulkigen Diskussion ziehen.

von MCUA (Gast)


Lesenswert?

> zumal mein alter 168 von vor 10
> Jahren sicher keine Rückschlüsse auf heutige Versionen erlaubt.
Doch, das ist ja das schlimme.

von H.Joachim S. (crazyhorse)


Lesenswert?

Ich grabe morgen mal paar Schätzchen aus der 90er Serie aus, da liegt 
noch irgendwo was rum. Ich bin mir ziemlich sicher, dass man den unteren 
Bereich damit schreiben und lesen kann.

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


Lesenswert?

H.Joachim Seifert schrieb:
> Ich grabe morgen mal paar Schätzchen aus der 90er Serie aus, da liegt
> noch irgendwo was rum. Ich bin mir ziemlich sicher, dass man den unteren
> Bereich damit schreiben und lesen kann.

Per SP die Register lesen? Das wär interessant! Vielleicht geh ich auch 
mal suchen.

von H.Joachim S. (crazyhorse)


Lesenswert?

Ich habe noch einen 4414 von 1997 gefunden...
Aber mit dem neuen AVR-Studio 6.2 gibts den beim STK500 gar nicht mehr.

von Bitflüsterer (Gast)


Lesenswert?

Ähm, habe ich das richtig verstanden, dass man per push/pop mit SP < 
0x100 nicht in die Register schreibt, sondern in einen sozusagen im 
Schatten dahinterliegenden Datenbereich? Und das das nicht bei allen 
Typen gleich ist?

Wäre vielleicht jemand so nett, das mal zusammenfassend darzustellen? 
Das würde mich freuen.

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


Lesenswert?

Bitflüsterer schrieb:
> Ähm, habe ich das richtig verstanden, dass man per push/pop mit SP <
> 0x100 nicht in die Register schreibt, sondern in einen sozusagen im
> Schatten dahinterliegenden Datenbereich?

Richtig, damit schreibst du ins Controller-eigene WOM 
(Write-Only-Memory). :-)

> Und das das nicht bei allen
> Typen gleich ist?

Ich kenne nur AVR, bei denen das so ist. Da sich das Datenblatt aber 
nicht darüber auslässt, ist es natürlich nicht ganz auszuschließen, dass 
es auch AVR gibt, bei denen man über diesen Weg die Register beschreiben 
kann.

von (prx) A. K. (prx)


Lesenswert?

Bitflüsterer schrieb:
> Ähm, habe ich das richtig verstanden, dass man per push/pop mit SP <
> 0x100 nicht in die Register schreibt, sondern in einen sozusagen im
> Schatten dahinterliegenden Datenbereich?

Nein. PUSH schreibt auf einen Bus, auf dem niemand hört. Das RAM nicht, 
weil ausserhalb seines Adressraums. Und die Register nicht, vielleicht 
weil es nicht ihr Bus ist und sie das überhaupt nicht mitbekommen.

Wenn darauf der POP Befehl folgt, dann findet er ebenso keinen 
Ansprechpartner. Der Bus bleibt offen, tri-stated. Wenn zwischendrin 
sonst nichts auf dem Bus los war, dann liegt noch ein Weilchen der alte 
Wert drauf. Kurzzeitig in den Leitungs- und Gatekapazitäten gespeichert. 
Und das ist es, was der POP Befehl liest.

Wenn dazwischen viel Zeit vergeht, dann ist diese Ladung abgebaut und es 
kommt nichts sinnvolles an.

Wenn ein anderer Befehl des Bus unmittelbar vor dem POP nutzte (STS 
oben), dann steht der Wert davon drauf und POP kriegt die 0x66.

Wer Lust am Experimentieren hat, der kann diese These mal ausprobieren, 
indem er die Wartezeit zwischendrin sukzessive erhöht bis sich der Wert 
ändert. Dieser Code darf natürlich den Bus nicht verwenden, da muss man 
ggf. etwas experimentieren. NOPs dürften sicher sein.

: Bearbeitet durch User
von Bitflüsterer (Gast)


Lesenswert?

Markus Weber schrieb:
> Richtig, damit schreibst du ins Controller-eigene WOM
> (Write-Only-Memory). :-)

Danke für die Antwort.

Der Scherz verunsichert mich ein wenig. Ist es so, das ein Wert der in 
Adressen < 0x100 per PUSH geschrieben wird, zwar nicht in einem Register 
landet, aber auch nicht per POP wieder hervorgeholt werden kann?

von H.Joachim S. (crazyhorse)


Lesenswert?

Hm, ich bekomme die alten Teile nicht mehr programmiert. Weder über 
STK500, Dragon oder ISP MKII.

von (prx) A. K. (prx)


Lesenswert?

Bitflüsterer schrieb:
> Der Scherz verunsichert mich ein wenig. Ist es so, das ein Wert der in
> Adressen < 0x100 per PUSH geschrieben wird, zwar nicht in einem Register
> landet, aber auch nicht per POP wieder hervorgeholt werden kann?

Doch, unmittelbar darauf eben schon. Das hatte ja Hanns irritiert: 
Beitrag "Re: ATmega328P: Höchste mögliche Adresse vom Stackpointer?"

Das ist sozusagen wie DRAM, gespeichert in Kapazitäten. Nach einer Weile 
isser weg, der Inhalt. Jedes DRAM wird auf Dauer zum WOM, nur kann das 
u.U. Sekunden oder gar Minuten dauern.

: Bearbeitet durch User
von der alte Hanns (Gast)


Lesenswert?

an crazyhorse

Ein AT90S4433-8PI von 0045 zeigt dasselbe Verhalten, d.h.
.include "4433def.inc"
.def  tmp0  = r16
.org 0
  ldi  tmp0,$FF
  out  DDRD,tmp0
  ldi  tmp0,15
  out  SP,tmp0
  ldi  tmp0,$A5
  clr  r15
  push  tmp0
  out  PORTD,r15
  rjmp  pc

bringt $00, wird jedoch zwischen push und out ein

  pop  r15

zwischengeschaltet, so erscheint $A5.
Gleiches Verhalten mit angepasstem Programm bei einem AT90S8515-8PI von 
9825.


an prx

Mit diesem pop r15 kann ich beliebig viele nops vorschalten, es kommt 
immer $A5; Randbedingung: mega168, 5.0 V, 1 MHz:
8000 nops --> der Bus hält die Information mindestens 8 ms.

von Axel S. (a-za-z0-9)


Lesenswert?

Ich finde es übrigens sinnvoll, daß PUSH und POP nicht den gesamten 
Datenadreßbereich ansprechen können, sondern nur den Teil, der mit RAM 
hinterlegt ist. Sonst würden Amok laufende Programme (Stacküberlauf) 
unkontrolliert I/Os überschreiben.

Die indirekten Ladebefehle LD ... mit der Adresse in X, Y oder Z haben 
diese Einschränkung nicht. Mit denen kann man ohne Unterschied Register, 
I/O Register und RAM lesen und schreiben. Bei manchen Typen sogar das 
Flash lesen.


XL

von Stefan (Gast)


Lesenswert?

Geil, der ATmega hat ein DRAM :-))

Vielleicht kann man ja damit so eine Art "Recht auf Vergessen" im 
Firmwarebereich (Google light) einbauen ...

Gruß, Stefan

von der alte Hanns (Gast)


Lesenswert?

> "Recht auf Vergessen"

Das haben wir ja bereits, "Data retention: 20 years at 85°C/ 100 years 
at 25°C".

von (prx) A. K. (prx)


Lesenswert?

der alte Hanns schrieb:
> Mit diesem pop r15 kann ich beliebig viele nops vorschalten, es kommt
> immer $A5; Randbedingung: mega168, 5.0 V, 1 MHz:
> 8000 nops --> der Bus hält die Information mindestens 8 ms.

Also doch kein DRAM. Schade. ;-)

Diesem Effekt war ich allerdings schon vor Jahrzehnten bei anderen 
Rechnern begegnet, also eine solche kapazitive Speicherung gibt es.

Es sind auch andere Modelle für das Verhalten vorstellbar.

Beitrag #6629753 wurde von einem Moderator gelöscht.
Beitrag #6629881 wurde von einem Moderator gelöscht.
Dieser Beitrag ist gesperrt und kann nicht beantwortet werden.