Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

programski jezici za mikrokontrolere pitanja i odgovori

[es] :: Elektronika :: Mikrokontroleri :: programski jezici za mikrokontrolere pitanja i odgovori

Strane: < .. 1 2 3 4 5 6 7

[ Pregleda: 17965 | Odgovora: 120 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori01.08.2008. u 22:57 - pre 192 meseci
Jeste, buduci da je korak razocaran brzinom i duzinom koda koji generisu C kompajleri, pretpostavljam da bi mu maksimalna optimizacija ovde bila imperativ.

Upravo zbog bolje optimizacije koda predlazem par "nestandardnih" stvari kao sto su trobajtne varijable, zatim razliciti kod za razlicite slucajeve (npr. testiranje dvobajtnih ili trobajtnih varijabli...).
U principu, kompajler bi se mogao napraviti tako da testira samo cetvorobajtne varijable za sve moguce situacije, ali onda kod uopste nece biti optimizovan.

Dali ste malo nezgodan primer, jer se eto bas mnozenje (i deljenje) sa dva moze realizovati u PIC16F seriji sa dve instrukcije najobicnijom rotacijom. Matematicke rutine (koje bi u kompajleru bile u modulima) svakako bi se mogle dodatno optimizovati i za ove slucajeve, ali smatram da bi ipak to bio preveliki posao. Ako su dovoljno dobre za proizvodjace PIC mikrokontrolera, onda su dobre i za nas. Ionako se uvek trudim da nadjem alternativne metode za mnozenje i deljenje, i uglavnom uspevam. Dobar programer ce uvek biti u stanju da prepozna ovakve situacije i da umesto matematickih modula koristi mnogo, mnogo jednostavnije metode.

Konkretno za primer "if W>50 then" planiram napraviti bar desetinu razlicitih kodova.
1. za slucaj if W>50
2. za slucaj if W>=50
3. za slucaj if W<50
4. za slucaj if W<=50
5. za slucaj if W==P
6. za slucaj if W<>50

pa onda
1. za slucaj if 50>W
2. za slucaj if 50>=W
3. za slucaj if 50<W
4. za slucaj if 50<=W
5. za slucaj if 50==W
6. za slucaj if 50<>W

pa onda
1. za slucaj if W>JednobajtnaVarijabla
2. za slucaj if W>=JednobajtnaVarijabla
3. ...

pa
1. za slucaj if JednobajtnaVarijabla>W
2. za slucaj if JednobajtnaVarijabla>=W
3. ...

i dalje
1. za slucaj if JednobajtnaVarijabla>50
2. za slucaj if JednobajtnaVarijabla>=50
3. ...

i na kraju
1. za slucaj if JednobajtnaVarijabla_A>JednobajtnaVarijabla_B
2. za slucaj if JednobajtnaVarijabla_A>=JednobajtnaVarijabla_B
3. ...

To je ukupno 36 mogucih slucajeva samo za jednobajtne vrednosti. Ako to onda ne bude optimizovano najmanjim mogucim brojem instrukcija ne znam sta bi uopste moglo da bude.

Eventualno, mozda bi se kod mogao dodatno optimizovati za situacije poput "if W>50 AND W<80 then". Njegova optimizacija zahtevala bi dosta veci broj slucajeva, tako da sumnjam da bi se uopste isplatio ulozeni trud zbog ustede samo jedne ili dve instrukcije.

[Ovu poruku je menjao Stojan Trifunovic dana 02.08.2008. u 12:16 GMT+1]
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori04.08.2008. u 13:02 - pre 192 meseci
Vidim da navodite neke primere i da diskutujete o njima. Kako nemam asembler za PIC, a pricamo o tome da li bi vredeko da takav bide i za njega, navescu kako moj kompajler resava ta slucajeve. Pre toga: cilj mi je bio da jedan iskaz bude jedna asemblerska instrukcija, sem tamo gde ne mora.

Dakle W > 50:

Code:


  ldaa [w];
  cmpa 50;
  if > then
  begin
    <naredbe programa>
  end
  else    //ako treba
  begin
    <naredbe programa>
  end;

;

Drugi slucaj C = A* B u situaciji kada je A konstanta 2^n se svodi na siftanje. Za ovakve funkcije koristim makroe.

Code:

macro Pomnozi(a,b)
begin
  _if VarOf(A) and VarOf(B) then result := Mult(A,B); //Mult je procedura koja mnozi
  quit;  //prekida dalji prevod makroa
  
  _if not VarOf(a) then    
  begin
    _if A  in[2,4,8,16,32,64] then result := Shl(B,A)     //moze i vise od 64, dok to ne postane duze od mnozenja
                              else result := Mult(A,B);
  end
  else 
  begin
     _if B  in[2,4,8,16,32,64] then result := Shl(A,B)     //moze i vise od 64, dok to ne postane duze od mnozenja
                               else result := Mult(A,B);
  end;
end;



_if je komapajlersko if o odredjuje koji delovi programa ce se prevoditi. VarOf() je funkcija koja vraca true ako je parametar varijabla.

Pozdrav.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori04.08.2008. u 22:47 - pre 192 meseci
U redu. Sada imamo smernice.

16F za razliku od 18F serije ima prilicno limitirane funkcije poredjenja, pa bi se za W > 50 moralo pisati sledece:
Code:

Test                      ; if
        sublw   .50       ; Oduzimanje ce setovati Carry ako je W manje ili jednako broju 50.
        btfss   STATUS,C  ; Preskoci sledecu instrukciju ako je Carry setovan
        goto    Veci      ;

Manji                     ; else ili nastavak - ako je W <= 50
....

Veci                      ; then - ako je W > 50
.....

Kako ovo radi? Najpre se od W oduzme broj 50. Rezultat se smesta u W cime se on menja. Ukoliko je ovo nepozeljno, mogao bi se privremeno sacuvati i kasnije vratiti, kao u interaptima.
Oduzimanje se u 16f seriji hardverski obavlja sabiranjem sa drugim komplementom, tako da ce Carry biti setovan ukoliko ima pozajmice, ili ukoliko su brojeci isti.
Ako je Carry setovan preskocice se sledeca instrukcija (goto Veci) i nastavice se od labele Manji. Ako nije, izvrsice se instrukcija goto Veci, i program ce nastaviti odatle.

Za slucaj da je neophodno sacuvati W moglo bi se pisati sledece:
Code:

Test                      ; if
        movwf   TEMP      ; W u TEMP
        sublw   .50       ; Oduzimanje ce setovati Carry ako je W manje ili jednako broju 50.
        movf    TEMP,W    ; Povratak iz TEMP u W
        btfss   STATUS,C  ; Preskoci sledecu instrukciju ako je Carry setovan
        goto    Veci      ;

Manji                     ; else ili nastavak - ako je W <= 50
....

Veci                      ; then - ako je W > 50
.....

Znaci, za Vas slucaj
Code:

  ldaa [w];
  cmpa 50;
  if > then

kompajler bi trebao kopirati jedan od gornjih kodova. Koji, zavisi od toga da li se zeli da W registar ostane nepromenjen.


Mnozenje bi se i u 16F i u 18F serijama moglo obavljati na potpuno isti nacin (rotacijom). Nisam znao da imate i mogucnost uslovnog kompajliranja! Utoliko bolje.
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori05.08.2008. u 12:13 - pre 192 meseci
Ja sam napisao primer:

Code:

  ldaa [w];
  cmpa 50;
  if > then
  begin
    inca;
  end
  else
  begin
    deca;
  end;


Ali evo i prevoda da vidis kako kompajler prevodi if..then..else

Code:

   $6010 : $b652       [3] ldaa    [$52]
   $6012 : $a132       [2] cmpa     $32
   $6014 : $2303       [3] bls      $6019

   $6016 : $4c         [1] inca
   $6017 : $2001       [3] bra      $601a
   --------------------------------------
   $6019 : $4a         [1] deca
   $601a :


Prva kolona je adresa, zatim kod naredbe u heksa ciframa, u srednjim zagradama trajanje naredbe u ciklusima i na kraju asemblerska naredba. Naredba bls je granjanje ako je manje ili jednako. Mislim da ti je prevod jasan.

Slicno tome za PIC bi bilo:
Code:

  sublw 50;
  if >= then  //uzet uslov >= jer kod 16F je komplikovanije realizovati uslov >
  begin
     incf [49].0;
  end
  else
  begin
     decf [49],0;
  end;


Komapajler bi to trebao da prevede nekako ovako:

Code:

  $0100 :  sublw $32;
  $0101 :  btfsc STATUS,C;
  $0102 :  goto $0105;
  $0103 :  incf [$31],0;
  $0104 :  goto $0106;
  $0105 :  decf [$31],0;
  $0106 :


sto nije neki problem za realizaciju. Primecujes da je za ovo potrebno uvesti dve labele u klasicnom asembleru, a u ovom mom nema ni jedne. Nisam siguran da li sam dobro napisao asemblerski kod za PIC, ispravite me ako sam pogresio.

Pozdrav
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori05.08.2008. u 23:02 - pre 192 meseci
Prevod mi je jasan (stavise, skoro je isti kao za 6510), ali program za PIC nije ispravan. Sa btfsc instrukcijom koju ste upotrebili, Vas program bi izvrsio inkrementaciju bas za istinit slucaj "if W > 50", odnosno za onaj koji ste naveli kao tezi. Uopste nije tezi. Dovoljno je izokrenuti oduzimanje po sledecem:
Code:

   movf    BROJ,W ; BROJ u W
   sublw   .2     ; W = 2 - BROJ

   movlw   .2      ; 2 u W
   subwf   BROJ,W  ; W = BROJ - 2

Ovakav nacin pruza mogucnost lakog dobijanja poredjenja <, >, <= i >=. Za == i <> testirao bi se Zero flag.

Koliko sam ukapirao, ukoliko se u vasem kompajleru stavi znak ; iza instrukcije, onda to oznacava asemblersku instrukciju koju kompajler samo prepisuje (eventualno menjajuci brojni sistem). Medjutim, jedna stvar mi onda nije jasna. Na koji nacin je u tom slucaju u kompajleru definisano nad kojim ce se varijablama vrsiti testiranje? Mislim, bilo bi jasnije da se stavi "if W >= 50" nego "if >=". A sta u situacijama kada bi bilo potrebno porediti "if 50 < W" ili dve varijable "if A <= B"?

I jos nesto! Ne bi li bilo zgodnije da se umesto
Code:

  sublw 50;
  if >= then  //uzet uslov >= jer kod 16F je komplikovanije realizovati uslov >
  begin
....

pise samo
Code:

  if W >= 50 then  //uzet uslov >= jer kod 16F je komplikovanije realizovati uslov >
  begin
....

Zbog toga predlazem da za svaki pojedinacni slucaj (<, >, <=, >=, =, <>) i za sve moguce oblike varijabli (W, jednobajtna i eventualno visebajtne varijable) kompajler kopira poseban kod, bas za tu operaciju. Onda bi kompajler sam brinuo o oduzimanju, skokovima i testiranju flegova. Ovako samo eliminise labele (nije ni to mala prednost) ali za racunanje koliko mi se cini ostavlja programeru pisanje instrukcija koje ce na odgovarajuci nacin promeniti flegove.

Tih 36 razlicitih slucajeva (za jednobajtne varijable) i nije toliko mnogo, za ono sto bi se njima dobilo. Ipak bi takav kod bio maksimalno optimizovan bas za svaki pojedinacni slucaj.
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori06.08.2008. u 13:23 - pre 192 meseci
Da, u pravu si,
jos uvek razmisljam na 'motorola' nacin. Ovde se testira bit u statusnoj reci, i za '>=' C = 0, a za '<' C = 1, zar ne. U pravu si i za ono drugo, ako se obrne oduzimanje, onda moze da se ostvari ono sto sam rekao da je komplikovano. Opet iz razloga koje sam malopre naveo, otelo mi se da kazem da je komplikovanije, jer motorola za '>' testira istovremeno C i Z bit.

Ipak, iz opreza da kazem da mi se cini komplikovanim, uporedjivanje oznacenih brojeva kod PIC-a. Na primer u w ja 10 a uporedujes sa $FF sto je -1. Ovde bi uporedjenje pokazalo da je manja vrednost u w, a ustvari je veca. Ja znam da za svaki MCU postoji posebna tehnika pisanja softvera koja resava sve slucajeva, pa me interesuje kako se ovaj slucaj resava.

Moj cilj, kada sam pisao asembler nije bio da napravim visi programski jezik, jer bi onda taj jezik izgubio na snazi. Cilj mi je bio da to i dalje bude asembler, ali da je kompajler u stanju da uradi umesto programera sve ono sto moze sa ciljem da se olaksa programeru posao. Postoje tu i druge stvari repeat..until petlja, while..do petlja case..of struktura, vrlo mocni makroi, prenos parametara procedurama i funkcijama i moduli kao posebne programske celine u posebnim fajlovima i koji mogu da se koriste u raznim softverskim projektima. Dakle, to mi je bio cilj, da se ne udaljim previse od asemblera.

Pozdrav.

 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori06.08.2008. u 23:13 - pre 192 meseci
@korak
"za '>=' C = 0, a za '<' C = 1, zar ne."
U principu jeste, ali zavisi od toga kako je reseno prethodno oduzimanje.

Uporedjivanje oznacenih brojeva? Moram da priznam da o njima uopste nisam razmisljao. Nemam mnogo iskustava sa njima, ali mislim da bi najjednostavniji nacin poredjenja podrazumevao da se najpre uporedi bit znaka (MSB). Ukoliko se ne slaze, rezultat poredjenja se moze odmah dobiti (+ je uvek > od -). Ukoliko je znak isti i pozitivan nastavlja se sa obicnim poredjenjem, a ako je isti i negativan obe varijable se komplementuju i obrise im se MSB, pa se onda standardno porede. Kod za obicno poredjenje je uvek isti, tako da kompletan kod ne bi morao biti previse dug.
Mozda postoji i jednostavniji nacin. Zna li ko?

Mislim da bi bilo najbolje pre ikakve dalje diskusije definisati tipove varijabli i njihovu sintaksu.

Predlazem sledece:
bit sa sintaksom W,3 (ON,OFF)
bit sa sintaksom REGISTAR,5 (ON,OFF)
neoznaceni bajt sa sintaksom W
neoznaceni bajt sa sintaksom REGISTAR (0,+255)
oznaceni bajt sa sintaksom nestoW (-128,+127)
oznaceni bajt sa sintaksom nestoREGISTAR (-128,+127)
word (2 bajta) sa sintaksom REGISTAR (0,+65535)
oznaceni word sa sintaksom nestoREGISTAR (-32768,+32767)
tri bajta sa sintaksom REGISTAR (0,+16777215)
Oznacena tri bajta sa sintaksom nestoREGISTAR (-8388608,+8388607)
long (4 bajta) sa sintaksom REGISTAR (0,+4294967295)
Oznaceni long sa sintaksom nestoREGISTAR (-2147483648,+2147483647)

To "nesto" mogao bi biti neki od znakova interpunkcije. Sigurno da negde postoji standardizovani oblik predstavljanja oznacenih brojeva, ali meni eto nije poznat.

Jednobajtne i visebajtne varijable ovako bi imale istu sintaksu, ali kompajler bi pravio razliku izmedju njih na osnovu podataka iz deklaracionog bloka.

Za pocetak, mogli biste krenuti samo sa bit i bajt tipovima, ali tako da predvidite moucnost nadgradnje kompajlera i za ostale tipove.

Takodje, predlazem da deklaracija varijabli bude jedino unutar deklaracionog bloka, i da se odmah u njemu definise oznacenost i velicina varijabli (jedan ili vise bajtova).
Code:

var bank 0 [0x20..0x6F]
  <deklaracija varijabli >

var bank 1 [0xA0..0xEF]
  <
   DAN    res 1
   MESEC  res 1
   GODINA res 2
   TROBAJTNA_VARIJABLA res 3
   nestoOZNACENA_DVOBAJTNA_VARIJABLA res 2
   >


Buduci da se ne biste previse udaljavali od asemblera, pojasnite nam da li uopste nameravate ubaciti visebajtne varijable i oznacene brojeve (ukoliko ne postoji jednostavniji nacin poredjenja).
Takodje, da bi kod bio sto blizi asembleru, prakticnije bi bilo ne uporedjivati direktno dve varijable ili varijablu sa konstantnom vrednoscu, vec samo W sa konstantnom vrednoscu ili W sa varijablom.

Dakle definisite do koje dubine zelite ici, a konkretne kodove prepustite meni. Bar za if..then, repeat..until, while..do i case..of. Za makroe, prenose parametara i module ne verujem da cu Vam moci pomoci.
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori07.08.2008. u 11:50 - pre 192 meseci
Evo ovako,
MMA (makro mega asembler, tako ga zovem) ima sledece preddefinisane tipove:

Code:

Ime tipa    Duzina u bajtovima    Opseg vrednosti
byte                1                  0..255
shortint            1                -128..127
char                1                #0..#255
word                2                0..65535
integer             2             -32768..32767
longword            4             0..4294967295
longint             4         2147483648..2147483647
real                4         ±(5.88e-39..6.81e+38),0
boolean             1            true, folse (1,0)
string             256           0..254 karaktera



Pa bi primer tvojih deklaraciija bio:

Code:


var bank 0 [0x20..0x6F]
  <deklaracija varijabli >

var bank 1 [0xA0..0xEF]
  <
   DAN  : byte
   MESEC  : byte
   GODINA : word
   TROBAJTNA_VARIJABLA : array[0..2] of byte
   nestoOZNACENA_DVOBAJTNA_VARIJABLA : integer
   >


Sto se programskih struktura tice, pogledaj prikaceni fajl, koji je jedno nedovrseno uputstvo, i samo njegov podnaslov 'Karakteristicne programske strukture'. Bice mi vazno kako ti kao poznavalac PIC-a mislis da se tako nesto moze sto efikacnije implementirati na PIC.

Pozdrav.
Prikačeni fajlovi
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
77.46.210.*



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori07.08.2008. u 12:47 - pre 192 meseci
Trenutno nemam vremena za fajl (pogledaću ga sutra), ali recite mi želite li znači u asembler za PIC ubaciti sve te oblike varijabli?
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori07.08.2008. u 14:45 - pre 192 meseci
Da, to je dobro za povecanje pouzdanosti softvera, a olaksava i odrzavanje.

Pozdrav.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori08.08.2008. u 07:10 - pre 192 meseci
Pogledao sam fajl, i mislim da ce za PIC16 seriju biti najteze realizovati operacije sa oznacenim brojevima, jer jednostavno u PIC16 seriji ne postoje instrukcije koje ih podrzavaju. Ostale strukture ne bi trebale predstavljati problem. U principu mogu se odraditi i oznaceni brojevi, ali uz duzi kod.

Evo (za pocetak) primera za testiranje W sa konstantom.
Radi lakseg razumevanja uzeo sam da se registar inkrementuje ako je uslov ispunjen, da se dekrementuje ako nije, i jednu praznu instrukciju (nop) pri nastavku programa.

if W > konstante 50 then inc else dec
Code:

  if W > 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $0100 : sublw   $32;
 $0101 : btfsc   STATUS,C;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


if W < konstante 50 then inc else dec
Code:

  if W < 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0100 : movwf   TEMP;
 $0101 : movlw   $32;
 $0102 : subwf   TEMP,W;
 $0103 : btfsc   STATUS,C;
 $0104 : goto    $0107;
 $0105 : incf    [$31],W;
 $0106 : goto    $0108;
 $0107 : decf    [$31],W;
 $0108 : nop;


if W >= konstante 50 then inc else dec
Code:

  if W >= 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0100 : movwf   TEMP;
 $0101 : movlw   $32;
 $0102 : subwf   TEMP,W;
 $0103 : btfss   STATUS,C;
 $0104 : goto    $0107;
 $0105 : incf    [$31],W;
 $0106 : goto    $0108;
 $0107 : decf    [$31],W;
 $0108 : nop;


if W <= konstante 50 then inc else dec
Code:

  if W <= 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0100 : sublw   $32;
 $0101 : btfss   STATUS,C;
 $0102 : goto    $0105;
 $0103 : incf    [$31],0;
 $0104 : goto    $0106;
 $0105 : decf    [$31],0;
 $0106 : nop;


if W == konstante 50 then inc else dec
Code:

  if W == 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $0100 : xorlw   $32;
 $0101 : btfss   STATUS,Z;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


if W <> konstante 50 then inc else dec
Code:

  if W <> 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $0100 : xorlw   $32;
 $0101 : btfsc   STATUS,Z;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;





Sada evo primera za testiranje konstante sa W. Naravno, kod koji bi proizvodio kompajler je isti kao i ranije, jedino je znak poredjenja (<, >, <= i >=) promenjen.
Opet je radi lakseg razumevanja uzet prethodni slucaj (inkrementuja, dekrementacija i nop).

if konstanta 50 < W then inc else dec
Code:

  if 50 < W then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $0100 : sublw   $32;
 $0101 : btfsc   STATUS,C;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


if konstanta 50 > W then inc else dec
Code:

  if 50 > W then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0100 : movwf   TEMP;
 $0101 : movlw   $32;
 $0102 : subwf   TEMP,W;
 $0103 : btfsc   STATUS,C;
 $0104 : goto    $0107;
 $0105 : incf    [$31],W;
 $0106 : goto    $0108;
 $0107 : decf    [$31],W;
 $0108 : nop;


if konstanta 50 <= W then inc else dec
Code:

  if 50 <= W then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0100 : movwf   TEMP;
 $0101 : movlw   $32;
 $0102 : subwf   TEMP,W;
 $0103 : btfss   STATUS,C;
 $0104 : goto    $0107;
 $0105 : incf    [$31],W;
 $0106 : goto    $0108;
 $0107 : decf    [$31],W;
 $0108 : nop;


if konstanta 50 >= W then inc else dec
Code:

  if 50 >= W then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0100 : sublw   $32;
 $0101 : btfss   STATUS,C;
 $0102 : goto    $0105;
 $0103 : incf    [$31],0;
 $0104 : goto    $0106;
 $0105 : decf    [$31],0;
 $0106 : nop;


if konstanta 50 == W then inc else dec
Code:

  if 50 == W then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $0100 : xorlw   $32;
 $0101 : btfss   STATUS,Z;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


if konstanta 50 <> W then inc else dec
Code:

  if 50 <> W then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

  
 $0100 : xorlw   $32;
 $0101 : btfsc   STATUS,Z;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


Sve ovo su slucajevi za if...then...else... strukturu. Za obicnu if...then... strukturu izbacio bi se donji deo.
TEMP varijablu je pozeljno staviti u deljene (izmedju svih banki) registre.
Code:

var shared_bank [0x70..0x7E]
  <
   TEMP  : byte
  >


Koriscenjem "nestandardnog" W registra kao varijable se malo pobeglo od osnovnih tipova varijabli vaseg MMA, ali smatram da bi ipak pozeljno bilo uvesti i ovaj tip, jer se (relativno) najkrace prevodi, a cesto se srece u asemblerskim programima, bar za PIC.

[Ovu poruku je menjao Stojan Trifunovic dana 08.08.2008. u 08:38 GMT+1]
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori08.08.2008. u 08:40 - pre 192 meseci
Da ne bih duzio sa ostalim if...then...else... primerima, da probam da implementiram i ostale programske strukture.

Buduci da u korakovom uputstvu programska struktura repeat...until... koristi nizove koje PIC16 serija ne podrzava najbolje, ogranicicu se na (za PIC16) jednostavnije primere.

Struktura repeat SABIRAK + 5 until SABIRAK > 50 bi izgledala ovako:
Code:

repeat
  movlw   5;
  addwf   SABIRAK,F;
until SABIRAK > 50
nop;


$0100 : movlw    $05;
$0101 : addwf    SABIRAK,F;
$0102 : movf     SABIRAK,W
$0103 : sublw    $32;
$0104 : btfsc    STATUS,C;
$0105 : goto     $0100;
$0106 : nop;


Ovaj kod bi se mogao dodatno optimizovati za slucajeve brojenja unapred (samo do 256) ili unazad (samo do 0) koristeci incfsz ili decfsz instrukciju:

repeat SABIRAK + 5, dec INDEX until INDEKS = 0
Code:

repeat
  movlw   5;
  addwf   SABIRAK,F;
  decfsz  INDEX,F;
until INDEX = 0
nop;


$0100 : movlw    $05;
$0101 : addwf    SABIRAK,F;
$0102 : decfsz   INDEKS,F;
$0103 : goto     $0100
$0104 : nop;


Ovaj slucaj bio bi ipak tezi za implementaciju jer bi kompajler morao gledati i instrukciju pre until direktive, i na osnovu nje detektovati da li moze dodati samo goto instrukciju ili mora izvrsiti i odgovarajuce testiranje.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori08.08.2008. u 11:26 - pre 192 meseci
Da pogledamo ostale strukture. Case...of... struktura bi se mogla ovako napraviti:
Code:

case W of
1,9,21,30 : incf [49],F;
31,50,70,90 : decf [49],F;
else clrf [49];
end;
nop;


 $0100 : xorlw $01;  // Da li je W == 1?
 $0101 : btfsc STATUS,Z;
 $0102 : goto  $011A;
 $0103 : xorlw $08;  // Da li je W == 9? W je sada postao (W XOR $01) XOR ($01 XOR $09), sto je isto kao W XOR $09.
 $0104 : btfsc STATUS,Z;
 $0105 : goto  $011A;
 $0106 : xorlw $1D;  // W == 21? ($08 XOR $15)
 $0107 : btfsc STATUS,Z;
 $0108 : goto  $011A;
 $0109 : xorlw $03;  // W == 30? ($1D XOR $1E)
 $010A : btfsc STATUS,Z;
 $010B : goto  $011A;
 
 $010C : xorlw $1C;  // W == 31? ($03 XOR $1F)
 $010D : btfsc STATUS,Z;
 $010E : goto  $011C;
 $010F : xorlw $2E;  // W == 50? ($1C XOR $32)
 $0110 : btfsc STATUS,Z;
 $0111 : goto  $011C;
 $0112 : xorlw $68;  // W == 70? ($2E XOR $46)
 $0113 : btfsc STATUS,Z;
 $0114 : goto  $011C;
 $0115 : xorlw $32;  // W == 90? ($68 XOR $5A)
 $0116 : btfsc STATUS,Z;
 $0117 : goto  $011C;
 
 $0118 : clrf  [49];    // deo za else
 $0119 : goto  $011D;
 
 $011A : incf  [49],F;  // incf
 $011B : goto  $011D;
 
 $011C : decf  [49],F;  // decf
 $011D : nop;           // nastavak

Kompajler bi morao automatski izracunavati XOR za svaki sledeci clan.
Zasto je upotrebljen ovako nerazumljiv (spagete) kod? Zato sto je najoptimizovaniji, i zato sto ne zahteva TEMP registar. Kada se W dva puta XOR-uje istom vrednoscu, vraca mu se originalna vrednost. Jeste komplikovanije, ali komplikovaniji je i quick sort algoritam, pa je ipak najbrzi. Ionako ce kod biti skriven od programera.
Naravno da se ovo moglo izbeci, ali onda bi se za svako poredjenje pored TEMP registra trosila instrukcija vise.

Verovatno bi prakticnije bilo da se instrukcije koje slede u slucaju ispunjenja (i neispunjenja) uslova stave u bloku ovako:
Code:

case W of
1,9,21,30 :
  begin
    incf [49],F;
  end
31,50,70,90 :
  begin
    decf [49],F;
  end
else
  begin
    clrf [49];
  end;
nop;



Mislim da nisam najbolje shvatio sintaksu i komparaciju iz vaseg uputstva . Konkretno, sta ce se dogoditi sa sledecim kodom:
[/code]
ldaa [bb];
case AccA of
1,9,21..30 : inca;
31..50,70..90 : deca;
else clra;
end;
staa [bb];
[/code]
Znaci li to inkrementaciju ukoliko je vrednost u akumulatoru u opsegu od 21 do 30 i dekrementaciju ukoliko je od 31 do 50 i od 70 do 90 ili nesto drugo?
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori08.08.2008. u 13:01 - pre 192 meseci
Sto se toce primera za koji kazes da nisi shvatio, ustvari, dobro si ga shvatio. Ako se brojevi nalaze jedan za drugim nema potrebe komparacija sa njuma nego samo sa granicama opsega,to je krace, zar ne.

Sve primere si odlicno rucno preveo, i sigurno naslucuhes da bi to bilo lako i kompajleru. Uslov koji pises kao w > 50 nije praktican, on nije upotrebljiv za dvobajtve i visebajtbe varijable. Video si da ja tu koristim samo znake uporedjenja koji u stvari testiraju flegove u statsusnom registru. Tako ako longint testiras da li je nula, orujes sve bajtove, i testitas dali je resultat orovanja 0, odnosno da li se setovao Z fleg.

Simbolne znake za uslov koristim sa znacenjem:

Code:

Za neoznacene brojeve:

IfSimbol      Zavisnost od flegova   Mnemonik
   =                  if Z = 1         beq
  <>                  if Z = 0         bne
   <                  if C = 1         bcs/blo
  <=                  if C+Z = 1       bls
   >                  if C+Z = 0       bhi
  >=                  if C = 0         bcc/bhs


Za oznacene brojeve:

IfSimbol      Zavisnost od flegova      Mnemonik
   +            if N = 0                  bpl
   -            if N = 1                  bmi
  =0            if Z = 1                  beq
 <>0            if Z = 0                  bne
  <0            if N eor V                blt
 <=0            if Z+(N eor V) = 1        ble
  >0            if Z+(N eor V) = 0        bgt
 >=0            if N eor V = 0            bge


Ostali simboli zna~e:

IfSimbol       Zavisnost od flegova    Mnemonik
  cc                  if C = 0          Bcc/bhs
 sc/cs                if C = 1          Bcs/blo
 cv/vc                if V = 0          bvc
 sv/vs                if V = 1          bvs





N je fleg za znak, a V je fleg za prekoracenje oznacenih brojeva

Kao sto vidis, posle bilo kojih operacija sa visebajtnim brojevima testiram flegove statusnoig registra. Da ne buh pamtio, sto mi nikada ne bi uspelo, da koristim ble, bgt, bge i t. d. vec mi je to jednostavnije sa uvodjenjem ovih znakova uporedjenja. Zapazas da kada se testira uporedjenje oznacenih brojeva, da se uz znake uporedjenja pise 0.

I repeat..until si dobro uradio, ali ja bih uz until napisao:

until decr(INDEX) =0;

a izostavio decfsz INDEX,F; ali bi kompajler preveo:

decfsz INDEX,F;
goto $0100;

Tablica koju sam prikazao je potpuna sa svim skokovima. Ali PIC nema potpunu tablicu, i u pravu si sto kazes da bi se tu potrosilo malo vise koda kako bi se obuhvatili svi slucajevi.

Dakle, ovo sa uslovnim granjanjima bi se dalo resiti, ostaje problem brojeva sa znakom. Jedna od tehnika je da svako osnaceni bajt bude uvecan za 128, kako bi uvk bio pozitivan. Ali, pri svakom sabiranju takva dva bajta treba oduzeti 128 (jer bi rezultat bio uvecan za 256), a kod oduzimanja treba dodati 128. Dvobajtne oznacene vrednosti trebaju da budu uvecane za 32768 i t. d. No, srecom malo se koriste oznaceni brojevi.

Ostaje za mene nepoznata stvar, a to su lokalne dinamicke varijable. Video sam kako to rade C kompajleri, ali mi nije mnogo jasno. Oni kao da prvo analiziraju koja funkcija poziva neku drugu, i koliko u jednom trenutku ima najvise lokalnih varijabli, i onda prostor za njih obezbedjuje na RAM-u. Taj mehanizam mi se cini komplikovanim. Ima li neko ilju ideju?

Pozdrav
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori08.08.2008. u 23:02 - pre 192 meseci
Uslov W < 50 (i ostali) svakako nije praktican za visebajtne varijable, ali jos nisam poceo ni implementaciju jednobajtnih, a kamoli visebajtnih varijabli. Kada budem, krenucu od if...then...else strukture sa testom npr. if GODINA > 2008 then inc else dec.

U pravu ste za decfsz. Ipak je bolje "until decr(INDEX) =0;".

Za dinamicke varijable, ne znam kako su resene u C, ali u relokativnom asemblerskom modu o njima brine linker. Kako je prethodno potrebno definisati sve varijable koje se koriste u programu kao i pripadnost bankama (BANK0, BANK1, SHARED, OVR-za dinamicke varijable) ali ne stavljajuci im apsolutnu adresu, linker ce svaku varijablu koja pripada OVR sekciji jednostavno prebrisati nakon izlaska iz tekuce procedure (fajla). To naravno nije resenje ukoliko se zeli gnezdjenje procedura, ali je ipak kakvo takvo resenje.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori09.08.2008. u 06:46 - pre 192 meseci
Kako mi je sada jasnija case...of... struktura, nastavljam sa njom, ali i dalje samo za W.
Code:

case W of
1,9,21..30 : incf [49],F;
31..50,70..90 : decf [49],F;
else clrf [49];
end;
nop;

 $0100 : movwf TEMP;
 $0101 : xorlw $01;       // Da li je W == 1?
 $0102 : btfsc STATUS,Z;
 $0103 : goto  $0121;     // Jeste. Idi na inc
 $0104 : xorlw $08;       // Da li je W == 9?
 $0105 : btfsc STATUS,Z;
 $0106 : goto  $0121;     // Jeste. Idi na inc
 
 $0107 : movf  TEMP,W;
 $0108 : sublw $15;       // W > 21?
 $0109 : btfsc STATUS,C;
 $010A : goto  $010F;     // Nije, idi dalje na provere.
 $010B : movlw $1E;       // Jeste. W < 30
 $010C : subwf TEMP,W;
 $010D : btfss STATUS,C;
 $010E : goto  $0121;     // Jeste. Idi na inc

 $010F : movf  TEMP,W;
 $0110 : sublw $1F;       // W > 31?
 $0111 : btfsc STATUS,C;
 $0112 : goto  $0117;     // Nije, idi dalje na provere.
 $0113 : movlw $32;       // Jeste. W < 50?
 $0114 : subwf TEMP,W;
 $0115 : btfss STATUS,C;
 $0116 : goto  $0123;     // Jeste. Idi na dec

 $0117 : movf  TEMP,W;
 $0118 : sublw $46;       // W > 70?
 $0119 : btfsc STATUS,C;
 $011A : goto  $011F;     // Nije, idi dalje na provere.
 $011B : movlw $32;       // Jeste. W < 5A?
 $011C : subwf TEMP,W;
 $011D : btfss STATUS,C;
 $011E : goto  $0123;     // Jeste. Idi na dec

 $011F : clrf  [49];      // deo za else
 $0120 : goto  $011D;
 
 $0121 : incf  [49],F;    // inc
 $0122 : goto  $011D;
 
 $0123 : decf  [49],F;    // dec
 $0124 : nop;             // nastavak


Sve pojedinacne case slucajeve kompajler bi trebao (za slucaj da programer to nije uradio) prebaciti na pocetak koda, ovako:
Code:

Umesto:
case W of
1,9,21..30,18,93 : incf [49],F;
31..50,70..90,55,99 : decf [49],F;

staviti:
case W of
1,9,18,93,21..30 : incf [49],F;
55,99,31..50,70..90 : decf [49],F;
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori09.08.2008. u 06:59 - pre 192 meseci
Upravo si mi dao jednu korisnu ideju.

Izraza sam naravno izbacio jer zapravo oni cine kod manje efikasnim (na primer a+b*c >= d*(d-c) i t. d.) u asembleru zavisno od varijabli programer moze bolje iskoristiti neke specificnosti i napisati kraci i brzi kod od onog koji bi na primer C generisao. Negde sam video PASCAL kompajler (zaboravio sam za koji MCU) gde izrazi mogu da budu samo tipa c := a opeaija b; i nista vise. Dakle, nema medjurezultata i ima sanse da kod bude vrlo efikasan. Tako i tvoje Godina > 2008 mi daje ideju da izraz bude sto prostiji: a := b ili a operator uporedjivanje b. Zapravo izraz bi bio a operator b, gde operator moze da bude samo operator dodele ili relacioni operator (oparator uporedjivanja).

Posto sam zavrsio 3 verziju kompajlera, sada bas radim na ovim finesama. Ideja po kojoj radim je da koristim makroe, Tako sam napisao macro Value() koja se koristi a := Value(b). Vec sam napravio da makro moze da bude parametar funkcije ili procedure, i namera mi je da makro ubacim u if..then i ostale uslovne strukture. Prednost makroa je sto moze da ima vise parametara i da realizuje i slozenije izraze. Zato mi tvoja ideja stvara dilemu, vrlo je ocigledna i citljiva za razliku od makroa, koje jos moras i da pises, doduse samo jednom. Najvise mrzim kada imam dilemu, moracu da dobro odvagam ove dve mogucnosti.

Pozdrav.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori09.08.2008. u 07:31 - pre 192 meseci
Da krenem sa testom jednobajtne neoznacene varijable (byte) i konstante. Neka naziv varijable bude BROJ.

if BROJ > konstante 50 then inc else dec
Code:

  if BROJ > 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    BROJ,W
 $0100 : sublw   $32;
 $0101 : btfsc   STATUS,C;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


if BROJ < konstante 50 then inc else dec
Code:

  if BROJ < 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0101 : movlw   $32;
 $0102 : subwf   BROJ,W;
 $0103 : btfsc   STATUS,C;
 $0104 : goto    $0107;
 $0105 : incf    [$31],W;
 $0106 : goto    $0108;
 $0107 : decf    [$31],W;
 $0108 : nop;


if BROJ >= konstante 50 then inc else dec
Code:

  if BROJ >= 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0101 : movlw   $32;
 $0102 : subwf   BROJ,W;
 $0103 : btfss   STATUS,C;
 $0104 : goto    $0107;
 $0105 : incf    [$31],W;
 $0106 : goto    $0108;
 $0107 : decf    [$31],W;
 $0108 : nop;


if BROJ <= konstante 50 then inc else dec
Code:

  if BROJ <= 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    BROJ,W
 $0100 : sublw   $32;
 $0101 : btfss   STATUS,C;
 $0102 : goto    $0105;
 $0103 : incf    [$31],0;
 $0104 : goto    $0106;
 $0105 : decf    [$31],0;
 $0106 : nop;


if BROJ == konstanta 50 then inc else dec
Code:

  if BROJ == 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    BROJ,W
 $0100 : xorlw   $32;
 $0101 : btfss   STATUS,Z;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


if BROJ <> konstante 50 then inc else dec
Code:

  if BROJ <> 50 then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    BROJ,W
 $0100 : xorlw   $32;
 $0101 : btfsc   STATUS,Z;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;




Sada evo primera za testiranje konstante sa jednobajtnom varijablom BROJ.

if konstanta 50 < BROJ then inc else dec
Code:

  if 50 < BROJ then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    BROJ,W
 $0100 : sublw   $32;
 $0101 : btfsc   STATUS,C;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


if konstanta 50 > BROJ then inc else dec
Code:

  if 50 > BROJ then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0101 : movlw   $32;
 $0102 : subwf   BROJ,W;
 $0103 : btfsc   STATUS,C;
 $0104 : goto    $0107;
 $0105 : incf    [$31],W;
 $0106 : goto    $0108;
 $0107 : decf    [$31],W;
 $0108 : nop;


if konstanta 50 <= BROJ then inc else dec
Code:

  if 50 <= BROJ then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0101 : movlw   $32;
 $0102 : subwf   BROJ,W;
 $0103 : btfss   STATUS,C;
 $0104 : goto    $0107;
 $0105 : incf    [$31],W;
 $0106 : goto    $0108;
 $0107 : decf    [$31],W;
 $0108 : nop;


if konstanta 50 >= BROJ then inc else dec
Code:

  if 50 >= BROJ then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    BROJ,W
 $0100 : sublw   $32;
 $0101 : btfss   STATUS,C;
 $0102 : goto    $0105;
 $0103 : incf    [$31],0;
 $0104 : goto    $0106;
 $0105 : decf    [$31],0;
 $0106 : nop;


if konstanta 50 == BROJ then inc else dec
Code:

  if 50 == BROJ then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    BROJ,W
 $0100 : xorlw   $32;
 $0101 : btfss   STATUS,Z;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


if konstanta 50 <> BROJ then inc else dec
Code:

  if 50 <> BROJ then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    BROJ,W
 $0100 : xorlw   $32;
 $0101 : btfsc   STATUS,Z;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;

Ocigledno je da je kod samo neznatno izmenjen.



Nisam bas najbolje shvatio Vas zadnji post, ali pretpostavljam da je u pitanju sledeci slucaj.
Na pocetku "GODINA := (((A + B) * C) / D)" i kasnije "if GODINA == 2009 then...else..."
Mislim da je ovo daleko prakticnije od "if (((A + B) * C) / D) == 2009 then...else..." u pogledu razumljivosti koda, ali mozda malo manje prakticno u pogledu njegove optimizovanosti. U ovom slucaju, ipak bih namerno zrtvovao par instrukcija zbog bolje citljivosti.

Ne bih se toliko brinuo oko izraza. U asembleru ce se moci odraditi na koji god moguci nacin, pa eto i makroima. Ipak, uporedjivanje visebajtnih varijabli je itekako dobrodoslo.

Jedino eventualno poboljsanje koje bi bilo korisno uvesti su naprednije mogucnosti uslovnog grananja sa OR, AND i NOT logickim operacijama poput: "if GODINA >= 2009 AND GODINA <= 2011 then PRESTUPNA_GODINA == false", medjutim nisam siguran koliko bi njih bilo moguce optimizovati.
 
Odgovor na temu

korak
Nis

Član broj: 125522
Poruke: 622
*.dynamic.sbb.rs.



+7 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori09.08.2008. u 14:37 - pre 192 meseci
Sa primerom izraza sam samo hteo da ukazem na cinjenicu da dok se on prevodi postoje medjurezultati koji negde mora da se pamte. Obocno se oni pamte na steku, ali to nije moguce kod PIC-a osim da se za to odvoji poseban prostor na RAM-u.

Teoretski ne postoji prepreka da visi programski jezik ne prevodi 100% efikasno, ali prakticno to je nemoguce. Postoje razradjeni metodi optimizacije prevodjenja ali svi oni uvode neke predpostavke da bi postupak kompajliranja mogao da se realizuje. Upravo te predpostavke dovode do toga da se smanjuje efikasnost prevodjenja.

Na primer sabiramo dve varijable koje su kompatibilnih tipova, sto znaci da mogu da se saberu.

1. svaka od njih moze biti: byte, shortint, integer, word, longint, longword, to je 15 kombinacija;
2. svaka od njih moze biti karakter ili string, to je 4 kombinacije
3. svaka moze biti skup, to je 1 kombinacija

Ukupno imamo 20 kombinaija koda samo za sabiranje. Ako svaka varijabla moze biti staticka i dinamicka to je 20 x 4 = 100 kombinacija. Kada se tome dodaju i druge operacije (oduzimanje, mnozenje, deljenje, siftanje, logicke operacije i t. d.) broj kombinacija kodova pravoda se priblizava broju od oko 800. Ovu analizu sam pravio. E sada, moguce je uvesti niz predpostavki, ogranicenja na kojim registrima ce se vrsiti operacije i t. d. i da se problem pojednostavi tako da moze da se resi za razumno vreme. Cena toga je smanjenje efikasnosti.

Ja sam se opredelio da ostanem sto blize asembleru, a da napravim snazan mehanizam makroa kojima mogu da se resavaju problemi sa slozenijim izrazima Osim toga makroi, kako sam ih ja koncipirao pruzaju i neke sitne elemente objektnog programiranja, mada mi to nije bilo ni na kraj pameti.

Dakle, treba drzati sto tesnju vezu sa asemblerom. Ono sto si napisao odgovara tome, ali ako budes sirio problem komplikovace se geometrijskom progresijom.

Pozdrav.
 
Odgovor na temu

Stojan Trifunovic

Član broj: 15156
Poruke: 366
*.yu
Via: [es] mailing liste



+8 Profil

icon Re: programski jezici za mikrokontrolere pitanja i odgovori09.08.2008. u 16:44 - pre 192 meseci
Pa nista. Realizujte onda samo poredjenje ovih varijabli, a matematiku prepustite programeru i asembleru.

Evo sada primera za poredjenje dve varijable (A i B) byte tipa.

if A > B then inc else dec
Code:

  if A > B then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    A,W;
 $0100 : subwf   B,W;
 $0101 : btfsc   STATUS,C;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


if A < B then inc else dec
Code:

  if A < B then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0101 : movf    B,W;
 $0102 : subwf   A,W;
 $0103 : btfsc   STATUS,C;
 $0104 : goto    $0107;
 $0105 : incf    [$31],W;
 $0106 : goto    $0108;
 $0107 : decf    [$31],W;
 $0108 : nop;


if A >= B then inc else dec
Code:

  if A >= B then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;


 $0101 : movf    B,W;
 $0102 : subwf   A,W;
 $0103 : btfss   STATUS,C;
 $0104 : goto    $0107;
 $0105 : incf    [$31],W;
 $0106 : goto    $0108;
 $0107 : decf    [$31],W;
 $0108 : nop;


if A <= B then inc else dec
Code:

  if A <= B then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    A,W;
 $0100 : subwf   B,W;
 $0101 : btfss   STATUS,C;
 $0102 : goto    $0105;
 $0103 : incf    [$31],0;
 $0104 : goto    $0106;
 $0105 : decf    [$31],0;
 $0106 : nop;


if A == B then inc else dec
Code:

  if A == B then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    A,W;
 $0100 : xorwf   B,W;
 $0101 : btfss   STATUS,Z;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


if A <> B then inc else dec
Code:

  if A <> B then
  begin
    incf [49],W;
  end
  else
  begin
    decf [49],W;
  end
  nop;

 $00FF : movf    A,W;
 $0100 : xorwf   B,W;
 $0101 : btfsc   STATUS,Z;
 $0102 : goto    $0105;
 $0103 : incf    [$31],W;
 $0104 : goto    $0106;
 $0105 : decf    [$31],W;
 $0106 : nop;


Narednih 6 slucajeva (npr. "if B >A then...") nema smisla obradjivati, jer se koristi potpuno isti kod.
 
Odgovor na temu

[es] :: Elektronika :: Mikrokontroleri :: programski jezici za mikrokontrolere pitanja i odgovori

Strane: < .. 1 2 3 4 5 6 7

[ Pregleda: 17965 | Odgovora: 120 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.