=?iso-8859-2?Q?Zrozumie=E6_asemblera_dla_AVR=F3w?=



Masz problem? Zapytaj na forum elektroda.pl

Poprzedni Następny
Wiadomość
Spis treści
From: Mateusz Majchrzycki <spam_at_nospam_spam.spam>
Subject: =?iso-8859-2?Q?Zrozumie=E6_asemblera_dla_AVR=F3w?=
Date: Sun, 5 Dec 2004 20:25:16 +0000 (UTC)


Właśnie siedzę i uczę sie asemblera na AVRy. Wszystko narazie idzie
ładnie, wspomagam sie kilogramami dokumentacji, ale czegoś w niej nie
rozumiem.
Dokłądniej to chodzi o intrukcje skoków. Np. taka instrukcja RJMP. Jako
argument podajemy jej adres pod jaki ma skoczyć. Wszystko ładnie
pięknie. Ale dlaczego w AVR Instruction Set oraz w manualu do ATiny26
(na nim będę ćwiczył, narazie symulacja w AVR Studio) w sekcji Operations
dla instrukcji RJMP jest napisane:
PC <- PC + k + 1
Ja rozumiem to tak że do aktualnego stanu PC dodawany jest argument k
oraz 1, i wartosć tego jest nowym licznikiem rozkazów. A tymczasem
działa to tak ze licznik rozkazów zastępowany jest zinkrementowanym
argumentem k. Gdybym miał opisać jak w rzeczywistosci działa instrukcja
RJMP to napisałbym:
PC <- k + 1
Gdzie tkwi błąd w moim rozumowaniu?
I przy okazji zapytam się, czy jest jakiś sposób na ominięcie iluś
rozkazów korzystajac z porównań i skoków, czy też muszę grupę rozkazów
zetykietować i pomijać w programie skok do tej etykiety?
Z góry dziękuje za pomoc :)

--
+-----Pozdrawiam------+------------------------+
\ Mateusz Majchrzycki \ W życiu liczą się \
\ MateoM[at]poczta.fm \ drobne przyjemności... \
+------GG#897890------+------------------------+

Poprzedni Następny
Wiadomość
Spis treści
From: Waldemar Krzok <waldemar.krzok_at_nospam_t-online.de>
Subject: Re: =?ISO-8859-2?Q?Zrozumie=E6_asemblera_dla_AVR=F3w?=
Date: Sun, 05 Dec 2004 21:45:10 +0100


Mateusz Majchrzycki wrote:

Właśnie siedzę i uczę sie asemblera na AVRy. Wszystko narazie idzie
ładnie, wspomagam sie kilogramami dokumentacji, ale czegoś w niej nie
rozumiem.
Dokłądniej to chodzi o intrukcje skoków. Np. taka instrukcja RJMP. Jako
argument podajemy jej adres pod jaki ma skoczyć. Wszystko ładnie
pięknie. Ale dlaczego w AVR Instruction Set oraz w manualu do ATiny26
(na nim będę ćwiczył, narazie symulacja w AVR Studio) w sekcji Operations
dla instrukcji RJMP jest napisane:
PC <- PC + k + 1
Ja rozumiem to tak że do aktualnego stanu PC dodawany jest argument k
oraz 1, i wartosć tego jest nowym licznikiem rozkazów. A tymczasem
działa to tak ze licznik rozkazów zastępowany jest zinkrementowanym
argumentem k. Gdybym miał opisać jak w rzeczywistosci działa instrukcja
RJMP to napisałbym:
PC <- k + 1
Gdzie tkwi błąd w moim rozumowaniu?
działa to tak, jak jest opisane w manualu. A to, że w assemblerze piszesz
RJMP <etykieta> to akurat nieważne. Kompilator czyta adres twojej etykiety
i pozycji, gdzie akurat jest i koduje w instrukcji różnicę między aktualna
pozycją i etykietą.

I przy okazji zapytam się, czy jest jakiś sposób na ominięcie iluś
rozkazów korzystajac z porównań i skoków, czy też muszę grupę rozkazów
zetykietować i pomijać w programie skok do tej etykiety?

