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

Dziwne zachowanie kompilatora w AVRStudio

narasta 08 Cze 2009 22:18 941 6
  • #1 6632878
    narasta
    Poziom 21  
    Swojego czasu próbowałem upchnąć program w attiny13 (1kb ROM) i mi się nie udało. Ostatnio przekonałem się do asemblera wiec przyszedł czas żeby projekt który chciałem zrobić - skończyć. Na razie zacząłem pisać to w symulatorze. Zatrzymałem się już na takim etapie:

    
    .nolist
    .include "tn13def.inc"
    .list
    
    
    .DEF q1 = R16
    
    rjmp start
    
    
    start:
    
    
    main_loop:
    
    	rjmp subroutine
    
    rjmp main_loop
    
    
    
    ;----------------------------------------
    subroutine:
    
    	ldi q1,123
    	
    ret
    
    


    i za każdym razem jak wychodzi z sabrutyny to leci na sam początek programu. Dlaczego się tak dzieje?

    Jestem przyzwyczajony do tego, że języki wysokiego poziomu same zajmują się stosem... Tu nie mam pojęcia co z tym zrobić...
  • #2 6632944
    dj_west
    Poziom 17  
    Być może dlatego, że do wywołania "sabrutyny", z której chcesz powrócić do miejsca wywołania za pomocą instrukcji ret należy użyć instrukcji call.
  • #3 6632977
    narasta
    Poziom 21  
    instrukcja nie jest obsługiwana przez attiny13.

    Okazuje się, że działa dla 'rcall'.

    Wcześniej pisałem program dla atmegi8 i próbowałem tego i nie chciało działać. Wyskakiwał mi bład "stack underflow at 0x/adres/"

    No nic, ważne, że działa teraz.
  • #4 6633011
    mirekk36
    Poziom 42  
    dj_west napisał:
    Być może dlatego, że do wywołania "sabrutyny", z której chcesz powrócić do miejsca wywołania za pomocą instrukcji ret należy użyć instrukcji call.


    dobrze kolega podpowiada - tylko, nie być może - a na pewno dlatego ;)

    tylko proszę autora - używaj ludzkich nazw typu podporogram, procedura, funkcja itp a nie "subrutyna" ;)

    a skoro się przesiadasz na asembler - to musisz sam zadbać o stos - to nie jest trudne i żeby pisać sofcik w asm trzeba się tego nauczyć - szczególnie ustawienia stosu na początku programu na koniec pamięci SRAM bo inaczej kicha totalna.

    1. masz nie ustawiony stos
    2. zamiast skoczyć do swojej procedury rozkazem call robisz skok bezwarunkowy rjmp a na końcu dajesz ret
    3. a ret - próbuje zdjąć ze stosu (który na dodatek nie został ustawiony) adres powrotu do miejsca za rozkazem call - no i dalej to już możesz sam sobie wyobrazić co się dzieje - wielki HAOS ;) po czym następuje reset procka i tobie wydaje się, ze program z procedury wraca do początku

    teraz jaśniej

    a jak chcesz język wyższego poziomu ale dobry to sięgnij po C - tam stosem też nie będziesz musiał się specjalnie zajmować - przynajmniej na początku swojej kariery w C
  • #5 6633102
    dj_west
    Poziom 17  
    :D Oczywiście, że na pewno, ale tyle problemów i dziwnych rozwiązań na elektrodzie już widziałem, że zaczynam do wszystkiego podchodzić asekuracyjnie :)
  • #6 6633478
    narasta
    Poziom 21  
    Już od dawna piszę w C a jeszcze dawniej pisałem w bascomie. Asemblera potrzebuje bo się nie mieszczę w 1kb romu :)

    inicjalizacja stosu dla at13
    
    .def q1 = R16
    
    LDI q1, LOW(RAMEND) ; Lower byte
    OUT SPL,q1 ; to stack pointer
    




    Ok teraz pytanie trochę z innej beczki: Jak zapisać jakeiś dane w pamięci ROM i potem móc je odczytać?

    zapis:
    etykieta: .DB 0xAB,0xFD

    odczyt
    ldi ZL,LOW(etykieta) ; odczytuje niższy bajt adresu danych
    ldi ZH,HIGH(etykieta) ; odczytuje wyższy bajt adresu danych

    tylko teraz jak odczytać któyś bajt z tej etykiety i np przypisać go do jakiegoś portu?
  • #7 6633665
    tprzemko
    Poziom 22  
    Witam

    etykieta: .DB 0xAB,0xFD 
    
    ldi ZL,LOW(etykieta<<1) ; zapisuje do Z adres danych
    ldi ZH,HIGH(etykieta<<1) ;  
    
    lpm       ;
    
    out "port",R0

    Na port zostanie wystawiona wartość AB

    Pozdrawiam
REKLAMA