Forum: Compiler & IDEs Verständnisfrage zu Strings im SRAM


von UBoot-Stocki (Gast)


Lesenswert?

Hi,

Verständnisfrage:

Angenommen ich habe in einem Programm 10 Funktionen, die aus dem main() 
sequenziell aufgerufen werden. Z.B. so:
1
foo0();
2
foo1();
3
foo2();
4
foo3();
5
...
6
foo8();
7
foo9();
Dann wird doch der SRAM-Speicher während dem Aufruf einer Funktion 
belegt und an deren Ende wieder frei gegeben. Das ist doch richtig ?

Wie ist das nun mit Strings die innerhalb dieser 10 Funktionen benutzt 
werden wie z.B. ein Aufruf von uart_puttext("\n\rWert eingeben:"); in 
der Funktion foo1()

Werden diese Strings aus diesen Funktionen am Programmstart aus dem PROM 
in das SRAM kopiert oder wie funktioniert das ?

Oder ist es nicht viel eher so, dass Strings in Funktionen das SRAM nur 
zur Laufzeit der Funktion belegen (Kommen die auf den "Stack"?), d.h. 
insbesondere wird das SRAM danach wieder frei gegeben?

Wenn diese Vermutung stimmt, könnte man mit 20Byte-SRAM für Strings in 
obigem Beispiel 200 Zeichen darstellen .... ?

Wie ist das nun ?

Gruß

Andreas

von Stefan B. (stefan) Benutzerseite


Lesenswert?

UBoot-Stocki wrote:
> Angenommen ich habe in einem Programm 10 Funktionen, die aus dem main()
> sequenziell aufgerufen werden. Z.B. so:
>
1
> foo0();
2
> foo1();
3
> foo2();
4
> foo3();
5
> ...
6
> foo8();
7
> foo9();
8
>
> Dann wird doch der SRAM-Speicher während dem Aufruf einer Funktion
> belegt und an deren Ende wieder frei gegeben. Das ist doch richtig ?

Kann man so nicht bejahen oder verneinen. So wie du es geschrieben hast, 
wird kein SRAM benutzt. Wenn die Funktionen selbst was auf dem Stack 
ablegen, stimmt deine Vermutung.

> Wie ist das nun mit Strings die innerhalb dieser 10 Funktionen benutzt
> werden wie z.B. ein Aufruf von uart_puttext("\n\rWert eingeben:"); in
> der Funktion foo1()
> Werden diese Strings aus diesen Funktionen am Programmstart aus dem PROM
> in das SRAM kopiert oder wie funktioniert das ?

Ja. Die stehen vom ISP Programmieren her im FLASH-ROM und werden beim 
Programmstart in das SRAM in die Sektion BSS kopiert.

Wenn man schlau ist, lässt man die unveränderlichen Strings im FLASH-ROM
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Vereinfachung_f.C3.BCr_Zeichenketten_.28Strings.29_im_Flash

von Uboot- S. (uboot-stocki)


Lesenswert?

Stefan "stefb" B. wrote:
> UBoot-Stocki wrote:

>> Dann wird doch der SRAM-Speicher während dem Aufruf einer Funktion
>> belegt und an deren Ende wieder frei gegeben. Das ist doch richtig ?
>
> Kann man so nicht bejahen oder verneinen. So wie du es geschrieben hast,
> wird kein SRAM benutzt. Wenn die Funktionen selbst was auf dem Stack
> ablegen, stimmt deine Vermutung.

Naja, Register, Rücksprungadressen etc. werden da doch schon abgelegt. 
Wie ist das aber mit lokalen Variablen der Funktion? Wo kommen die denn 
hin? Und woin verschwinden die, wenn die Funktion Returnt ?

