Forum: Compiler & IDEs AVR, Heap - Variablen jenseits RAM-Grenze?


von Ludwig M. (laludelala)


Lesenswert?

Hallo!

Ich arbeite an einer MMC/FAT Implementierung, und beisse mir gerade die 
Zähne aus.

Ich habe einen Atmel ATMega16 laufen, der Debugmeldungen über die 
Serielle gibt.


Ich definiere einen Haufen globaler Variablen, die alle artig im 
Objektfile angelegt sind. Ihr Ende (_end in Symboltabelle) ist an 
Adresse 0x80028f. Von den 1kB SRAM, die ich zur Verfügung habe, bleiben 
also 0x400-0x28f = 369 Bytes für Heap und Stack zur Verfügung.


Jetzt definiere ich in main() einige Variablen, die ja eigentlich auf 
dem Heap, also ab Stelle 0x28f im RAM, angelegt werden sollten:
1
int     main(void)
2
{
3
uint16_t        cluster = 0;
4
int32_t         counter = 0;
5
uint8_t buf[60];
6
7
[... versch. Initialisierungsgeschichten, unwichtig ...]
8
uart_puts(PSTR("\n\rAdresse von cluster: "));
9
uart_puts_R(ltoa(&cluster, buf, 10));
10
uart_puts(PSTR("\n\r\n\r"));
11
12
[... usw. usf. ...]
13
}


jetzt liefert mir dieses kleine Programmcodebeispiel ein
1
Adresse von cluster: 1058



Lasse ich mir die Adresse von einer globalen Variable ausgeben, so 
stimmt diese mit der Adresse aus der Symboltabelle überein.





Ich frage mich, wieso denn die erste Variable von main, die eigentlich 
DIREKT hinter dem Stack kommen soll, an eine Adresse jenseits der 
Speichergrenze angelegt wird!




Zum Compilieren rufe ich auf (Zeile 658 ist die oben aufgeführte imt 
"ltoa" - wenn ich dort richtig caste, ändert sich am Ergebnis Nix - 
1058):
1
ludwig@client14:~/uni/HS/studarb/fat$ make clean avrfat
2
rm -f *.o *.out *.map *.hex
3
avr-gcc -g -mmcu=atmega16 -O0 -Wall  -c avrfat.c
4
In file included from avrfat.c:43:
5
mmc.c: In function MMC_Write:
6
mmc.c:276: warning: passing argument 1 of ltoa makes integer from pointer without a cast
7
avrfat.c: In function getDirEntry:
8
avrfat.c:289: warning: pointer targets in passing argument 1 of uart_puts_R differ in signedness
9
avrfat.c: In function getDataDir:
10
avrfat.c:306: warning: pointer targets in passing argument 1 of uart_puts_R differ in signedness
11
avrfat.c:313: warning: pointer targets in passing argument 1 of uart_puts_R differ in signedness
12
avrfat.c: In function writeDirEntry:
13
avrfat.c:338: warning: pointer targets in passing argument 1 of uart_puts_R differ in signedness
14
avrfat.c: In function FatInit:
15
avrfat.c:585: warning: unused variable ch
16
avrfat.c: In function main:
17
avrfat.c:658: warning: passing argument 1 of ltoa makes integer from pointer without a cast
18
avrfat.c:658: warning: pointer targets in passing argument 2 of ltoa differ in signedness
19
avrfat.c:670: warning: passing argument 1 of ltoa makes integer from pointer without a cast
20
avrfat.c:670: warning: pointer targets in passing argument 2 of ltoa differ in signedness
21
avrfat.c:675: warning: pointer targets in passing argument 1 of strlen differ in signedness
22
avrfat.c:690: warning: pointer targets in passing argument 1 of NewFile differ in signedness
23
avrfat.c:694: warning: pointer targets in passing argument 1 of sprintf differ in signedness
24
avrfat.c:695: warning: pointer targets in passing argument 1 of NewFile differ in signedness
25
avrfat.c:697: warning: pointer targets in passing argument 1 of sprintf differ in signedness
26
avrfat.c:698: warning: pointer targets in passing argument 1 of strlen differ in signedness
27
avr-gcc -g -mmcu=atmega16 -O0 -Wall -o avrfat.out -Wl,-Map,fat.map avrfat.o
28
avr-objcopy -j .text -O ihex avrfat.out rom.hex
29
ludwig@client14:~/uni/HS/studarb/fat$


Saluti!

Ludwig

von Ludwig M. (laludelala)


Lesenswert?

Hallo!

Im Assemblerfile sehe ich, daß die parameterübergabe offensichtlich 
nicht über den Stack erfolgt (kein "push"), sondern rein über Register.

Kann es sein, daß die CPU-Register jenseits der RAM-Grenze gemappt 
werden, obwohl laut Datenblatt sie am Anfang gemappt werden?



Saluti!

Ludwig

von Ludwig M. (laludelala)


Lesenswert?

Hallo!

OK, OK, OK - fünf Seiten weiter im Datenblatt steht drin, daß der SRAM 
"versetzt" adressiert wird ...

Bleibt dann trotzdem die Frage, wieso denn die lokalen Variablen so weit 
am Ende liegen! Die werden ja wohl nicht auf dem Stack angelegt werden??



Saluti!

Ludwig

von Karl H. (kbuchegg)


Lesenswert?

> Die werden ja wohl nicht auf dem Stack angelegt werden??

Klar. Wo denn sonst? Ist doch am allereinfachsten.
Beim Funktionsaufruf kommt die Returnadresse auf den
Stack und der Stackpointer wird noch zusätzlich um
die Anzahl der Bytes die für lokale Variablen benötigt
werden dekrementiert. Die Adressierung der Variablen
erfolgt dann relativ zum Stackpointer. Dann funktionierts
auch wunderbar mit Rekursionen.


lokale Variablen : Stack
alles was mittels malloc und Konsorten allokiert wird: Heap

von Malte _. (malte) Benutzerseite


Lesenswert?

Ludwig M. wrote:

> Bleibt dann trotzdem die Frage, wieso denn die lokalen Variablen so weit
> am Ende liegen! Die werden ja wohl nicht auf dem Stack angelegt werden??
Je nach dem. Entweder sie bleiben in den Registern oder müssen auf den 
Stack.
Hier sieht man auch deutliche Unterschiede ob man mit -O0 oder -O2 
compiliert.

von Ludwig M. (laludelala)


Lesenswert?

Hallo!

OK, habt vielen Dank für die Antworten!
Persönlich nützte ich den Stack zwar nur für die Kommunikation zwischen 
Funktionen, aber das ist ja jetzt geklärt.


Saluti!

Ludwig

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.