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

Assembler kilka pytań

Ajatol 30 Maj 2009 07:50 2763 8
REKLAMA
  • #1 6592715
    Ajatol
    Poziom 15  
    Nadszedł czas na assembler i przerabiając po kolei rozkazy jak na razie znalazłem 2 które działają dla mnie niejasno.

    1.Jaki powinien być wynik tej operacji.
    
    ldi r24,$FE
    ldi r25,$03
    adc r24,r25

    W symulacji w Avr Studio otrzymuje wynik 01
    ale przecież powinno być 02 ponieważ dodawana jest również flaga C(przepełnienie).
    Avr studio pokazuje że flaga C została ustawiona ale w wyniku jej nie uwzględnia ?.

    2.
    
    ala:
    nop
    brcc ala         ;skocz gdy flaga C = 0    
    nop


    Komenda
    powinna skoczyć do etykiety ala gdy flaga c jest wyzerowana no i skacze ale jeżeli w symulacji
    zatrzymam program na lini brcc ala flaga c ma wartość 1 i teraz zmieniam to flagę na 0 (czyli ustawiam spełnienie warunku dla skoku)
    to i tak mi nie skoczy ale gdy flagę C zmienię na zero jeden rozkaz wcześniej czyli żółta strzałka na komendzie nop bezpośrednio
    przed
    to teraz dochodząc do rozkazu skoku (flaga C jest 0) skok jest poprawny.
    Czy to ma związek z tym że w trakcie wykonywania jednego rozkazu pobiera już sobie następny.

    3. Gdzie w Avr studio ustawić numerowanie lini w edytorze (ver 4.16)

    Poprawiłem treść i dodałem znaczniki [code]
    Proszę zwracać uwagę na pisownię - pkt.15 regulaminu.
    Proszę stosować znaczniki [code].
    [zumek]
  • REKLAMA
  • #2 6592895
    Elektrooonik
    Poziom 29  
    Ad1. Takie dodawanie nie ma sensu jeśli dodajesz tylko dwa ośmiobitowe rejestry, (tzn ma sens tylko w skrajnych udziwnionych przypadkach :) ) flaga C jest ustawiana dopiero po wykonaniu dodawania czyli rozkaz ADC w tym momencie dodaje poprostu te dwa bajty i dopiero ustawia znacznik C i może on być użyty dopiero w następnej instrukcji
    Ad2. Tak, musisz ustawiać znacznik zanim strzałka znajdzie się na tej linii programu jeśli chcesz sprawdzić działanie tej linijki
  • REKLAMA
  • #3 6594577
    Ajatol
    Poziom 15  
    Odnosnie punktu 1 sprawdziłem i swieta racja.

    add r2,r0 ; Dodaj low byte
    adc r3,r1 ; Dodaj with carry high byte

    Teraz działa jak należy.

    Odnośnie punktu 2 to dziwne i nielogiczne dla mnie bo wygląda jakby przewidział jaki będzię stan flagi C po wykonaniu rozkazu bezpośrednio przed rozkazem skoku. No ale skoro tak józ jest to trzeba po poprostu przywyknać ale odrobine mi to miesza w głowie.
  • REKLAMA
  • #4 6595094
    11111olo
    Poziom 42  
    Ajatol podałeś taki przykład z którego nic nie wynika.

    Sprawdź taki prosty program i wtedy stwierdź czy jesteś w stanie przewidzieć jaki będzie stan flagi.

    ldi r16,1
    ldi r17,2
    start:
    cp r16,r17
    brcc dalej
    inc r16
    dalej:
    inc r17
    rjmp start


    Musisz przyjąć że to jest tylko symulator i robienie ręcznych zmian rejestrów procesora nie występuje w praktyce, czyli twoje działania są bezcelowe.
    Można zmienić wartość jakiegoś rejestru roboczego w celu sprawdzenia warunku, który może nastąpić w jakiejś skrajnej sytuacji.
  • REKLAMA
  • #5 6595203
    Ajatol
    Poziom 15  
    Tak po cichu przypuszczałem że to ma związek z symulacją . Dzięki za wyjaśnienie.
  • #6 6596951
    Ajatol
    Poziom 15  
    No i porwałem sie na rozkaz LPM i mam problemy ze zrozumieniem.
    Taki prosty przykład poniżej.
    
    .include "m128def.inc"
    .EQU fq = 8000000        ; XTal frequency definition
    ldi r20,$00 
    out SPL,r20 
    ldi r20,$05 
    out SPh,r20              ; stos ustawiony na $0500 
    
    start: 
    LDI ZH,HIGH(MyTable*2)   ; Adress of table to pointer Z
    LDI ZL,LOW(MyTable*2)    ; multiplied by 2 for bytewise access
    ADIW ZL,10               ; Point to fifth value in table
    LPM                      ;Read least significant byte from program memory
    MOV R24,R0               ; Copy LSB to 16-bit register
    ADIW ZL,1                ; Point to MSB in program memory
    LPM                      ; Read MSB of table value
    MOV R25,R0               ; Copy MSB to 16-bit register
    
    .org $0050
    MyTable:
    .DW 0x1234,0x2345,0x3456,0x4568,0x5678 ; The table values, wordwise
    .DW 0x6789,0x789A,0x89AB,0x9ABC,0xABCD ; organised
    
    


    Program ma odczytać 5 element z tablicy i umieścić odczytaną wartość w rejestrach R24 , R25 . Robi to poprawnie ale nie mogę zrozumieć jak. Siedzę jóż sporo czasu czytając pdfa ale dalej jestem zakłopotany.
    Co wiem.
    1.
    Pierwsze dwa rozkazy ustawiają rejestr Z na początek tabeli. Nie rozumiem dlaczego ten rejestr jest ustawiany na wartość $00A0 skoro ustawiłem dyrektywo że tabela ma się zapisać od adresu $0050 i tak żeczywiście jest zapisana co widać w okienku podglądu pamięci.

    Assembler kilka pytań

    2.
    Następny rozkaz dodaje 10 żeby wskazać na 5 element ale pamięć programu ma organizacje 16 bitową więc według mnie to powinno być dodawane 5 a nie 10 ponieważ moje dane w tabeli są 16 bitowe. Rejestr Z ma teraz wartość $00AA.
    3.
    Teraz jest LPM czyta mniej znaczący bajt 5 elementu. Odczytuje 89 ale to jest 6 komórka tabeli a nie 5 no chyba że tabele liczymy od 0.
    Dalej incrementacja Z i odczyt bardziej znaczącego bajtu i na koniec umieszczenie odczytanej wartości w rejestrach R24 , R25.

    Najtrudniejsze do zrozumienia dla mnie jest fakt że tabele umieszczam od adresu $0050 a program ustawia rejestr Z do odczytu tabeli na zupełnie inną wartość $00AA. Pod tym adresem nic w pamięci niema oprócz FF ale na koniec wartość w rejestrach R24 , R25 jest poprawna.
    Normalnie kosmos.

    Proszę poprawić błędy w pisowni - regulamin p.15
    [zumek]
  • #8 6596982
    Ajatol
    Poziom 15  
    Dzięki za linka. Wyjaśnił mi sporo , chociaż do końca to jeszcze nie czuję tej instrukcji , ale to dopiero trzeci dzień z assemblerem więc powinienem być dla siebie wyrozumiały.
REKLAMA