nie za bardzo rozumiem o co ci chodzi. Co chcesz robić?

Waldek


Poprzedni Następny
Wiadomość
Spis treści
From: Mateusz Majchrzycki <spam_at_nospam_spam.spam>
Subject: =?iso-8859-2?Q?Re:_Zrozumie=E6_asemblera_dla_AVR=F3w?=
Date: Sun, 5 Dec 2004 21:53:19 +0000 (UTC)


Pewnego dnia Waldemar Krzok <waldemar.krzok_at_nospam_t-online.de>
nastukał(a):
Gdzie tkwi błąd w moim rozumowaniu?
działa to tak, jak jest opisane w manualu. A to, że w assemblerze
piszesz RJMP <etykieta> to akurat nieważne. Kompilator czyta adres
twojej etykiety i pozycji, gdzie akurat jest i koduje w instrukcji
różnicę między aktualna pozycją i etykietą.

No dobrze, ale proszę mi w takiej sytuacji powiedzieć dokąd skoczy
program przy takich instrukcjach gdy z portu a odczyta 0b11111110.
Według moich zamirzeń miał przeskoczyć 4 instrukcje (brne 4 => PC <- PC
+ 4 + 1), czyli przejsc do następnego porównania

Poprzedni Następny
Wiadomość
Spis treści
From: Waldemar Krzok <waldemar.krzok_at_nospam_t-online.de>
Subject: Re: =?ISO-8859-2?Q?Zrozumie=E6_asemblera_dla_AVR=F3w?=
Date: Sun, 05 Dec 2004 23:16:39 +0100


Mateusz Majchrzycki wrote:

No dobrze, ale proszę mi w takiej sytuacji powiedzieć dokąd skoczy
program przy takich instrukcjach gdy z portu a odczyta 0b11111110.
Według moich zamirzeń miał przeskoczyć 4 instrukcje (brne 4 => PC <- PC
+ 4 + 1), czyli przejsc do następnego porównania:
============kod===========
.def ior=r16
.cseg
ldi ior,ramend
out sp,ior
ldi ior,0b00111110
out ddrb,ior
ldi ior,0b00000100
out portb,ior
ldi ior,0b11111111
out porta,ior
sbi portb,portb5

loop:
in ior,pina
sbrs ior,0
rjmp routesetup
rjmp loop

routesetup:
neg ior
cpi ior,1
brne 4
andi r20,0b00111111
ori r20,0b01000000
andi r21,0b00001111
ori r21,0b10100000
cpi ior,2
brne 4
andi r22,0b00111111
ori r22,0b01000000
andi r23,0b00001111
ori r23,0b10100000
rjmp loop
======koniec==kodu========
A w moim końcowym pytaniu chodziło o to jak ominąć te 4 instrukcje po
brne 4 jeżeli ior będzie różne od 1.

no właśnie po to sa etykiety, byś nie musiał liczyć. BRNE 4 przeskakuje 4
bajty, a nie 4 instrukcje. W tym przypadku lądujesz w połowie tego, co
chcesz. Aby działało jak chcesz, musisz napisać BRNE 8. Tylko szukanie
błędów po tym, jak program ma trochę więcej niz 20 linijek może doprowadzić
jezuitę do kurwienia na czym świat stoi. Daj te etykiety, nawet jakby ich
100 sztuk było, to i tak łatwiej szukać. Ja przywykłem dawać funkcjom nazwy
w stylu f01_cotafunkcjarobi, a etykietom potem f01_001 itd, jak te etykiety
tylko do realizacji instrukcji switch służą.

Waldek


Poprzedni Następny
Wiadomość
Spis treści
From: "Paweł" <pawel.neo_at_nospam_neostrada.pl>
Subject: Re: Zrozumieć asemblera dla AVRów
Date: Sun, 5 Dec 2004 23:19:03 +0100


.... BRNE 4 przeskakuje 4
bajty, a nie 4 instrukcje.

