HomeMade
Dzielenie ASM Atmega32 (lub inna Atmega) - Wersja do druku

+- HomeMade (http://sp-hm.pl)
+-- Dział: Oprogramowanie (/forum-84.html)
+--- Dział: Technika programowania mikroprocesorów (/forum-85.html)
+--- Wątek: Dzielenie ASM Atmega32 (lub inna Atmega) (/thread-1278.html)



Dzielenie ASM Atmega32 (lub inna Atmega) - SP4EJT - 05-04-2012 13:06

Kto się udzieli i zrobi tu procedurę dzielenia dwóch liczb 8-bitowych bez znaku.
Chciałbym aby to było dla zielonych z wyjaśnieniem linijka po linijce co się dzieje, najlepiej w AVR Studio bo taki soft posiadam.
Dwie liczby wpisane w pamięć danych lub bezpośrednio w rejestr.
Chciałbym się poduczyć z tego zakresu a kursy które widziałem mrugające diodami nie pomogą mi w arytmetyce wcale.
Wiem jak się dzieli binarnie na kartce ale kartka to nie mikrokontroler Smile Z góry dzięki.

Acha i jeszcze jakby wynik z dzielenia był podawany na któryś z portów to byłoby fajnie.


RE: Dzielenie ASM Atmega32 (lub inna Atmega) - SP5FCS - 05-04-2012 14:22

Marcin, naukę arytmetyki należałoby rozpocząć od dodawania i odejmowania ponieważ na nich opierają się funkcje mnożenia i dzielenia. Drugi krok to operacje przesuwania w lewo, w prawo a dopiero potem mnożenie i dzielenie.

Procesory AVR nie mają rozkazu dzielenia dlatego musimy zrobić to przy pomocy rozkazów odejmowania. Najprostszy algorytm dzielenia 8-bitowego to odejmowanie w pętli dzielnika od dzielnej i liczenie ilości wykonanych pętli.
Zalety: prosty, krótki kod, szybkie wykonanie przy dużych dzielnikach.
Wady: długi czas obliczeń przy małych dzielnikach.
Lepszą metodą jest algorytm oparty na przesuwaniu w lewo i odejmowaniu. To rozwiązanie stosowane jest w arytmetyce na formatach wielobajtowych 16, 32, 64 bity. Aby zrozumieć filozofię takiego dzielenia najlepiej użyć przykładu dla liczb minimum 16 bitowych (odejmowanie, przesunięcie wielobajtowe). Na bazie takiego algorytmu możemy potem zbudować dzielenie na praktycznie dowolnych formacie danych.

Temat na elektrodzie o dzieleniu na atmega w asm
Źródła procedur DIV8/8, DIV16/8


RE: Dzielenie ASM Atmega32 (lub inna Atmega) - SP5FCS - 05-04-2012 21:55

Przykładowy kod procedury dzielenia na liczbach 16 bitowych z komentarzami. Pełny program testowy do symulacji w AVR Studio w pliku załącznika. Przed analizą kodu warto zapoznać się z opisem poszczególnych rozkazów procesora oraz metodyką dzielenia w oparciu o przesuwanie i odejmowanie dzielnika.
W przypadku programowania w asseblerze musimy opanować trzy dziedziny wiedzy:
- dokładnie poznać zasoby programowanego procesora;
- poznać listę rozkazów procesora;
- poznać techniki realizacji różnych algorytmów, funkcji

Jak widać kod jest dość złożony (w Bacomie czy C to jedna linijka), wymaga znajomości kilkunastu rozkazów procesora oraz algorytmu dzielenia. Jest to oczywiście koszt jednostkowy, raz napisana i przetestowana procedura będzie do wykorzystania w wielu innych projektach. W zamian za większy nakład pracy dostajemy pełną swobodę tworzenia kodu bez ograniczeń wynikających np. ze składni języka wysokopoziomowego.

Kod:
;---------------------------------------------------------------------
;dzielenie uint16 / uint16
;---------------------------------------------------------------------
;[r27,r26] - dzielna
;[r31,r30] - dzielnik
;[r27,r26]=[r27,r26] / [r31,r30],   reszta z dzielenia w [r1,r0]

DIV_U16:
    CLR  R0                ;zerowanie reszty
    CLR  R1
    LDI  R25,16            ;ile bitow ma zmienna (licznik petli)

DIV_U16_1:                ;glowna petla obliczen
    LSL  R26            ;przesuwanie dzielnej z resztą (32bity) w lewo
    ROL  R27
    ROL  R0
    ROL  R1
    SUB  R0,R30            ;odejmowanie dzielnika od reszty
    SBC  R1,R31
    BRCC DIV_U16_2        ;czy reszta >= dzielnik

    ADD  R0,R30            ;nie możemy odjac, reszta jest mniejsza od dzielnika
    ADC  R1,R31            ;przywroc wartosc reszty przez dodanie
    RJMP DIV_U16_3

DIV_U16_2:                
    SBR  R26,1            ;poprawne odejmowanie, ustaw 1 w wyniku dzilenia

DIV_U16_3:
    DEC  R25            ;zmniejsz licznik petli
    BRNE DIV_U16_1        ;czy to ostatnia petla obliczen?, nie na poczatek petli

    ;koniec obliczen, wynik w [r27,r26] reszta w [r1,r0]
    RET                    ;powrot z procedury



RE: Dzielenie ASM Atmega32 (lub inna Atmega) - SP4EJT - 06-04-2012 11:25

Dzieki. Musze to sobie rozrysowac na kartce, czyli co zmienia sie w rejestrach zeby dobrze zrozumiec. Mam jeszcze jedno pytanie odnosnie laczenia asemblera z C:
Powiedzmy ze zrobilem pewien kod w asemblerze i chce go wstawic do programu w C. Chcialbym aby w jezyku C zapisac bajt ze zniennej o nawie "do_asm" do komorki pamieci danych 0x0060 ( lub do jakiegos rejestru ) , teraz uruchomilby sie kod w asm, a wynik jego dzialania zapisany bylby pod adresem 0x0062 pamieci danych i chcialbym to przekazac do zmiennej "z_asm" ktora istnieje w kodzie C.
Jest na to prosta metoda ??


RE: Dzielenie ASM Atmega32 (lub inna Atmega) - SP5FCS - 06-04-2012 13:04

Marcin, domyślam się, że chodzi Ci o łączenie kodu ASM z kodem C w wersji GCC. Niestety maja znajomość tego środowiska jest pobieżna. Moim zdaniem przekazywanie danych pomiędzy GCC a wstawkami w assemblerze jest dość zawiłe i mało czytelne dlatego ja zdecydowałem się na komercyjne środowisko CodeVision.

Tak naprawdę biegłe łączenie C z assemblerem to najskuteczniejsza metoda pisania optymalnego oprogramowania dla mikroprocesorów, wygoda języka C oraz zwartość i szybkość kodu assemblera. Niestety ta metoda wymaga sporej wiedzy oraz dużego doświadczenia w tworzeniu oprogramowania. Łączenie różnych języków jest dość trudne ponieważ wymaga biegłej znajomości używanego kompilatora. Musisz wiedzieć jakich rejestrów procesora używa kompilator, jak przekazuje parametry na stos danych aby w procedurach assemblerowych wiedzieć co ci wolno a co nie. Naruszenie ważnych dla kompilatora rejestrów, wskaźników może spowodować niekontrolowane "wysypanie" całego programu. Możemy oczywiście chronić wszystko czego używamy ale takie wstawki wcale nie będą optymalne.

Wstawki assemblerowe w GCC
Łączenie assemblera i GCC


RE: Dzielenie ASM Atmega32 (lub inna Atmega) - SQ6OXK - 06-04-2012 23:25

Gdzieś miałem przykład z WinAVR jak to się robiło. Spróbuję odszukać.


RE: Dzielenie ASM Atmega32 (lub inna Atmega) - SP4EJT - 10-04-2012 15:06

Adam dzięki za kod, pomógł mi - już się nauczyłem jak się dzieli Smile rozwiązałem to troszeczkę inaczej niż ty ale nie powiem jak Angel zrobiłem nawet kod asm który dzieli 64bit/64bit oraz liczący FTW dla AD9951. Teraz z innej beczki: wiem że AVR32 ma polecenie dzielenia 32/32bit (19 lub 35 cykli mu to zajmuje) ... jeśli chcemy podzielić 64bit/32bit to pojawia się zagadka - jak wykorzystać dzielenie sprzętowe AVR32 do tego aby podzielić 64bit/32bit lub 64bit/64bit ?
Czy znasz odpowiedź na to pytanie ?