AVR STUDIO - ASM - Wersja do druku +- HomeMade (http://sp-hm.pl) +-- Dział: Oprogramowanie (/forum-84.html) +--- Dział: Technika programowania mikroprocesorów (/forum-85.html) +--- Wątek: AVR STUDIO - ASM (/thread-536.html) |
RE: AVR STUDIO - ASM - SP4EJT - 10-04-2012 19:05 Teorie znam ... nadal nie wiem gdzie to podgladnac w AVRStudio symulujac Atmege 32. RE: AVR STUDIO - ASM - SQ6ADE - 10-04-2012 19:10 A co chcesz podglądać ? Wskaźnik stosu czy dane na stosie składowane ? RE: AVR STUDIO - ASM - SP4EJT - 10-04-2012 19:31 Najlepiej i to i to, zebym zrozumial "do konca" dopiero zauwazylem cos co sie zwie "stack pointer" w AVRStudio - ale jeszcze nie sprawdzalem tego. ps. nadal przepraszam wszystkich za brak polskich znakow ale klawiatura do mojego laptopa kosztuje okolo 100zl, a jakos nie chce mi sie ich pozbywac RE: AVR STUDIO - ASM - SQ6ADE - 10-04-2012 20:48 Otwierasz podgląd RAM i patrzysz na dane od adresu jaki zadeklarowałeś jako Stack Pointer. Dane te pojawiają się w RAM po zaistnieniu przerwania. RE: AVR STUDIO - ASM - SP5FCS - 10-04-2012 22:22 (10-04-2012 15:11)SP4EJT napisał(a): No właśnie ... zupełnie nie wiem jak w praktyce dobrać się do tego stosu. Wiem tylko że służy do odkładania wartości rejestrów, a potem pobierania ich z powrotem ale poco ? i jak to wszystko ogarnąć ? nie mam pojęcia ... STOS w mikroprocesorach to specjalny sprzętowo-programowy mechanizm zarządzania dostępem do pamięci danych. Część operacji na stosie wykonywana jest sprzętowo przez rdzeń procesora a część programowo w trakcie realizacji programu. Bajty (dane, adresy) są układane w pamięci w specyficzny sposób, tak jak na stosie, ostatnio położony bajt musi być pobrany jako pierwszy. Stos to określony fragment pamięci SRAM procesora wskazywany przez wskaźnik stosu SP. W procesorach 8051 stos rośnie w górę pamięci RAM, w procesorach AVR naleje dlatego ustawiany jest na końcu pamięci SRAM. Jeśli w programie używamy wywołań funkcji lub mamy obsługę przerwań wskaźnik stosu musi być ustawiony na początku programu. W procesorach o małej pomięci SRAM należy "oszacować" zapotrzebowanie na wielkość stosu. Spotkanie wskaźnika stosu z lokacją zmiennych będzie źródłem sporych kłopotów. Wskaźnik SP zawsze pokazuje wolny bajt na stosie. Dostęp do danych na stosie możemy mieć poprzez rozkazy pobierania i odkładania danych (PUSH, POP) lub poprzez adresowanie pamięci SRAM, tak jak do typowej zmiennej. Niestety manipulowanie danymi na stosie oraz na wskaźniku stosu wymaga dużego doświadczenia. Przy programowaniu w assemblerze takie zabiegi pozwalają robić ciekawe "sztuczki" jak: przekazywanie danych, podmiana adresu powrotu itd. W językach wysokopoziomowych występuje dodatkowo stos danych wykorzystywany do przekazywania parametrów do wywoływanych funkcji. Oba stosy są rozłączne, mają odrębne wskaźniki i pracują niezależnie od siebie. Obsługa sprzętowa stosu Dobrym przykładem na wyjaśnienie roli stosu jest wywołacie w programie obsługi jakiejś funkcji ( CALL). Obsługa programu jest przekazywana do kodu funkcji po czy musi ona powrócić w miejsce jej wywołania. Aby procesor wiedział w które miejsce programu ma wrócić na stos odkładany jest adres powrotu z funkcji. Po wykonaniu rozkazu (RET) adres jest pobierany ze stosu i wykorzystany do poprawnego powrotu. Odkładanie i pobieranie adresu wykonywane jest sprzętowo przez CPU bez naszego udziału. Kolejnym przykładem jest obsługa przerwań. Po wykryciu przerwania procesor przekazuje sterowania według wektora przerwań do procedury obsługi przerwania. Przerwanie może pojawić się w dowolnym momencie wykonywania programu głównego, jakiejś funkcji lub obsługi innego przerwania. Aby procesor wiedział gdzie wrócić po zakończeniu obsługi przerwania musi odłożyć na stosie adres powrotu. W rozbudowanych programach na stosie może w tym samym momencie być kilkanaście różnych adresów powrotów oddzielonych dodatkowo chronionymi rejestrami. Obsługa programowa stosu Procesor ma ograniczoną ilość rejestrów do wykorzystania w programie. Bardzo często podczas wywołania kolejnych funkcji nie chcemy niszczyć pierwotnej zawartości pewnych rejestrów a musimy z nich korzystać w programie funkcji. Wtedy pomocny jest stos na którym możemy przechować stan tych rejestrów za pomocą rozkazów PUSH. Po zakończeniu wykonywania funkcji przywracamy zawartość naruszonych rejestrów rozkazami POP. Ktoś może słusznie zauważyć, że rejestry możemy zapamiętywać w pamięci SRAM procesora i będzie miał po części rację. Stos jest mechanizmem szybszym bardziej elastycznym, efektywniejszym niż adresowany dostęp do zmiennych w SRAM. O ogromnej roli stosu przekonamy się podczas pisania programu obsługującego kilka przerwań sprzętowych. RE: AVR STUDIO - ASM - SQ6ADE - 10-04-2012 22:25 No zapomniał ja o tych "call" Też na stosie lądują "pamiętniki" Jak się przedobrzy z odwołaniami to stos pęka w szwach RE: AVR STUDIO - ASM - JaHo - 11-04-2012 22:09 (Poniżej, wszystkie linki będą do angielskojęzycznych wersji tekstów jako że nie znam równie dobrych polskich.) Wydaje mi się że celowe jest rozróżnienie abstrakcyjnej struktury danych zwanej "stosem" (stack) od jej pewnej szczególnej implementacji hardware'owej zwanej "call stack" / "machine stack" (stos maszynowy). To co opisuje SP5FCS powyżej dotyczy właśnie tego "szczególnego przypadku". Zdecydowanie nie zgodzę się jednak ze stwierdzeniem: "W językach wysokopoziomowych występuje dodatkowo stos danych wykorzystywany do przekazywania parametrów do wywoływanych funkcji. Oba stosy są rozłączne, mają odrębne wskaźniki i pracują niezależnie od siebie." Wręcz przeciwnie, w wysokopoziomowych językach kompilowanych to właśnie "call stack" / "machine stack" (stos maszynowy) jest używany do tego wszystkiego. Co więcej, istnieją specjalne reguły zwane "calling conventions" które prezycyjnie opisują jak "należy" go używać i czego się można spodziewać od kompilatorów (np. kiedy miesza się kawałki kodu napisane w róźnych językach, w tym napisane w asemblerze). Kiedy zachodzi potrzeba, programista może zaimplementować swoje własne stosy programowe ("software stacks") na swoje własne potrzeby (całkowicie niezależne od hardware'owego "call stack" / "machine stack" (stosu maszynowego), umieszczane w jakoś zaalokowanych kawałkach pamięci RAM) ... przykładowe implementacje znaleźć można na samej stronie z opisem abstrakcyjnej struktury danych zwanej "stosem" (stack). Takimi "programowymi stosami" posługują się całe klasy języków interpretowanych, a niektóre (np. PostScript, Forth, kalkulatory z Reverse Polish notation) są wręcz na nich zbudowane. RE: AVR STUDIO - ASM - SP5FCS - 11-04-2012 23:02 (11-04-2012 22:09)JaHo napisał(a): Zdecydowanie nie zgodzę się jednak ze stwierdzeniem: Nie analizowałem języków wysokopoziomowych do tworzenia oprogramowania na komputery i rozbudowane procesory. Tu dyskutujemy o mechanizmach jakie zostały zaimplementowane w kompilatorach na mikroprocesory 8-bitowe klasy 8051, AVR8 a w tych których używam jest dokładnie tak jak napisałem powyżej. Stos sprzętowy obsługiwany niezależnie od programu przez rdzeń procesora służy do odkładania adresów powrotu z funkcji i obsługi przerwań. Ten sam stos (obszar w RAM wskazywany przez wskaźnik SP) może być obsługiwany programowo do ochrony rejestrów oraz danych. Oczywiście istnieje również możliwość przekazywania parametrów do funkcji poprzez stos sprzętowy ale w językach wysokopoziomowych robi się to inaczej. Do tego celu tworzy się odrębny stos przeznaczony wyłącznie do przekazywania parametrów do funkcji. W kompilatorze języka C CodeVision dla procesorów AVR jest to wydzielony obszar RAM-u obsługiwany przez wskaźnik oparty o parę rejestrów [YH:YL]. Podczas przekazywania parametrów do funkcji dane są kładzione na stosie jako kopia danych na których pracuje wywołana funkcja. Przez cały czas wykonywania kodu funkcji dokładnie wiadomo gdzie znajdują się parametry wejściowe funkcji dlatego możemy z nich korzystać w dowolny sposób. Przed wyjściem z funkcji przywracana jest początkowa wartość wskaźnika do stosu danych co powoduje zniknięcie ze stosu tymczasowych danych utworzonych na potrzeby funkcji. Takie rozwiązanie całkowicie uniezależnia działanie stosu danych od operacji wykonywanych na stosie sprzętowym (skoki do funkcji, przerwania). Pozwala to uprościć mechanizm przekazywania danych oraz gwarantuje ich ochronę i poprawność niezależnie od intensywności wykorzystania stosu sprzętowego. Trzeci rodzaj stosu to programowa implementacja własnych stosów na potrzeby realizowanego algorytmu. RE: AVR STUDIO - ASM - JaHo - 12-04-2012 10:29 Znalazłem opis: "AVR Libc - FAQ - What registers are used by the C compiler?" który skrótowo podaje "calling conventions" używane przez avr gcc. Parametry wejściowe do procedur przekazywane są przez rejestry r25 do r8, a jeśli braknie rejestrów to kolejne argumenty umieszczane są na "stosie maszynowym" (podobnie jak i wszelkie argumenty których nie da się "upchnąć" w rejestry). Rezultat zwracany jest w określonych rejestrach (r25 do r18, zależnie od typu rezultatu). "Zmienne lokalne" procedur umieszczane są w "wolnych" rejestrach a jeśli takowych zabraknie to na "stosie maszynowym", gdzie procedura dostanie zaalokowane miejsce na swoje "zmienne lokalne" i wskaźnik do tego miejsca (na "stosie maszynowym") przekazany będzie w rejestrach r29:r28 (wskaźnik "Y", tzw. "frame pointer"). Reasumując, istnieje jeden jedyny "stos maszynowy" który służy zarówno do przechowywania adresów powrotu z procedur i przerwań jak i jako miejsce do zachowywania używanych w tych procedurach i przerwaniach rejestrów jak i do przekazywania argumentów między procedurami oraz jako miejsce dla "zmiennych lokalnych" procedur. Nie ma ŻADNEGO zabezpieczenia ani ochrony danych umieszczonych na stosie ... dowolna procedura, albo na skutek błędu albo celowo, może "nadpisać" zawartość stosu i w ten sposób zmienić "bieg programu". (PS. Mocno bym się zdziwił gdyby się okazało że kompilator C CodeVision stosuje znacząco inne "calling conventions", bo te używane przez avr gcc wydają się być bardzo sensowne i dobrze dopasowane do małych procków z niewielką ilością RAM.) RE: AVR STUDIO - ASM - SP5FCS - 12-04-2012 12:44 (12-04-2012 10:29)JaHo napisał(a): (PS. Mocno bym się zdziwił gdyby się okazało że kompilator C CodeVision stosuje znacząco inne "calling conventions", bo te używane przez avr gcc wydają się być bardzo sensowne i dobrze dopasowane do małych procków z niewielką ilością RAM.) Kolego, JaHo lubię dyskutować ale na argumenty a nie o tym co mi się wydaję. Programuję zarówno w assemblerze jak i C na AVR z łączeniem obu języków w obie strony. Zawsze sprawdzam wygenerowany kod asm przez kompilator, jeśli jest zły to robię wstawkę w assemblerze. Proponuję zainstalować sobie demo CodeVision i na własne oczy zobaczyć jak jest zorganizowany stos danych oraz przekazywanie parametrów do funkcji. Nigdy nie twierdziłem, że wszystkie kompilatory mają odrębny stos danych, wyraźnie podkreśliłem, że tak jest w tym którego używam czyli CodeVision. W kompilatorze GCC dla AVR jest tak jak napisał powyżej kol. JaHo, parametry do funkcji przekazywane są poprzez rejestry co ilustruje podgląd kodu w assemblerze przykładowej funkcji. Kod: @0000007A: main W Code Vision te same parametry wejściowe typu long int są kładzione na stosie danych wg. wskaźnika [YH:YL] poprzez dwukrotne wywołanie procedury PUTPARD1, podgląd w assemblerze: Kod: _main: Język GCC powstał dużo wcześniej na inne procesory a po pojawieniu się rodziny AVR został przystosowany do tych procesorów. Moim zdanie metoda przekazywania danych zastosowana w GCC jest gorsza, mniej przejrzysta i blokuje dostęp do rejestrów. Mieszanie adresów powrotu z danymi wejściowymi na jednym stosie utrudnia dostęp do danych w kodzie funkcji. To między innymi przyczyna gorszych wyników w teście porównawczym obu kompilatorów gdzie GCC był wolniejszy i generował większy kod. Nie chcę nikogo zniechęcać do GCC ani przekonywać do CodeVision bo to sprawa indywidualnych preferencji. Warto odnotować odmienne podejście do tematu stosu w różnych kompilatorach i od czasu do czasu sprawdzić jaki to ma wpływ na jakość generowanego kodu. Ta dyskusja powinna toczyć się w innym wątku. |