Kompilator to zinterpretuje jako skok pod adres 4.

Paweł



Poprzedni Następny
Wiadomość
Spis treści
From: Mateusz Majchrzycki <spam_at_nospam_spam.spam>
Subject: =?iso-8859-2?Q?Re:_Zrozumie=E6_asemblera_dla_AVR=F3w?=
Date: Sun, 5 Dec 2004 22:30:25 +0000 (UTC)


Pewnego dnia Paweł <pawel.neo_at_nospam_neostrada.pl> nastukał(a):
.... BRNE 4 przeskakuje 4
bajty, a nie 4 instrukcje.
Kompilator to zinterpretuje jako skok pod adres 4.

No i doszliśmy do tego co mnie dręczy. Przeskoczy 4 czy skoczy pod 4?
Według zapisów z Instruction Set powinien przeskoczyć 4, ale według
tego co mi serwuje AVR Studio to skoczy pod 4. Kto ma racje i dlaczego?

--
+-----Pozdrawiam------+------------------------+
\ Mateusz Majchrzycki \ W życiu liczą się \
\ MateoM[at]poczta.fm \ drobne przyjemności... \
+------GG#897890------+------------------------+

Poprzedni Następny
Wiadomość
Spis treści
From: "Paweł" <pawel.neo_at_nospam_neostrada.pl>
Subject: Re: Zrozumieć asemblera dla AVRów
Date: Sun, 5 Dec 2004 22:47:48 +0100


dla instrukcji RJMP jest napisane:
PC <- PC + k + 1
Ja rozumiem to tak że do aktualnego stanu PC dodawany jest argument k
oraz 1, i wartosć tego jest nowym licznikiem rozkazów. A tymczasem
działa to tak ze licznik rozkazów zastępowany jest zinkrementowanym
argumentem k. Gdybym miał opisać jak w rzeczywistosci działa instrukcja
RJMP to napisałbym:
PC <- k + 1
Gdzie tkwi błąd w moim rozumowaniu?

Zapewne pisząc program nie wpisujesz kodów bajtowych poszczególnych
instrukcji. Używasz słów które są przeznaczone dla kompilatora.
W przypadku RJMP kompilator na podstawie np. etykiet oblicza jaki ma być
argument tej instrukcji i wpisuje odpowiednią wartość do pliku wynikowego.
W AVR Studio wyświetl okienko View->Disassembler to zobaczysz co faktycznie
stworzył kompilator

I przy okazji zapytam się, czy jest jakiś sposób na ominięcie iluś
rozkazów korzystajac z porównań i skoków, czy też muszę grupę rozkazów
zetykietować i pomijać w programie skok do tej etykiety?

Nie wiem czy AVR Studio jest odpowiednia dyrektywa oznaczająca aktualną
wartość PC. Załóżmy dla przykładu, że tak i jest to znak $.
Czyli RJMP $+3 lub ewentualnie RJMP $+6 (w AVRach instrukcje zajmują 2
bajty) będzie oznaczało ominięcie trzech instrukcji.

Paweł



Poprzedni Następny
Wiadomość
Spis treści
From: Mateusz Majchrzycki <spam_at_nospam_spam.spam>
Subject: =?iso-8859-2?Q?Re:_Zrozumie=E6_asemblera_dla_AVR=F3w?=
Date: Sun, 5 Dec 2004 22:20:40 +0000 (UTC)


Pewnego dnia Paweł <pawel.neo_at_nospam_neostrada.pl> nastukał(a):
Zapewne pisząc program nie wpisujesz kodów bajtowych
poszczególnych instrukcji. Używasz słów które są przeznaczone dla
kompilatora. W przypadku RJMP kompilator na podstawie np. etykiet
oblicza jaki ma być argument tej instrukcji i wpisuje odpowiednią
wartość do pliku wynikowego. W AVR Studio wyświetl okienko
View->Disassembler to zobaczysz co faktycznie stworzył kompilator