>> Wie ist das nun mit Strings die innerhalb dieser 10 Funktionen benutzt
>> werden wie z.B. ein Aufruf von uart_puttext("\n\rWert eingeben:"); in
>> der Funktion foo1()
>> Werden diese Strings aus diesen Funktionen am Programmstart aus dem PROM
>> in das SRAM kopiert oder wie funktioniert das ?
>
> Ja. Die stehen vom ISP Programmieren her im FLASH-ROM und werden beim
> Programmstart in das SRAM in die Sektion BSS kopiert.
>
> Wenn man schlau ist, lässt man die unveränderlichen Strings im FLASH-ROM
> 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Vereinfachung_f.C3.BCr_Zeichenketten_.28Strings.29_im_Flash

Ja, das ist klar. Mir gehts ums Verständnis ...

Gruß und Danke

Andreas

von Simon K. (simon) Benutzerseite


Lesenswert?

Ok.

Folgendes:
1
void fooX(void)
2
{
3
    char sText[20] = "19Zeichenlangertext...";
4
5
    printf(sText);
6
}

belegt 20Byte Stack. Schließlich wird die Variable mit dem String auf 
dem Stack erzeugt.
Die Variable wird also bei jedem Funktionsaufruf mit diesem String 
initialisiert.
1
void fooX(void)
2
{
3
    printf("19Zeichenlangertext...");
4
}

belegt 20Byte RAM. Und zwar für immer, da der String zu Programmstart 
aus dem ROM in das RAM befördert wird.

Ich hoffe so keinen Unsinn erzählt zu haben.

von Günther Kreischer (Gast)


Lesenswert?

Hallo,

die lokalen Variablen werden normalerweise auf dem Stack angelegt d.h. 
der Stackpointer wird mit der entsprechenden Größe der Variablen 
subtrahiert um Platz für die Variable zu schaffen. Am Ende der Funktion 
wird die Größe/Size der Variable wieder aufaddiert. Die Variable 
verschwindet so automatisch.

Je nach Größe der Variable kann der Optimizer die Variable auch in ein 
oder mehrere Register verschieben. Bei einem String ist das eher 
unwahrscheinlich.

Ciao

von Simon K. (simon) Benutzerseite


Lesenswert?

Günther Kreischer wrote:
> Hallo,
>
> die lokalen Variablen werden normalerweise auf dem Stack angelegt d.h.
> der Stackpointer wird mit der entsprechenden Größe der Variablen
> subtrahiert um Platz für die Variable zu schaffen. Am Ende der Funktion
> wird die Größe/Size der Variable wieder aufaddiert. Die Variable
> verschwindet so automatisch.
>
> Je nach Größe der Variable kann der Optimizer die Variable auch in ein
> oder mehrere Register verschieben. Bei einem String ist das eher
> unwahrscheinlich.
>
> Ciao

Danke für die tausendste Erklärung, aber das weiß UBoot-Stocki doch.

Ihm gehts darum, dass wenn er einen Aufruf ala
> uart_puttext("\n\rWert eingeben:");
macht, Speicher reserviert wird. Aber von wo!

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Simon K. wrote:
> Ihm gehts darum, dass wenn er einen Aufruf ala
>> uart_puttext("\n\rWert eingeben:");
> macht, Speicher reserviert wird. Aber von wo!

"\n\rWert eingeben:" steht zunächst im FLASH-ROM. Beim Programmstart 
wird der String in die DATA (oben hatte ich das ASM-Listing falsch 
gelesen, sorry) Sektion des SRAM kopiert. Beim Funktionsaufruf wird ein 
Pointer auf den String in DATA übergeben. Wenn der String in der 
Funktion manipuliert wird (also nicht implizit const ist), wird eine 
Kopie auf dem Stack angelegt.

> void fooX(void)
> {
>    char sText[20] = "19Zeichenlangertext...";

"19Zeichenlangertext..." steht zunächst im FLASH-ROM. Beim Programmstart 
wird der String in die DATA Sektion des SRAM kopiert. In fooX() wird 
eine Kopie des Strings auf dem Stack angelegt.

von Simon K. (simon) Benutzerseite


Lesenswert?

Alles Klar, wieder was gelernt :-)

Es lohnt sich in jedem Falle die Sachen im Progmem zu belassen und über 
die pgm_read_* Makros zu lesen.

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.