Nie bardzo rozumiem ?
ROTFL :-) Ale rada dobra - jak sie nie chce czytac podrecznika, to trzeba sie czym innym zajac :-)
J.
Nie bardzo rozumiem ?
ROTFL :-) Ale rada dobra - jak sie nie chce czytac podrecznika, to trzeba sie czym innym zajac :-)
J.
Nic na sile ... wszystko mlotkiem :-)
J.
Thu, 06 May 2004 11:53:20 +0200, na pl.misc.elektronika, Milosz Skowyra napisał(a):
BTW - czy masz zestawione jakies srodowisko symulacyjne ? Do takich roznych niuansow jest jak znalazl. Pod Win swietnie sie sprawdza AvrStudio 4.08
Raczej nie - w avr-gcc wskaznik jest zawsze 16-bitowy ( czyli rozmiar int ). Wiec deklaracja char *xptr; tworzy zmienna dwubajtowa xptr. Natomiast kompilator kontroluje 'target' wskaznika - jesli chcesz tam wpisac jakas dowolna liczbe to ostrzega, ze mu sie nie zgadza. Wystarczy poinformowac xptr=(char*)(&x+1); zeby zgasic warninga.
Pozdrowienia Jurek Szczesiul
Oj, w a laduje x[20]. A czy to jest y[0] to juz tylko konkretny kompilator wie. Generalnie nie musi.
Prawidlowo.
Nie - chodzi o to ze zmieniasz typ wskaznika - tzn typ obiektu wskazywanego. A potem bedziesz narzekal ze xptr+1 to nie jest rowne &x+1 ..
Ale w koncu nie zrozumialem - przekombinowales, czy kompilator zle dziala ?
J.
Nie takie rzeczy my ze Zbysiem po trzech flaszkach ;-)))
Mam, robie coff-a i do AvrStudio. Ale czasem to tez nie daje pelnego obrazka... zwlaszcza jak wiedzy brakuje ;-(
Jasne. Dzieki.
Roznica jest w definicji wartosci zwracanej przez operator. W operatorze prefiksowym jest prosto, bo najpierw wykonuje sie operacje, a dopiero pozniej zwraca zmodyfikowany obiekt. W przypadku operatora postfiksowego trzeba zwrocic obiekt opisujacy stan _przed_ wykonaniem operacji, co pociaga za soba koniecznosc skonstruowania obiektu tymczasowego. Jesli obiekt jest typu wbudowanego, to w zasadzie nie ma roznicy, bo kompilator wyrzuci niepotrzebny obiekt w fazie optymalizacji. Jesli jednak napiszesz wlasny obiekt implementujacy oba operatory ++, to kompilator nie bedzie juz mogl tego dokonac. Dlatego warto wyrabiac sobie nawyk uzywania "tanszych" wersji operatorow, gdy mozna sobie na to pozwolic. Operator prefiksowy jest tanszy, bo zazwyczaj zwraca referencje do obiektu, a nie obiekt.
Pozdrawiam Piotr Wyderski
Zakladajac ze kompilator ulozy w pamieci tablice x i y po sobie (pewnie nie ma co takiej ewentualnosci zakladac, bo optymalizacja moze pomieszac, ale jesli chodzi o elementy struktury to chyba mozna cos takiego zalozyc, czy nie ??) Ale generalnie chodzilo mi o to czy wskaze nastepny bajt po koncy tablicy x.
W koncu... jakas pomrocznosc mnie dopadla.
No dobrze, ale ja zrobie jak proponuje Jurek tzn. xptr=(char*) to znow zgwalce kompilator ??
Tak dziala i dziala poprawnie konstrukcja: lcd_port=pgm_read_byte(polish_chars+f);
Diobra. MOV R31,R29 //adres tablicy w R28-R29 MOV R30,R28 LPM MOV R24,R0 OUT 0x18,R24 [...] // tu mruganie pinami do wyswietlacza. SUBI R17,0xFF ADIW R28,0x01 CPI R17,0x40 BRCS +0x5D
Tak w ogole to dziwi mnie ze bezposrednio nie inkrementuje Z, chociaz Z nie jest uzywany przez nic innego. Ale moze taka polityka ;-)
To nie dziala (znaczy sie czyta smieci). lcd_port=pgm_read_byte(polish_chars[f]);
MOV R31,R15 ;r14-r15 adres MOV R30,R14 LD R24,Z+ ;tego nie kumkam MOV R14,R30 MOV R15,R31 MOV R30,R24 ;i tego tez CLR R31 LPM MOV R24,R0 [...] //tu tez mrugranie liniami LCD SUBI R28,0xFF CPI R28,0x40 BRCS +0x59
Wyglada jakby z pamieci programu pobieral 1 bajtowy wskaznik do danej we flashu. Hmmm dlaczego nie wiem. Chociaz cos mi zaczelo chodzic po glowie.
[chwila kombinacji............] W faqu jest przyklad:const char foo[] PROGMEM = "Foo"; const char bar[] PROGMEM = "Bar";
PGM_P array[2] PROGMEM = { foo, bar };
int main (void) { char buf[32]; strcpy_P (buf, array[1]); return 0; }
Na jego podstawie wyklepalem:
const unsigned char polish_chars[] PROGMEM ={
0x0C,0x04,0x06,0x0C,0x04,0x04,0x0E,0x00, //0 - l 0x00,0x00,0x0E,0x11,0x1F,0x10,0x0E,0x02, //1 = e 0x00,0x02,0x16,0x19,0x11,0x11,0x11,0x00, //2 = n 0x00,0x04,0x1F,0x02,0x04,0x08,0x1F,0x00, //3 = z 0x02,0x04,0x0E,0x011,0x11,0x11,0x0E,0x00, //4 = o 0x00,0x04,0x0E,0x10,0x10,0x11,0x0E,0x00}; //5 = cPGM_P pol_znak[] ={polish_chars};
Odwolujac sie za pomoca: lcd_port=pgm_read_byte(pol_znak[f]); dostaje nie dzialajacy kod ;-) MOV R30,R28 CLR R31 LSL R30 ROL R31 SUBI R30,0xA0 SBCI R31,0xFF LD R0,Z+ LDD R31,Z+0 MOV R30,R0 LDD R24,Z+0 MOV R30,R24 CLR R31 LPM MOV R24,R0 [...] //mruganie liniami LCD
natomiast dziala lcd_port=pol_znak[f]; tyle ze kopiuje stringa do RAM.
Thu, 06 May 2004 15:51:19 +0200, na pl.misc.elektronika, Milosz Skowyra napisał(a):
polish_chars jest de facto adresem tablicy w ROM, polish_chars + f = adres f-tego elementu - i OK
A polish_chars[f] juz nie jest adresem tylko wartoscia f-tego elementu - wiec smieci czyli tez OK :-) Napisz lcd_port=pgm_read_byte(&polish_chars[f]);
Jasne... tepota straszna ze mnie ;-(((
To nie jest gwalcenie, tylko jawna zmiana typu. Zakladamy ze programista wie co robi :-)
Ale mi chodzilo o lcd_port=polish_chars[f] ;
I prawidlowo, bo co tu kazales? a) bierzemy f-ty element z tablicy polish_chars - nie adres, ale juz wartosc, czyli te twoje 0x0C np
b) odczytujemy bajt pamieci programu spod adresu bedacego odczytana poprzednio wartoscia [czyli 0x000C]
A mi sie wydaje ze to na przyszlosc - i tak trzeba wskaznik powiekszyc
bo tu realizujemy b)
wlasnie rozszerzamu uchar do wskaznika czy int
IMHO - bo mu dokladnie wlasnie to kazales.
Bo na ile sie domyslam to: a) zadeklarowales tablice wskaznikow pol_znak, wskazujacych na progmem [kompilator musi to wiedziec zeby wlasciwe instrukcje stosowac]. b) tablica jest jednoelementowa i zawiera adres [wskazanie w/g Bieleckiego] polish_chars
c) pol_znak[f] jest f-tym wskaznikiem w tablicy pol_znak - czyli smieciami, bo poza tablica,
d) odczytany wskaznik traktujemy jako adres bajtu w progmem, ktory pobieramy
f do R30,31
elementy pol_znak sa dwubajtowe, wiec trzeba pomnozyc f przez 2
Dziwne, ale to jest widac adres poczatkowy pol_znak
pobieramy z pamieci polznak[f] - dwa bajty, bo to wskaznik
A to jest lekko dziwaczne - jakby kolejne posrednie adresowanie, ty nie sklamales z tym lcd_port=pgm_read_byte(pol_znak[f]) ?
Zaraz - jakim cudem to moze dzialac ?
Milosz - my naprawde dobrze radzimy - albo przeczytasz ze zrozumieniem ksiazke, albo .. na marchewce tez sie mozna dorobic.
J.
Jasne... sadzac z ksiazeczki nazywa sie to typecast ;-)))
W asm-ie wiem dokladnie do robie... w C ma to robic za mnie kompilator... ale za malo piffa z nim wypilem ;-))) Ale sens powyzszego jest jasny.
Dziala, tylko ze na starcie programu kopiuje cala tablice do RAM, a tego wlasnie chce uniknac.
Jasne. Probu i wysylke przeprowadzilem w czasie kiedy rozsadek poszedl na spacer. Dlatego takie wyniki. Teraz sam widze co powyprawialem ;-(((
Nie ma szans, pisalem ze rozsadek mial wolne. Wszystko bylo Copy&Paste.
Nie wiem, ale raczej zbieg okolicznosci ;-) Pierwszy znak jest zle definiowyany, potem ok.
No i wlasnie wrocilem z przebiegu po moim "ukochanym" miescie Opolu. Bylem w 6 ksiegarniach i tak naprawde to nie ma co kupic. W jenej znalazlem pozycje "C" Bjorna Stroustrupa, ale w skorze z odcisnietymi literkami za jedyne 144 pln. Reszta to malo ciekawe dla mnie pozycje, dotyczace najczesciej obiektowych wersji C, samouczki C, a nawet "C w 24 godziny". Co do ANSI C to nie znalazlem ani jednej pozycji. Z ciekawostek byly 2 ksiazki typu 99 najczestszych bledow w C++, nawet ciekawe. Ale jakies 80% porad dotyczylo wersji okienkowych. W koncu juz w trzeciej bibliotece znalazlem "C" K&R, a dodatkowo pozyczylem z sentymentu "Sam na sam z jezykiem C" Bieleckiego, opisujacy HiSoft C na.... ZX ;-) Zaczyna sie od slow LOAD "" ;-) Na razie mam "C" K&R, Kieszkonkowy leksykon C i Borland C++. Mysle ze wystarczy, a jak nie to kupie cos naprawde sensownego ale w interq ;-))) Dalsze pytania nie wykluczone... Jak bede we Wrocku to stawiam piffo. Dzieki.
PS. Ksiazki ogrodnicze o uprawie marchewki byly wszedzie... za wyjatkiem ksiegarni technicznej ;-)
Nie chcial Milosz nosic teczki to ponosi marcheweczki ;-)))
Hm, moze przeceniam avrgcc, ale skoro zadeklarowales tablice w progmem, to nie powinien tego robic.
Bielecki w C byl dobry. Co prawda specyficzny to autor i ksiazki mial trudne, ale jak go zrozumiesz to i C zrozumiesz :-) Z tym ze wersja ZX moze byc bardzo uproszczona.
J.
A kicha... nie dziala. Usiluje czytac z RAM-u ale wczesniej do niego nie kopiuje stringa. MOV R14,R21 //w r14-15 adres, poprawny bo napis w flash leci od 0x0021 LDI R21,0x00 MOV R15,R21 ale samo czytanie odbywa sie z ramu. MOV R31,R15 MOV R30,R14 LD R24,Z+ MOV R14,R30 MOV R15,R31 OUT 0x18,R24
Zgadza sie, pamietam ksiazki Bieleckiego z okresu ZX-a (bylem gdzies w
4-5 klasie podstawowki) i pozniejsze z pecetologii. Ciezki do czytania i rozumienia, ale za to trzeba mu przyznac ze wiedze posiadal spora.Sat, 08 May 2004 14:04:01 +0200, na pl.misc.elektronika, Milosz Skowyra napisał(a):
To juz nie wiem jak robisz. Taki tu prosty przyklad różnych składni:
const char Tx1[] PROGMEM = "One"; .................... i=1; x=pgm_read_byte(Tx1); x=pgm_read_byte(&Tx1[i]); i=2; x=pgm_read_byte(Tx1 + i); generuje :
i=1; 180: 81 e0 ldi r24, 0x01 ; 1 182: 90 e0 ldi r25, 0x00 ; 0 184: 90 93 70 00 sts 0x0070, r25 188: 80 93 6f 00 sts 0x006F, r24 x=pgm_read_byte(Tx1); 18c: e6 e9 ldi r30, 0x96 ; 150 18e: f0 e0 ldi r31, 0x00 ; 0 190: 84 91 lpm r24, Z 192: 80 93 6c 00 sts 0x006C, r24 x=pgm_read_byte(&Tx1[i]); 196: 31 96 adiw r30, 0x01 ; 1 198: 84 91 lpm r24, Z 19a: 80 93 6c 00 sts 0x006C, r24 i=2; 19e: 82 e0 ldi r24, 0x02 ; 2 1a0: 90 e0 ldi r25, 0x00 ; 0 1a2: 90 93 70 00 sts 0x0070, r25 1a6: 80 93 6f 00 sts 0x006F, r24 x=pgm_read_byte(Tx1 + i); 1aa: 31 96 adiw r30, 0x01 ; 1 1ac: 84 91 lpm r24, Z 1ae: 80 93 6c 00 sts 0x006C, r24
Przeciez Jarek ewidentnie pytal czy dziala sekwencja.
Specjalnie zostawilem cytat ktory wyciales. Przeczytaj ze dwa posty wyzej. Mozesz zreszta pokazac co da w Twoim przypadki x=Tx1[i];
Sat, 08 May 2004 18:04:32 +0200, na pl.misc.elektronika, Milosz Skowyra napisał(a):
OK, OK ;-) Watek sie cokolwiek pokomplikowal.
Zoptymalizowalo :
x=Tx1[i]; 178: 80 91 97 00 lds r24, 0x0097 17c: 80 93 6c 00 sts 0x006C, r24
Wow - popatrzcie jak optymalizator ladnie sledzi jakie stale wpisujemy do i
Zauwaz rowniez ze wypromowal chara do inta.
Have something to add? Share your thoughts — no account required.
Ask the community — no account required