No dobrze. Ale to i tak nie tłumaczy dlaczego pisząc np. brne 10
program skoczy do 10 instrukcji od początku programu, a nie przeskoczy
10 instrukcji. Cały czas rozchodzi mi się o ten zapis w Instruction
Set:
PC <- PC + k + 1
gdzie k to argument instrukcji brne.
Według mnie, przy powyższym zapisie, instrukcja brne 10 powinna zostać
wykonana jako PC <- PC+10+1, a nie jako PC<-10+1.
To mnie własnie cały czas dręczy

Nie wiem czy AVR Studio jest odpowiednia dyrektywa oznaczająca
aktualną wartość PC. Załóżmy dla przykładu, że tak i jest to znak
$. Czyli RJMP $+3 lub ewentualnie RJMP $+6 (w AVRach instrukcje
zajmują 2 bajty) będzie oznaczało ominięcie trzech instrukcji.

Poszukałem i jest. Nomen omen ta dyrektywa nazywa sie PC :)
Czyli mój zapis wygląda teraz brne PC+10. Ale mimo wszystko nie
tłumaczy to wyżej opisanego sposobu myślenia mojego i twórców avr-asm
/

--
+-----Pozdrawiam------+------------------------+
\ Mateusz Majchrzycki \ W życiu liczą się \
\ MateoM[at]poczta.fm \ drobne przyjemności... \
+------GG#897890------+------------------------+

Poprzedni Następny
Wiadomość
Spis treści
From: "Paweł" <pawel.neo_at_nospam_neostrada.pl>
Subject: Re: Zrozumieć asemblera dla AVRów
Date: Sun, 5 Dec 2004 23:45:54 +0100


No dobrze. Ale to i tak nie tłumaczy dlaczego pisząc np. brne 10
program skoczy do 10 instrukcji od początku programu, a nie przeskoczy
10 instrukcji. Cały czas rozchodzi mi się o ten zapis w Instruction
Set:
PC <- PC + k + 1
gdzie k to argument instrukcji brne.
Według mnie, przy powyższym zapisie, instrukcja brne 10 powinna zostać
wykonana jako PC <- PC+10+1, a nie jako PC<-10+1.
To mnie własnie cały czas dręczy

Instrukcja jaką wykonuje procesor to 2 bajty.
np. C0 07 oznacza wykonanie PC<-PC+7+1

Kompilator natomiast zakłada, że po RJMP będzie się znajdował fizyczny
adres.
Taka składnia języka jest znacznie wygodniejsza.


Paweł



Poprzedni Następny
Wiadomość
Spis treści
From: Mateusz Majchrzycki <spam_at_nospam_spam.spam>
Subject: =?iso-8859-2?Q?Re:_Zrozumie=E6_asemblera_dla_AVR=F3w?=
Date: Sun, 5 Dec 2004 23:00:49 +0000 (UTC)


Pewnego dnia Paweł <pawel.neo_at_nospam_neostrada.pl> nastukał(a):
Instrukcja jaką wykonuje procesor to 2 bajty.
np. C0 07 oznacza wykonanie PC<-PC+7+1
Kompilator natomiast zakłada, że po RJMP będzie się znajdował
fizyczny adres.
Taka składnia języka jest znacznie wygodniejsza.

Czyli zapisy w Instruction Set wprowadzają w błąd? No bo jeżeli
kompilator zapis
brne 10
interpretuje jako: PC<-10
to w takiej sytuacji zapis z manuala:
brne k
PC<-PC+k+1
wprowadza w błąd :/
A może ja dziwnie rozumuję :/
Zobaczymy jak to jutro będzie wyglądało.

--
+-----Pozdrawiam------+------------------------+
\ Mateusz Majchrzycki \ W życiu liczą się \
\ MateoM[at]poczta.fm \ drobne przyjemności... \
+------GG#897890------+------------------------+

Poprzedni Następny
Wiadomość
Spis treści
From: J.F. <jfox_nospam_at_nospam_poczta.onet.pl>
Subject: Re: Zrozumieć asemblera dla AVRów
Date: Mon, 06 Dec 2004 00:55:03 +0100


