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

[ASM] Jak zapisać fizyczne adresy etykiet jako dane?

roman_partyka 13 Kwi 2020 15:41 657 23
  • #1 18614228
    roman_partyka
    Poziom 24  
    Witam.
    Mam przykładowy szkielet programu:

    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod


    Chodzi mi o zapisanie fizycznych adresów etykiet program1 ... program4 jako danych.
    W jaki sposób to zrobić?

    Dodano po 31 [sekundy]:
  • #2 18614445
    JacekCz
    Poziom 42  
    .dd program2

    ???

    Nie mam pojęcia o co ci chodzi, co z tym chcesz zrobić, w jakim kontekście rozumiesz "dane".
    I na jakim procku
  • #3 18614448
    roman_partyka
    Poziom 24  
    Chodzi o mikrokontroler AVR.
  • #4 18614454
    JacekCz
    Poziom 42  
    A co z tych chcesz zrobić?
    Na AVR jest rozdzielona przestrzeń adresowa, i rzeczy robią się "skomplikowańsze"
  • #5 18614460
    Gregor9
    Poziom 8  
    Pokaz plik listingu wygenerowany przez kompilator.
  • #6 18614479
    Marek_Skalski
    VIP Zasłużony dla elektroda
    @roman_partyka Polecam lekturę AVR Assembler
    Szczególnie sekcja 7.1. Można wygenerować adres funkcji (procedury) zapisując to mniej więcej tak:
    .dw LWRD(program1<<1)
    Przesunięcie jest konieczne, ponieważ pamięć Flash jest adresowana słowami, a nie bajtami.

    @JacekCz Czasami przydaje się funkcja skoku względnego z przesunięciem w akumulatorze. To jest odpowiednik switch-case. A czasami można w locie podmienić adres funkcji zależnie od warunków lub czasu aplkacji. Na 8-bitowcach takie rzeczy są dość normalne.
  • #7 18614480
    roman_partyka
    Poziom 24  
    Mam przykładowo menu i aby wykonać określony jego element można po kolei sprawdzać czy jest to element 1 2 itd., tylko sprawdzenie ostatniego z nich trwa zawsze najdłużej.
    A gdyby adresy poszczególnych skoków były zapisane we flashu byłoby znacznie prościej.

    Przykład.
    Mam etykiety programów
    program0 pod adresem $160
    program1 pod adresem $23a
    program2 pod adresem $348
    program3 pod adresem $a36
    program4 pod adresem $102d
    program5 pod adresem $2000

    I w jaki sposób to zapisać aby kompilator automatycznie to przeliczył i zapisał adresy tych podprogramów w tablicy jako dwa bajty?

    Potem wiedząc że odczytam np. 5 element to odczytuję 10 i 11 element tablicy, ładuję do R30 i R31 i wykonuję odpowiedni skok.
  • #8 18614525
    JacekCz
    Poziom 42  
    roman_partyka napisał:
    Mam przykładowo menu i aby wykonać określony jego element można po kolei sprawdzać czy jest to element 1 2 itd., tylko sprawdzenie ostatniego z nich trwa zawsze najdłużej.
    A gdyby adresy poszczególnych skoków były zapisane we flashu byłoby znacznie prościej.

    Przykład.
    Mam etykiety programów
    program0 pod adresem $160
    program1 pod adresem $23a
    program2 pod adresem $348
    program3 pod adresem $a36
    program4 pod adresem $102d
    program5 pod adresem $2000

    I w jaki sposób to zapisać aby kompilator automatycznie to przeliczył i zapisał jako dane?


    Menu to nie kod wykonywalny. Coś nie gra.
    czas czynności człowieka (menu) jest wielokrotnie większy niż choćby przeszukanie pętlą, więc wytłumacz dokładniej.

    I pisz do jasnej ciasnej w C, mniejsza szansa na strzał w kolano. Tam koncepcja o jaką PRAWDOPOBNIE ci chodzi, to wskaźnik funkcyjny (wskaźnik na funkcję). Menu można całkiem fajnie wyrazić w C itd...
    Który to dokładnie procesor?

    @Marek_Skalski Rozumiem co MOŻNA z tym zrobić, rzecz w tym co OP chce zrobić
  • #9 18614538
    roman_partyka
    Poziom 24  
    Jacku chętnie bym napisał to w C ale tu jest bardzo mało czasu i każdy cykl jest na wagę złota.
    Poprawiłem wcześniejszy post.
  • #10 18614548
    Gregor9
    Poziom 8  
    Jakiego assemblera używasz, podaj nazwe. Możesz na końcu programu wygenerować tablicę w rodzaju np, WORD program1, program2 itp.
  • #11 18614567
    roman_partyka
    Poziom 24  
    Chciałbym to napisać w AVR STUDIO 4.

    Jacku C nie znam za dobrze a też nie chodzi o to abym się męczył. Pisanie w czystym asemblerze jest w miarę łatwe, a na pewno nie ma miliona niewiadomych jakie są w języku C.
  • #12 18614604
    BlueDraco
    Specjalista - Mikrokontrolery
    roman_partyka napisał:
    Chciałbym to napisać w AVR STUDIO 4.


    Przybysz z przeszłości... Wiesz, w ciągu ostatniej dekady trochę się zmieniło.
  • #13 18614609
    roman_partyka
    Poziom 24  
    BlueDraco napisał:
    Przybysz z przeszłości... Wiesz, w ciągu ostatniej dekady trochę się zmieniło.

    Po co mam zmieniać coś co działa?
    Może Kolega pomoże bo póki co problemem nie jest w czym to napisać tylko jak.
  • #14 18614643
    JacekCz
    Poziom 42  
    roman_partyka napisał:
    BlueDraco napisał:
    Przybysz z przeszłości... Wiesz, w ciągu ostatniej dekady trochę się zmieniło.

    Po co mam zmieniać coś co działa?
    Może Kolega pomoże bo póki co problemem nie jest w czym to napisać tylko jak.


    Problemem są pewne braki ... nie chcę żeby mi post skasowali.

    A w projektach się zmienia bo:
    1. nie działa (usuwa błędy)
    2. utracił możliwości bezpiecznego, skutecznego, zorganizowanego rozwoju.


    Nawiasem mówiąc GCC zapakowany w AS 7 wymiata tak, że amatorzy asemblerowcy pękajcie.
    Ale jak ASM zaspokaja czyjeś intymne poczucie wartości ...
  • #15 18614670
    roman_partyka
    Poziom 24  
    Czy mój problem jest dla wszystkich zrozumiały?

    Doskonale wiem jak to można napisać w C tylko taka forma jest bardzo czasochłonna (cyklochłonna).

    if (a==0)
    { coś tam};
    if (a==1)
    { coś tam};
    if (a==2)
    { coś tam};
    ...
    if (a==250)
    { coś tam};

    Wiem że można też z ELSE itp.
    Problem tu jest taki że pierwszy warunek zostanie sprawdzony po kilku czy kilkunastu cyklach. A ostatni jeśli ich będzie 250? To będzie trwało wieki!

    Czy teraz jest coś jaśniej czemu tak mocno chcę to napisać w ASM?
  • #16 18614697
    JacekCz
    Poziom 42  
    Znasz taką strukturę jak "tablica" ? Albo taki algorytm jak dzielenie binarne?
    Wszystko da się zakodować.


    BTW swicth case na 200 pozycji mógłby być ciekawie zoptymalizowany, potwierdzicie?
  • #17 18614706
    roman_partyka
    Poziom 24  
    Jacku może i da się to zoptymalizować ale tu nie chodzi o "zgadywanie" ile to czy tamto potrwa.
    Nieważne czy zmienna "a" będzie miała 0 czy 250 to skok do podprogramu ma trwać tyle samo.

    Mógłbym to zaprezentować na asm 6502 bo tam to jest banalne.
  • #18 18614711
    JarekC
    Poziom 32  
    Nie wiem czy koledze o to chodzi ale poniżej przykład jak utworzyć tablicę adresów funkcji i wywoływać funkcję na podstawie jej numeru.
    Kod: ARM assembler
    Zaloguj się, aby zobaczyć kod


    Sam czasami piszę w ASM i nie widzę w tym nic złego.
    Ostatni przykład to funkcja szyfrowanie AES z kluczem 128 bitów.
    Funkcja wykorzystywana w bootloaderze gdzie wymagana była minimalna zajętość pamięci.
    Całość w assemblerze zajmuje 504 bajty z czego 256 to tablica S, 16 bajtów to klucz, 16 bajtów to wektor startowy.
    Czyli sama funkcja zajmuje 216 bajtów.
    I tu poproszę JacekCz aby napisał to w C (GCC) tak aby wynikowy kod nie przekroczył tego rozmiaru
  • #19 18614712
    tmf
    VIP Zasłużony dla elektroda
    Czyli ładujesz do rejestru wartość, następnie przesuwasz ją o 1 bit w lewo (bo adresy na AVR są zazwyczaj 16-bitowe. Teraz do tego dodajesz adres początku tablicy z adresami i następnie ładujesz do rejestrów adres skoku z tablicy przygotowanej tak jak Marek to opisał i wykonujesz skok.
    Z drugiej strony, jeśli tak zależy ci na czasie, to prościej w menu zamiast ID, od razu jako ID umieszczać adres funkcji, która obsługuje daną pozycję menu.

    Dodano po 3 [minuty]:

    JarekC napisał:
    I tu poproszę JacekCz aby napisał to w C (GCC) tak aby wynikowy kod nie przekroczył tego rozmiaru

    W przypadku szyfrowania, np. AES, ważniejsze niż rozmiar jest poprawne napisanie tych funkcji, tak, aby nie dało się odzyskać klucza poprzez np. banalny pomiar prądu MCU. Np. w XMEGA tak skopali sprzętowo blok kryptograficzny, że odzyskanie klucza jest możliwe w ciągu kilku minut przy pomocy amperomierza/oscyloskopu.
  • #20 18614872
    JarekC
    Poziom 32  
    tmf napisał:
    W przypadku szyfrowania, np. AES, ważniejsze niż rozmiar jest poprawne napisanie tych funkcji, tak, aby nie dało się odzyskać klucza poprzez np. banalny pomiar prądu MCU. Np. w XMEGA tak skopali sprzętowo blok kryptograficzny, że odzyskanie klucza jest możliwe w ciągu kilku minut przy pomocy amperomierza/oscyloskopu.


    Oczywiście masz rację ale w pewnych zastosowanie jakieś zabezpieczenie jest lepsze od żadnego.
    A że nie ma zabezpieczeń doskonałych pokazały ostatnie przypadki STM32
    W przypadku STM32F1xx można odczytać od 89 do 94% kodu, a w przypadku STM32F0xx (przy poziomie protekcji 1) całość kodu.
  • #21 18614940
    tmf
    VIP Zasłużony dla elektroda
    JarekC napisał:
    Oczywiście masz rację ale w pewnych zastosowanie jakieś zabezpieczenie jest lepsze od żadnego.

    Bez dwóch zdań, tym bardziej, że wprowadzenie takiego zabezpieczenia praktycznie nic nie kosztuje.
    Niemniej warto pokusić się o lepszą implementację, która utrudnia tego typu ataki. W sumie nawet bardziej jako pouczające ćwiczenie. Pochwal się tym bootloaderem. AES jak skończysz. Widziałeś tą stronę:
    https://wiki.das-labor.org/w/AVR-Crypto-Lib/en
    Jest napisane, że AES 128 bitów to 2070 bajtów kodu, czyli twoje 216 bajtów byłoby niezłym wyczynem.
  • #22 18615808
    trol.six
    Poziom 31  
    roman_partyka napisał:
    A gdyby adresy poszczególnych skoków były zapisane we flashu byłoby znacznie prościej.

    Szybciej będzie bez pobierania tablic, bo cykl pobierania z tablic jest dość pracochłonny. I za pomocą skoku (rjmp ma ograniczony zasięg a jmp jest dwubajtowy, konieczność przesunięcia). Ja używam avra, tam adresy są w słowach 16 bitowych:

    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod


    Można to zoptymalizować z wyrównaniem do 00 (org) i wtedy nie musisz dodawać.

    Kod: AVR assembler
    Zaloguj się, aby zobaczyć kod

    .
  • #23 18616386
    roman_partyka
    Poziom 24  
    Kombinuje to trochę inaczej. Jak się uda to cały kod nie będzie korzystał z przerwań ani stosu. Wszystko będzie policzone na cykle bo to dość specyficzne zadanie będzie pełnić.
    Musze sprawdzić czy procesor to zdąży przetworzyć i próbkę kodu zamieszczę na forum.
  • #24 18616753
    trol.six
    Poziom 31  
    roman_partyka napisał:
    Kombinuje to trochę inaczej. Jak się uda to cały kod nie będzie korzystał z przerwań ani stosu. Wszystko będzie policzone na cykle bo to dość specyficzne zadanie będzie pełnić.

    Kod który wrzuciłem nie korzysta ani z przerwań ani ze stosu. A ilość cykli jest zawsze identyczna. Jednak jak to w programowaniu każdy problem często można rozwiązać na wiele sposobów.

Podsumowanie tematu

W dyskusji poruszono temat zapisywania fizycznych adresów etykiet programów w asemblerze dla mikrokontrolera AVR. Użytkownik poszukiwał sposobu na zapisanie adresów programów (program1 do program4) w tablicy jako danych, aby uprościć wywoływanie funkcji w menu. Uczestnicy forum sugerowali różne podejścia, w tym użycie instrukcji .dw do generowania adresów oraz optymalizację kodu poprzez skoki do funkcji. Wskazano na konieczność zrozumienia struktury tablicy oraz algorytmów, które mogą pomóc w efektywnym zarządzaniu adresami. Użytkownik podkreślił, że czas wykonania operacji jest kluczowy, co skłoniło go do pozostania przy asemblerze zamiast przechodzić na C. Wspomniano również o problemach z wydajnością w kontekście przeszukiwania menu oraz o możliwościach optymalizacji kodu.
Podsumowanie wygenerowane przez model językowy.
REKLAMA