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

Jak zbudować tablicę adresów funkcji w BASCOM i asm? Czy kod jest poprawny?

wasi 23 Kwi 2005 22:32 2003 7
REKLAMA
  • #1 1431488
    wasi
    Poziom 12  
    Posty: 75
    Ocena: 5
    Wpadłem na pomysł jak zoptymalizować swój programik i zamiast serii instrukcji:

    instrukcja_10:
       clr   C
       mov   A,{instrukcja}
       subb  A,#10
       jnz   .instrukcja_11
          ajmp  .wykonaj_instrukcje_10
    instrukcja_11:


    Zapisać adresy do funkcji w tabeli i za pomocą:

       mov DPTR, .Tablica_instrukcji
       mov A,{instrukcja}
       jmp @A+DPTR


    Pomijając fakt, że nie mam pewności czy ten kawałek kodu jest poprawny to mam problem ze zbudowaniem tablicy adresów. Bascom zna słowo kluczowe db ale już dw nie.

    Pytaniem więc moim jest: czy ktoś wie jak zbudować tablicę adresów na funkcje w asm ale kompilowalny pod Bascom ? I czy kod powyższy jest poprawny dla takiej tablicy ?

    Pozdrowienia
  • REKLAMA
  • #2 1431878
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    Nie wiem jaki cel chcesz osiągnąć ,używając w Bascomie assemblera do wywoływania podprogramów.Procedurki pisz sobie w asm ale wywołuj je z poziomu bascoma.Nie prościej , jak poniżej:
    
    ...
    On instrukcja Gosub label_0,label_1,label_2,label_3,label_4,label_5
    ...
    label_0:
    $asm
       nop
       nop
    $end asm
    return
    ...
    label_x
    Print "Cośtam";
    return
    ...
    


    Piotrek

    PS
    No chyba , że o czymś nie wiem :wink:
  • REKLAMA
  • Pomocny post
    #3 1431919
    elektryk
    Poziom 42  
    Posty: 11029
    Pomógł: 439
    Ocena: 240
    wasi napisał:
       mov DPTR, .Tablica_instrukcji
       mov A,{instrukcja}
       jmp @A+DPTR

    Pomijając fakt, że nie mam pewności czy ten kawałek kodu jest poprawny to mam problem ze zbudowaniem tablicy adresów.
    Pomysł jest dobry, ale wykonanie złe ;), albo zrobisz pomnożysz A przez 2 albo 3 i pod adresem tablica instrukcji zrobisz serie skoków (bliski ma 2 bajty, daleki 3 bajty), albo pomnożysz przez większą wartość i zrobisz pod kolejnymi adresami po kilka instrukcji i na końcu ret który wróci do procedury wyższego rzędu (ew skok który wychodzi z tego rozwidlenia).
  • #4 1432419
    wasi
    Poziom 12  
    Posty: 75
    Ocena: 5
    W odpowiedzi dla "zumek":
    Na celu miałem optymalizację pamięciową programu. chciałem zaoszczędzić na instrukcjach. Jeśli chodzi o Bascoma i Asm to Bascom ma wygodne jak dla mnie środowisko (edytor, kompilator, programator) a procedurki w asm mało zajmują i drogą ewolucji zacząłem pisać całość kodu w asm pod Bascomem. I dlatego chciałem napisać obługę tej tablicy w asm.

    Rzeczywiście polecenie "On instrukcja gosub ..." jest tym co potrzebuję ale chciałem coś takiego w asemblerze uzyskać.

    W odpowiedzi dla "elektryk"a:
    rzeczywiście zapomniałem pomnożyć A * cokolwiek. Do uzyskania tablicy rzeczywiście można użyć skoków i tak też zrobiłem :)

    No i ostatecznie napisałem procedurkę:
    
    message:
       'polecenie w R6
       mov   dptr, #.tab
       mov   A,R6
       rl       A
       jmp   @A+dptr
    
    tab:
       ajmp  .No_message   '0
       ajmp  .get_inputs      '1
       ajmp  .set_output      '2
       ajmp  .No_message   '3
       ajmp  .No_message   '4
       ajmp  .No_message   '5
       ajmp  .No_message   '6
       ajmp  .No_message   '7
       ajmp  .No_message   '8
       ajmp  .No_message   '9
       ajmp  .set_adres       '10
       ajmp  .get_eeprom    '11
       ajmp  .set_eeprom    '12
       ajmp  .No_message   '13
       ajmp  .set_type         '14
       ajmp  .No_message   '15
    
    No_message:
       ret
    

    i zaoszczędziłem 10b w kodzie programu lub ok 20b gdybym miał obsługę wszystkich 15 poleceń w kolejnych warunkach. A 20b to już coś mając tylko 2048 :)

    Można to jeszcze optymalniej napisać?
  • #5 1432803
    olekewaagata
    Poziom 25  
    Posty: 638
    Pomógł: 64
    Ocena: 28
    Sam podprogram jest mało uniwersalny bo ma na stałe przypisane skoki. Leprzym rozwiazaniem jest podprogram o następującej budowie:
    ;----------------------------------------------------------------------------
    ; Wykonanie skoku do podanej etykiety w zaleznosci od wartosci w ACC
    ;---------------------------------------------------------------------
    ; LCALL JMPA
    ; DB nn Liczba etykiet skokow (bez nadmiarowej)
    ; DW ET0 Etykieta dla wartosci ACC = 0
    ; DW ET1 Etykieta dla wartosci ACC = 1
    ; .
    ; DW ETnn ;Etykieta dla wartosci ACC = nn
    ; DW ETexit ;Etykieta dla wartosci ACC > nn (POZA ZAKRESEM)
    ;----------------------------------------------------------------------------
    Tylko to jest dla tych którzy preferuja asm, bo w Bascomie to wszystko już jest.
  • REKLAMA
  • #6 1432930
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 52
    wasi napisał:
    W odpowiedzi dla "zumek":
    Na celu miałem optymalizację pamięciową programu. chciałem zaoszczędzić na instrukcjach. Jeśli chodzi o Bascoma i Asm to Bascom ma wygodne jak dla mnie środowisko (edytor, kompilator, programator) a procedurki w asm mało zajmują i drogą ewolucji zacząłem pisać całość kodu w asm pod Bascomem. I dlatego chciałem napisać obługę tej tablicy w asm.

    Skoro tak się sprawy mają , to ... kiepskie środowisko dla assemblera wybrałeś.Bascom do tego się nie nadaje :( .Spróbuj np. http://www.opcube.com/software/midepack0248.exe i masz 2 w 1 IDE+kompilatory dla asm i C.

    Piotrek

    PS
    Pomiętaj o 2kB stronach dla "ajmp".
  • REKLAMA
  • #7 1433721
    wasi
    Poziom 12  
    Posty: 75
    Ocena: 5
    Tak przeglądałem swój kod, zainstalowałem to IDE i wiem :) dlaczego nie pisałem całości w ASM. Nie potrafię inicjalizować portu szeregowego (lub przynajmniej nigdy nie próbowałem) i nie mam kompletnych procedur obsługi I2C. Do tej pory posługuję się instrukcjami bascoma do tego.
    I wzwiązku z tym zadam dodatkowe pytania :)

    1. Jak powinien wyglądać początek kodu programu dla 89C2051, który zrobi to samo co robi Bascom na starcie i uwzględni poniższe ustawienia jakie mam w programie?
    Cytat:

    $nosp
    Sp = &H70
    $crystal = 11059200
    $baud = 57600
    Config I2cdelay = 0


    2. Czy można gdzieś znaleźć gotowe procedurki w asm zastępujące bascomowe I2cstart, I2cwbyte, I2crbyte, I2cstop czy czeba coś takiego samemu sobie napisać i przetestować ?