On Sun, 5 Dec 2004 23:00:49 +0000 (UTC), Mateusz Majchrzycki wrote:

Czyli zapisy w Instruction Set wprowadzają w błąd? No bo jeżeli
kompilator zapis
brne 10
interpretuje jako: PC<-10
to w takiej sytuacji zapis z manuala:
brne k
PC<-PC+k+1
wprowadza w błąd :/
A może ja dziwnie rozumuję :/

Dziwnie rozumujesz. Jak piszesz brne 10, to kompilator sprawdza pod
jakim adresem jest rozkaz brne, wylicza roznice i umieszcza w kodzie
rozkazu.

Wpisz brne 10 kilka razy pod rzad i zobacz jaki kod sie wygeneruje.

A dodatkowo - jesli wpiszesz brne <etykieta> to kompilator moze
roznice wyliczyc. Jesli brne 10 - to zazwyczaj dopiero linker
bedzie wiedzial pod jakim adresem umiesci ten rozkaz.

J.


Poprzedni Następny
Wiadomość
Spis treści
From: "T.M.F." <tfrancuz_at_nospam_nospam.mp.pl>
Subject: Re: =?ISO-8859-2?Q?Zrozumie=E6_asemblera_dla_AVR=F3w?=
Date: Sun, 05 Dec 2004 23:55:07 +0100



No dobrze. Ale to i tak nie tłumaczy dlaczego pisząc np. brne 10
program skoczy do 10 instrukcji od początku programu, a nie przeskoczy
10 instrukcji. Cały czas rozchodzi mi się o ten zapis w Instruction
Set:
PC <- PC + k + 1
gdzie k to argument instrukcji brne.
Według mnie, przy powyższym zapisie, instrukcja brne 10 powinna zostać
wykonana jako PC <- PC+10+1, a nie jako PC<-10+1.
To mnie własnie cały czas dręczy

Popelniasz blad w rozumowaniu - zapis brne 10 powie kopilatorowi, ze
chcesz skoczyc do instrukcji o adresie absolutnym rownym 10 i on to
przetlumaczy na brne xx, gdzie xx to roznica pomiedzy 10 i PC. Latwo sie
o tym przekonasz kompilujac taki kod, a nastepie ogladajac go w
disassemblerze, nie bedzie brne 10 tylko brne np. 138.
A przy okazji wartosc k w skokach wzglednych jest zapisywana w kodzie
uzupelnien, czyli wartosci powyzej 128 sa traktowane jako ujemne, np.
brne $FE to skok o jedna instrukcje wczesniej.
Zobacz cos takiego:
START:
BRNE 10

i
START:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
BRNE 10

Zobaczysz jaki kod ci wygeneruje assembler - za kazdym razem argument
BRNE bedzie inny mimo, ze ty ciagle wpisales 10. Co wiecej mozesz
stwierdzic, ze raz argumentem bedzie 10, a raz -10, w zaleznosci jak
jest polozona instrukcja BRNE wzgledem komorki pamieci o adresie 10.
Z kolei jedynka ktora jest dodawana wynika z faktu, ze w chwili
wykonywania skoku licznik instrukcji (PC) wskazuje juz na nastepna
instrukcje za BRNE. Wbrew pozorom takie zachowanie kompilatora jest
logiczne, bo zwykle wykonujesz BRNE etykieta - gdzie kompilator zamiast
etykieta podstawia po prostu jej adres, dlatego tez zapis BRNE 10 musi
byc traktowany jako skok do komorki o adresie 10, a nie skok o 10 slow
do przodu.

Z kolei odpowiadajac na twoje drugie pytanie dotyczace pomijania blokow
instrukcji - niestety tylko realizujac na poczatku bloku skok warunkowy.
W szczegolnym przypadku kiedy to jest wylacznie jedna instrukcja, ktora
chcesz warunkowo wykonac mozesz wykoszystac SBIC, SBIS, SBRC, SBRS.
Pozdrawiam,
T.M.F.



