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....
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.