Podsumowanie tematu

✨ Dyskusja dotyczy optymalizacji programu w Bascomie poprzez budowę tablicy adresów funkcji w asemblerze. Autor chciał zastąpić serię instrukcji warunkowych skokiem do funkcji za pomocą tablicy adresów, jednak napotkał problem z inicjalizacją takiej tablicy w Bascomie, który nie obsługuje słowa kluczowego dw (definicja słowa 16-bitowego). Proponowano użycie instrukcji "On ... Gosub" w Bascomie jako prostszą alternatywę oraz pomnożenie rejestru A przez odpowiednią wartość, aby poprawnie indeksować tablicę skoków. Zaprezentowano przykład procedury w asemblerze, gdzie tablica zawiera adresy skoków (ajmp) do poszczególnych funkcji, a indeks jest przesunięty (np. przez przesunięcie w lewo rejestru A). Wskazano, że Bascom nie jest optymalnym środowiskiem do pisania całego kodu w asemblerze, sugerując alternatywne IDE z obsługą asemblera i C. Autor dodatkowo pytał o inicjalizację i procedury obsługi portu szeregowego oraz I2C w asemblerze dla mikrokontrolera 89C2051, na co polecono notki aplikacyjne Atmela z przykładami w C, które można zaadaptować. Podsumowując, rozwiązaniem problemu jest tworzenie tablicy skoków w asemblerze z odpowiednim mnożeniem indeksu i użycie instrukcji ajmp, a także rozważenie mieszania Bascoma z asemblerem dla wygody i efektywności.
Wygenerowane przez model językowy.
REKLAMA