logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATMEGA][ASEMBLER] - Długa pętla w asemblerze i dziwna matematyka.

Kuniarz 20 Lut 2013 08:47 3663 22
  • #1 11959793
    Kuniarz
    Moderator Projektowanie
    Muszę przyspieszyć trochę Bascoma, więc zabrałem się za wstawki w asemblerze. Kod prawie działa, piszę "prawie" bo mi się ni jak na logikę nie zgadza ilość przebiegów pętli.

    Na początek fragment kodu z moimi komentarzami.

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Ja to widzę tak (dla ułatwienia wartości dziesiętne):
    256 odejmowań R16 * 132 operacje na R17 * 3 operacje na R18.
    Pętla moim zdaniem powinna wykonać się 101376 razy.
    Wykonuje się jednak 230400 razy...

    Jak to ?! Gdzie jest haczyk, którego nie rozumiem ? ;-)

    Docelowo potrzebuję pętlę, która wykona się 1152000 razy. Jest to czyszczenie ekranu LCD, w Bascomie trwa to prawie 5 sekund, po wpisaniu danych pętli "na pałę" trwa to sekundę.
    Wszystko ładnie pięknie, ale póki nie zrozumiem tej pokrętnej arytmetyki to nie mam co eksperymentować. Pomoże ktoś łopatologicznie ?
    Pomogłem? Kup mi kawę.
  • #2 11959836
    alagner
    Poziom 26  
    no zrobiłeś sobie liczbę 3 bajtową 03_84_FFh, czyli 230655. Najbardziej znaczący bajt masz w R18, najmniej - w R16. No i dekrementujesz. Nie do końca natomiast wiem, skąd się doliczyłeś 230400. Chyba, że po drodze wchodzi Ci jeszcze przerwanie i modyfikuje zawartość któregoś rejestru.
    A to co chcesz zrobić powinienneś (czyli 3x132 itd.) napisać w pętli zagnieżdżonej.
    czyli np.:
    [piszę z pamięci, nie mam listy rozkazów pod ręką, bardziej chodzi o ideę]

    Kod: text
    Zaloguj się, aby zobaczyć kod


    itd.
    Albo wpisać do powyższych rejestrów 18C00, wtedy będziesz mieć 101376 i traktować to jako normalną liczbę.

    pzdr.
  • #3 11959847
    Kuniarz
    Moderator Projektowanie
    alagner napisał:
    Nie do końca natomiast wiem, skąd się doliczyłeś 230400.

    Tak jest wyliczone w przykładzie zamieszczonym w EP. Przy czym tam jest mniejszy wyświetlacz, więc pętla wykonuje się 320 * 240 * 3 = 230400 razy.

    Nie chciałbym kombinować z zagnieżdżaniem pętli, skoro to działa.
    Jeszcze jakieś pomysły ?
    Pomogłem? Kup mi kawę.
  • Pomocny post
    #4 11959855
    alagner
    Poziom 26  
    Patrz wyżej - oblicz sobie odpowiednią wartość i ładuj do powyższych 3 rejestrów.
    Ale chodzi mi o to, że nie wyobrażam sobie jak ta Twoja pętla z 1szego posta wykona się 230400 razy, bo jak dla mnie to o jakieś 255 za mało wgzlędem tego co w rejestrach wpisałeś.
  • Pomocny post
    #5 11959890
    JarekC
    Poziom 32  
    Witam,

    A czy w ostatniej linii nie jest przypadkiem
    Kod: text
    Zaloguj się, aby zobaczyć kod

    zamiast
    Kod: text
    Zaloguj się, aby zobaczyć kod


    bo wtedy by się zgadzało.

    Pierwszy przebieg pętli to 132*256 a następne trzy to 256*256
    (po pierwszym przebiegu R17 zostanie załadowane 255 a nie 132).

    132*256 + 3*256*256 daje 230400.

    Pozdrawiam
    JarekC
  • #6 11960019
    Kuniarz
    Moderator Projektowanie
    W programie best BRNE niestety.
    Zrobiłem eksperyment, 1152000 to 256*100*45, takie też wartości wprowadziłem do rejestrów i niestety pętla wykonuje się znacznie więcej razy.

    EDIT:
    metodą "na pałę" doszedłem do takich wartości w rejestrach:

    R17 - 7A
    R18 - 11

    i teraz ekran jest prawie cały wyczyszczony, brakuje kilku linijek. Czyli pętla przebiega PRAWIE 1152000 razy. Co oczywiście ni jak się ma do sensu, bo powinna przebiec 530940...
    Pomogłem? Kup mi kawę.
  • #7 11960051
    excray
    Poziom 41  
    Do pętli czasowych dłuższych niż 255 cykli dobrze jest stosować ten sposób:
    Kod: text
    Zaloguj się, aby zobaczyć kod

    Pętla jest o tyle wygodna że jedno "kółko" zawsze trwa 4 cykle (nie licząc obszaru "ldi") więc łatwo policzyć precyzyjnie czas jej trwania.
  • #8 11960064
    Kuniarz
    Moderator Projektowanie
    Chodzi tu akurat o to, żeby czas trwania był najkrótszy. Chyba napiszę do autora artykułu w EP, jak tą pętlę wykombinował ;-)
    Pomogłem? Kup mi kawę.
  • #9 11960078
    excray
    Poziom 41  
    Kuniarz napisał:
    Chodzi tu akurat o to, żeby czas trwania był najkrótszy. Chyba napiszę do autora artykułu w EP, jak tą pętlę wykombinował ;-)

    Przecież jest krótki. 4 cykle jak na pętlę powyżej 255 cykli to MEGA krótko. Szybciej się nie da. Tutaj:
    https://www.elektroda.pl/rtvforum/topic2424971.html
    masz opisane jak się liczy inne pętle, bardziej zagnieżdżone.
  • #10 11960089
    Kuniarz
    Moderator Projektowanie
    Ok, ale tu osiągnę maksymalnie 65536 przejść pętli, a ja potrzebuję 1152000 - rozumiem, że jeszcze jedną pętlę dołożyć, ale czy rejestr jest dowolny ?
    Pomogłem? Kup mi kawę.
  • Pomocny post
    #11 11960120
    excray
    Poziom 41  
    Kuniarz napisał:
    czy rejestr jest dowolny ?

    Może być dowolny. To już tylko zależy od Ciebie czy go gdzieś nie używasz.
  • Pomocny post
    #12 11960183
    kamyczek
    Poziom 38  
    To jest prosta pętla wykonuje się tyle razy jaki długi jest rejestr żeby ją przedłużyć można zrobić na dwa sposoby dobudować jeszcze jedną pętlę ,która wykona obecną n razy lub rozszerzyć rejestr do długości 3 bajtów wykonując to samo odejmowanie przeniesienia na tym najwyższym i będzie to samo . Dla bezpieczeństwa między sbi portx i cbi portx warto wstawić "nop". Przy obecnym zapisie można korzystać z rejestrów od 16 do 31 w przypadku używania rejestrów od o do 15 nie można ładować zmiennej liczbowej nie działa instrukcja ldi ...
  • #13 11960304
    Kuniarz
    Moderator Projektowanie
    Dzięki, ale tak naprawdę, pierwotnie to jest pętla na 3 rejestrach, tylko liczy jakoś dziwnie... Dodałem NOP.

    EDIT:

    zagadki ciąg dalszy.
    Przypomnę, że każdy piksel to 3 bajty, więc po ustaleniu takich parametrów:

    R16=255
    R17=8
    R18=0

    uzyskuję linijkę 768 pixeli, to się zgadza. Idziemy dalej, zwiększenie R18 powinno dać mi już prawie dwie linijki tak ?

    R16=255
    R17=8
    R18=1

    ...ale, przecież to byłoby zbyt logiczne i za proste... na LCD mam ze 20-30 linijek, czyli pętla zewnętrzna wykonała się znacznie więcej niż 2x

    Dodano po 28 [minuty]:

    Ależ ja jestem głupi... ;-)

    Wszystko się zgadza, olśnienie nastąpiło po mailu od autora programu w EP.

    Dla potomnych:
    - pętla odlicza trzybajtową liczbę, która pierwotnie wygląda : 0384FF, co jak w pysk daje 230655 (o 255 więcej, ale to akurat nie istotne).
    - chcąc wykonać pętlę 1152000 razy, trzeba w rejestry wpisać liczbę 119400 (HEX) - proste prawda ?

    DZIAŁA ;-)

    Dziękuję wszystkim za udział w dyskusji.
    Pomogłem? Kup mi kawę.
  • Pomocny post
    #14 11960550
    2rs232
    Poziom 18  
    Trochę łatwiejsze w liczeniu ;-)
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #15 11960731
    kozak_sc
    Poziom 23  
    Może nie stricte z tematem, ale miałem podobną sytuację na początku swojej zabawy z mikrokontrolerami. Pisałem programy w bascomie na 51 i na Avr i dla przyśpieszenia działania robiłem wstawki w asm. Po pewnym czasie moje programy wyglądały tak

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Wtedy doszedłem do wniosku że używanie bascoma nie ma sensu i przesiadłem się na czystego assemblera a potem na C.
  • #16 11961131
    kamyczek
    Poziom 38  
    Wszystko wynika z wymagań autora . Na początku chcemy żeby coś zadziałało dioda zamigała , pokazał się napis "hello word" itp . Do tego bascom jest idealny bo załatwia wiele rzeczy bez naszej wiedzy... Kolejnym krokiem jest wstawka w ASM bo coś nie chce dzialać po naszej myśli . Następny jest asembler bo tam wszystko działa zawsze tak samo , szybko i zajmuje mało miejsca . Ci którzy piszą komercyjnie i na wyścigi siadają do C bo wiele rzeczy jest na tacy jako gotowe biblioteki . Są też tacy którzy piszą w c disasemblują kod i poprawiają w asemblerze ( wywalają zbęne śmieci ) i jest lepiej niż w C . Ja pobawiłem się bascomem 2 tygodnie i podczas pisania poważniejszego programu przesiadłem sie na asemblera i tak jest do dziś . Może wolniej od ludków w C ale za to z jaka satysfakcją .
  • #17 11965442
    Konto nie istnieje
    Konto nie istnieje  
  • #18 11965513
    Nekrodemokrata
    Poziom 10  
    Saabotaz napisał:
    Mniej na temat ale ja robię dokładnie jak kamyczek.
    Zacząłem od Bascoma bo było łatwo i szybko, nie zabija początkującego jak C. Wszyscy krzyczą żeby zacząć od C ale moim zdaniem dla kogoś kto zaczyna programowanie to tylko się nabluzga i zniechęci.

    Gdy mi Bascom już nie wystarczał lub wyżerał pamięć to robiłem wstawki ASM, i tez kończyło sie na tym że cały program to była wielka wstawka.
    Dzisiaj szybkie prototypowanie robię w Bascom, a finalny program w ASM. I to wcale nie jest trudniejsze, bo no AVR STUDIO pozwala "rozwijać" składnię ASM do tej podobnej w C co jeszcze bardziej ułatwia programowanie. Jedyne upierdliwości to operacje arytmetyczne (szczególnie dzielenie), reszta idzie bardziej gładko niż w C.

    to co ty będziesz tydzień klepał w asmie programista C zrobi w dzień, może dwa a w dodatku potem nie będzie problemu żeby kod (pod warunkiem że jest dobrze napisany) przenieść na inny uC.
  • #19 11965516
    alagner
    Poziom 26  
    powodzenia w obsłudze ethernetu ;) No ale zależy kto czego używa.
  • #20 11965537
    Nekrodemokrata
    Poziom 10  
    alagner napisał:
    powodzenia w obsłudze ethernetu ;) No ale zależy kto czego używa.

    nie rozumiem? na STM32 ethernet działa bez problemu
  • #21 11965553
    alagner
    Poziom 26  
    @Nekrodemokrata: sorry, to było do Kolegi powyżej Ciebie, piszącego w asm. Chodziło mi właśnie o obsługę bardziej złożonych peryferiów czy wykonywanie abstrakcyjnych operacji. Nie widzi mi się to na poziomie maszyny, o przenośności nawet już nie wspominam.
    Oczywiście, krytyczne czasowo rzeczy warto pisać w asmie, ale stosunek zysku wydajności do czasu wypada zdecydowanie lepiej dla C w skali całego projektu.
  • #22 11965807
    Konto nie istnieje
    Konto nie istnieje  
  • #23 12833586
    Kuniarz
    Moderator Projektowanie
    Jako że mój problem został rozwiązany, a dyskusja zeszła na inne tory to .. zamykam ;-)
    Pomogłem? Kup mi kawę.
REKLAMA