--
Inteligentny dom - http://idom.wizzard.one.pl
Teraz takze forum dyskusyjne
Zobacz, wyslij uwagi, dolacz sie do projektu.

Poprzedni Następny
Wiadomość
Spis treści
From: "mavs[NOSPAM]" <"mavs[NOSPAM]"_at_nospam_o2.pl>
Subject: Re: =?ISO-8859-2?Q?Zrozumie=E6_asemblera_dla_AVR=F3w?=
Date: Sun, 05 Dec 2004 23:55:58 +0100


Dnia 2004-12-05 21:25, Użytkownik Mateusz Majchrzycki napisał:
[...]
Gdybym miał opisać jak w rzeczywistosci działa instrukcja
RJMP to napisałbym:
PC <- k + 1
Gdzie tkwi błąd w moim rozumowaniu?

Blad z tego co czuje polega na tym ze RJMP to skrot od Relative Jump...
Oznacza to "skok względny". Wzgledny - w stosunku do aktualnego licznika
instrukcji! PC - Program Counter. Czyli skaczesz o [parametr] do przodu.
Nie wzgledem poczatku tylko wzgledem aktualnego polozenia w kodzie.
Dlatego masz PC+K... proste? :)


--
pozdr,
mavs

Poprzedni Następny
Wiadomość
Spis treści
From: "Marek A." <marcom_at_nospam_dgt.com.pl>
Subject: Re: Zrozumieć asemblera dla AVRów
Date: Mon, 6 Dec 2004 09:07:20 +0100



Użytkownik "Mateusz Majchrzycki" <spam_at_nospam_spam.spam> napisał w wiadomości
news:Xns95B6D8638D204XNSMateoM_at_nospam_192.168.0.1...
Właśnie siedzę i uczę sie asemblera na AVRy. Wszystko narazie idzie
ładnie, wspomagam sie kilogramami dokumentacji, ale czegoś w niej nie
rozumiem.
Dokłądniej to chodzi o intrukcje skoków. Np. taka instrukcja RJMP. Jako
argument podajemy jej adres pod jaki ma skoczyć. Wszystko ładnie
pięknie. Ale dlaczego w AVR Instruction Set oraz w manualu do ATiny26
(na nim będę ćwiczył, narazie symulacja w AVR Studio) w sekcji Operations
dla instrukcji RJMP jest napisane:
PC <- PC + k + 1
Ja rozumiem to tak że do aktualnego stanu PC dodawany jest argument k
oraz 1, i wartosć tego jest nowym licznikiem rozkazów. A tymczasem
działa to tak ze licznik rozkazów zastępowany jest zinkrementowanym
argumentem k. Gdybym miał opisać jak w rzeczywistosci działa instrukcja
RJMP to napisałbym:
PC <- k + 1
Gdzie tkwi błąd w moim rozumowaniu?
I przy okazji zapytam się, czy jest jakiś sposób na ominięcie iluś
rozkazów korzystajac z porównań i skoków, czy też muszę grupę rozkazów
zetykietować i pomijać w programie skok do tej etykiety?
Z góry dziękuje za pomoc :)

--
> +-----Pozdrawiam------+------------------------+
> \ Mateusz Majchrzycki \ W życiu liczą się \
> \ MateoM[at]poczta.fm \ drobne przyjemności... \
> +------GG#897890------+------------------------+



Poprzedni Następny
Wiadomość
Spis treści
From: "Marek A." <marcom_at_nospam_dgt.com.pl>
Subject: Re: Zrozumieć asemblera dla AVRów
Date: Mon, 6 Dec 2004 09:39:10 +0100


PC jest rejestrem 16-to bitowym(PCH i PCL). Zapis PC<=PC+k+1 oznacza ,że do
aktualnej wartości PC zostanie dodane przesunięcie k. Z tego względu, że
rejestr PC jest dwubajtowy i musi być zapisany w dwóch sąsiednich komórkach
pamięci, " +1 " oznacza następną sąsiednią komórkę pamięci a nie liczbę 1
która ma być dodana do przesunięcia k .