Warum wird SP unnötig initialisiert? (AVR-GCC, Attiny841)

Gast #5103690
Lesenswert?

Hallo!

Ich habe gestern mal avr-gcc 4.9.2 (von packages.ubuntu.com für xenial, 
inklusive avr-libc und binutils-avr) ausprobiert und das 
Beispielprogramm aus dem AVR-GCC-Tutorial (mit dem Makefile von dort) 
für den Attiny841 übersetzt.

In main.lss habe ich folgendes entdeckt:
1
...
2
...
3
  3a:  08 c0         rjmp  .+16       ; 0x4c <__bad_interrupt>
4

5
0000003c <__ctors_end>:
6
  3c:  11 24         eor  r1, r1
7
  3e:  1f be         out  0x3f, r1  ; 63
8
  40:  cf ef         ldi  r28, 0xFF  ; 255
9
  42:  d2 e0         ldi  r29, 0x02  ; 2
10
  44:  de bf         out  0x3e, r29  ; 62
11
  46:  cd bf         out  0x3d, r28  ; 61
12
  48:  02 d0         rcall  .+4        ; 0x4e <main>
13
  4a:  06 c0         rjmp  .+12       ; 0x58 <_exit>
14

15
0000004c <__bad_interrupt>:
16
  4c:  d9 cf         rjmp  .-78       ; 0x0 <__vectors>
17

18
0000004e <main>:
19
...
20
...
Wie man sieht, wird der Stackpointer mit RAMEND initialisiert. (40–46) 
Aber warum? Das ist doch sinnlos, da der Attiny841 SP sowiesor mit 
RAMEND initialisiert.

Wenn ich „volatile uint8_t blabla;“ und „blabla++“ dazuschreibe, wird 
die Variable tatsächlich aus dem SRAM geladen, jedoch nicht etwa von 
hinter dem Stack. Scheinbar beginnt der Stack also immer bei RAMEND.

Kann man auf diese unnütze Initialisierung verzichten?

Gruß, Tuxpilot

P. S.: Natürlich ist diese Frage nicht so wichtig, ich wundere mich 
nur...
Gast #5103734
Lesenswert?

Tuxpilot schrieb:

> Kann man auf diese unnütze Initialisierung verzichten?

Natürlich. Aber eben nur bei den Targets, bei denen sie wirklich unnütz 
ist. Tiny841 ist so eins, andere sind's nicht. Vor allem ältere 
natürlich, die das einfach noch nicht in Hardware eingebaut haben. Z.B. 
Mega8, 16, 32, 1280, 2560 und sicher auch ein ganze Menge älterer Tinys, 
ganz sicher z.B. der (wegen seiner UART) recht häufig verwendete 2313.

Letzte Sicherheit, ob der Stackpointer bereits durch die Hardware 
sinnvoll initialisiert wird, liefert (natürlich) das Datenblatt des 
Target...

Im Übrigen sollte man nicht vergessen, dass diese hardwaremäßige 
Initialisierung des SP auch nur bei einem Hardware-Reset passiert. 
Manchmal ist es aber z.B. durchaus nützlich, nur eine Art "Soft-Reset" 
auszuführen, also einen unbedingten Sprung zum Reset-Vektor. Bootloader 
sind ein typische Anwendung dafür, zumindest die, die von kompetenten 
Leuten so geschrieben wurden, dass sie ordentlich hinter sich aufräumen, 
bevor sie die geladene App anspringen. Bei denen gehört dann natürlich 
auch zum Job, den SP neu zu initialisieren, wenn sie sich nicht darauf 
verlassen können, dass die App oder deren Runtime-Umgebung das tut. Ich 
hoffe, du schreibst auch deine Bootloader selbst und kompetent...
Gast #5103933
Lesenswert?

c-hater schrieb:
> Ich
> hoffe, du schreibst auch deine Bootloader selbst und kompetent...

Ach so, macht Sinn. An Bootloader habe ich noch nicht gedacht.

Nee, ich schreibe keine Bootloader. Wenn ich den auf den AVR 
programmieren kann, dann kann ich auch gleich das fertige Programm 
nehmen...

Dann hör ich jetzt auf mich zu wundern, danke für die Auskunft.
Wenn mir mal wieder 8000mB fehlen, kann ich das ja noch wegmachen.*


* mB = millibyte ;)
Persönliche Seite #5110759
Lesenswert?

Tuxpilot schrieb:
> In main.lss habe ich folgendes entdeckt:
>
1
>   3c:  11 24         eor  r1, r1
2
>   3e:  1f be         out  0x3f, r1  ; 63
3
>   40:  cf ef         ldi  r28, 0xFF  ; 255
4
>   42:  d2 e0         ldi  r29, 0x02  ; 2
5
>   44:  de bf         out  0x3e, r29  ; 62
6
>   46:  cd bf         out  0x3d, r28  ; 61
7
>   48:  02 d0         rcall  .+4        ; 0x4e <main>
8
>   4a:  06 c0         rjmp  .+12       ; 0x58 <_exit>
9
>
> Wie man sieht, wird der Stackpointer mit RAMEND initialisiert. (40–46)

Nicht wirklich, SP wird mit dem Wert des Symbols __stack initialisiert, 
das per default auf RAMEND sitzt.

Grund 1: Wenn also SP auf einen anderen Wert initilisiert werden soll, 
dann geht das z.B. ohne Neucompilierung per
1
avr-gcc ... -Wl,--defsym,__stack=0x200

> Aber warum? Das ist doch sinnlos, da der Attiny841 SP sowiesor mit
> RAMEND initialisiert.

Grund 2: Es gibt Leute, die per "goto 0" einen "Neustart" des µC 
veranstalten, z.B. von einem Bootloader zur Anwendung springen.

> Kann man auf diese unnütze Initialisierung verzichten?

Wenn du sie nicht brauchst, ja.  Du kannst dir deinen eigenen 
Startup-Code klöppeln und verwenden; allerdings braucht's dazu mehr als 
-nostartfiles weil ein Teil des Startup-Codes traditionell aus der 
libgcc stammt.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren