RTV forum PL | NewsGroups PL

Wzrost rozmiaru kodu o 44 bajty przy przenoszeniu zmiennych lokalnych do globalnych w AVR-GCC?

avr-gcc wielkość kodu

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Wzrost rozmiaru kodu o 44 bajty przy przenoszeniu zmiennych lokalnych do globalnych w AVR-GCC?

pawel
Guest

Fri Sep 11, 2009 11:30 am   



Witam.

Mam dwie zmienne lokalne typu
unsigned int a,b;
i dwa wskaźniki typu
char *wsk1,*wsk2;

Zmienne te wykorzystuję w jednej funkcji.
Chcąc wykorzystać je globalnie w innych funkcjach przeniosłem je do
globalnych.
Dlaczego po samym przeniesieniu ich rozmiar kodu urósł aż o 44 bajty?

Dzięki za pomoc
Paweł

Łukasz Góralczyk
Guest

Fri Sep 11, 2009 2:40 pm   



On Fri, 11 Sep 2009 12:30:41 +0200, pawel wrote:
[ciach o zm. lok.]
Quote:
Zmienne te wykorzystuj w jednej funkcji. Chcc wykorzysta je globalnie
w innych funkcjach przeniosem je do globalnych.
Dlaczego po samym przeniesieniu ich rozmiar kodu urós a o 44 bajty?

Domyślam się że dorzucany jest kod do inicjacji zmiennych globalnych,
zmienne lokalne nie muszą być inicjowane. Tutaj więcej: http://
www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_varinit .

P.S.
Ustaw czytnik tak aby wysyłał w jakim kodowaniu masz posty.

--
Łukasz.

Zbych
Guest

Fri Sep 11, 2009 3:10 pm   



Łukasz Góralczyk pisze:

Quote:
On Fri, 11 Sep 2009 12:30:41 +0200, pawel wrote:
Dlaczego po samym przeniesieniu ich rozmiar kodu urósł aż o 44 bajty?

Skoro masz swój program przed nosem, to czemu nie porównasz plików
wynikowych (*.lst, albo *.lss) z obydwu wersji (przy pomocy np. beyond
compare), tylko liczysz na to, że na grupie jest wróżka?

Quote:
Domyślam się że dorzucany jest kod do inicjacji zmiennych globalnych,

Kod inicjalizacyjny jest niezależnie od tego czy jest co inicjalizować,
czy nie. A przynajmniej gcc nie potrafi tego kodu usuwać.

Grzegorz Kurczyk
Guest

Fri Sep 11, 2009 3:11 pm   



Użytkownik pawel napisał:
Quote:
Witam.

Mam dwie zmienne lokalne typu
unsigned int a,b;
i dwa wskaźniki typu
char *wsk1,*wsk2;

Zmienne te wykorzystuję w jednej funkcji.
Chcąc wykorzystać je globalnie w innych funkcjach przeniosłem je do
globalnych.
Dlaczego po samym przeniesieniu ich rozmiar kodu urósł aż o 44 bajty?


Operacje na zmiennych lokalnych wykonywane są w miarę możliwości
bezpośrednio na rejestrach. Są to rozkazy dwu-bajtowe (jedno słowo).
Przeniesienie zmiennych do globalnych wymusza odwoływanie się do nich za
pośrednictwem czterobajtowych rozkazów LD i ST. Przykładowo
inkrementacja zmiennej lokalnej typu char przechowywanej w rejestrze to
jeden rozkaz np:
INC R16
zajmujący dwa bajty.
Dla zmiennej globalnej zapamiętanej w pamięci RAM będzie to już
sekwencja trzech rozkazów np:
LD R16, [zmienna] // 4 bajty
INC R16 // 2 bajty
ST [zmienna], R16 // 4 bajty
czyli z dwóch bajtów zrobiło się dziesięć.

Dla zmiennych typu int i wskaźników sprawa wygląda odpowiednio gorzej.
Kompilator stara się to możliwie optymalizować wykonując co się da na
rejestrach i dopiero na koniec zapamiętuje wynik w pamięci RAM pod
adresem zmiennej.


Pozdrawiam
Grzegorz

Łukasz Góralczyk
Guest

Fri Sep 11, 2009 3:40 pm   



On Fri, 11 Sep 2009 16:10:20 +0200, Zbych wrote:
[ciach]
Quote:
Domyślam się że dorzucany jest kod do inicjacji zmiennych globalnych,

Kod inicjalizacyjny jest niezależnie od tego czy jest co inicjalizować,
czy nie. A przynajmniej gcc nie potrafi tego kodu usuwać.

Masz rację, teraz sprawdziłem dokładniej i różnica wynika z tego że
zmienne globalne musi przechowywać z pamięci (odczyt zapis).

--
Łukasz.

Norbert Jaros
Guest

Fri Sep 11, 2009 4:40 pm   



On 11 Wrz, 16:11, Grzegorz Kurczyk
<grzegorz.usun...@control.slupsk.pl> wrote:
Quote:
Użytkownik pawel napisał:

Witam.

Mam dwie zmienne lokalne typu
unsigned int a,b;
i dwa wskaźniki typu
char *wsk1,*wsk2;

Zmienne te wykorzystuję w jednej funkcji.
Chcąc wykorzystać je globalnie w innych funkcjach przeniosłem je do
globalnych.
Dlaczego po samym przeniesieniu ich rozmiar kodu urósł aż o 44 bajty?

Operacje na zmiennych lokalnych wykonywane są w miarę możliwości
bezpośrednio na rejestrach. Są to rozkazy dwu-bajtowe (jedno słowo)..
Przeniesienie zmiennych do globalnych wymusza odwoływanie się do nich za
pośrednictwem czterobajtowych rozkazów LD i ST. Przykładowo
inkrementacja zmiennej lokalnej typu char przechowywanej w rejestrze to
jeden rozkaz np:
INC     R16
zajmujący dwa bajty.
Dla zmiennej globalnej zapamiętanej w pamięci RAM będzie to już
sekwencja trzech rozkazów np:
LD      R16, [zmienna] // 4 bajty
INC     R16             // 2 bajty
ST      [zmienna], R16  // 4 bajty
czyli z dwóch bajtów zrobiło się dziesięć.

Dla zmiennych typu int i wskaźników sprawa wygląda odpowiednio gorzej.
Kompilator stara się to możliwie optymalizować wykonując co się da na
rejestrach i dopiero na koniec zapamiętuje wynik w pamięci RAM pod
adresem zmiennej.

Pozdrawiam
Grzegorz

..... jest jeszcze gorzej , bo jeżeli chcesz użyć LD to najpierw trzeba
adres zmiennej załadować do X,Y lub Z
a jeżeli użyjesz LDS to zajmujesz 2 słowa ale sądząc po tych " // 4
bajty " to chyba o LDS koledze wlasnie chodzilo.... :)

Pozdrawiam
Norbert

Grzegorz Kurczyk
Guest

Tue Sep 15, 2009 10:11 am   



Użytkownik Norbert Jaros napisał:
Quote:

.... jest jeszcze gorzej , bo jeżeli chcesz użyć LD to najpierw trzeba
adres zmiennej załadować do X,Y lub Z
a jeżeli użyjesz LDS to zajmujesz 2 słowa ale sądząc po tych " // 4
bajty " to chyba o LDS koledze wlasnie chodzilo.... Smile

Oczywiście ma Kolega rację. Chodziło mi o LDS i STS. Adresowanie
pośrednie z offsetem kompilator używa do adresowania pól w zmiennych
strukturalnych o ile jest to opłacalne (kilka odwołań pod rząd). Przy
pojedynczym odwołaniu skompiluje do LDS/STS.

Pozdrawiam
Grzegorz

Adam Dybkowski
Guest

Wed Sep 16, 2009 8:47 pm   



Grzegorz Kurczyk pisze:

Quote:
.... jest jeszcze gorzej , bo jeżeli chcesz użyć LD to najpierw trzeba
adres zmiennej załadować do X,Y lub Z
a jeżeli użyjesz LDS to zajmujesz 2 słowa ale sądząc po tych " // 4
bajty " to chyba o LDS koledze wlasnie chodzilo.... :)

Oczywiście ma Kolega rację. Chodziło mi o LDS i STS. Adresowanie
pośrednie z offsetem kompilator używa do adresowania pól w zmiennych
strukturalnych o ile jest to opłacalne (kilka odwołań pod rząd). Przy
pojedynczym odwołaniu skompiluje do LDS/STS.

Warto przy tym pamiętać, że instrukcje LDS i STS mają podany bezwzględny
adresu w drugim słowie rozkazu. Dlatego też są używane przez kompilatory
do pobrań i zapisów zmiennych globalnych, których adresy określane są na
etapie konsolidacji (linkowania). Ale jeżeli zmienna leży na stosie lub
jest alokowana dynamicznie, LDS i STS do niczego się nie przydadzą.

--
Adam Dybkowski
http://dybkowski.net/

Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.

elektroda NewsGroups Forum Index - Elektronika Polska - Wzrost rozmiaru kodu o 44 bajty przy przenoszeniu zmiennych lokalnych do globalnych w AVR-GCC?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map