Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ASEMBLER] konwersja z pliku hex na asm

picassek 26 Cze 2010 22:07 3579 9
  • #1 26 Cze 2010 22:07
    picassek
    Poziom 9  

    Witam, sprawa wygląda następująco, mam napisany program w bascomie 8051 pod mikrokontroler 89c2051, skompilowałem go i uzyskałem plik hex. Pobrałem z sieci program IDA Pro Advanced ver. 5.5. Otworzyłem w nim plik hex, wybrałem processor type intel 8051 a następnie w opcjach procesora model 89c2051. Uzyskałem w ten sposób kod asemblera. Moje pytanie jest następujące, na ile ten kod jest poprawny? czy dużo jest roboty, żeby uzyskać z tego działający kod asemblera? potrzebuje kod programu w asemblerze, a pisanie go od zera jest dla mnie czarną magią jaką jest asembler. Poniżej umieszczam fragment tego co uzyskałem.

    Code:

    ; public start
    start:
    jbc     RAM_20.0, extint0
    ; End of function start
    ; External interrupt 0 (INT0 / EX0)

    ; public extint0
    extint0:
    nop
    xchd    A, @R0
    ljmp    CODE_6B1
    ; End of function extint0
    ; START OF FUNCTION CHUNK FOR extint0
    CODE_6B1:
    add     A, R0
    cjne    A, #4, CODE_6B7
    ; START OF FUNCTION CHUNK FOR extint0
    CODE_70D:
    mov     @R1, RAM_75
    mov     DPTR, #2
    inc     @R0
    ajmp    CODE_2E4+1
    ; END OF FUNCTION CHUNK FOR extint0
    CODE_6B7:
    inc     RAM_10
    jz      CODE_6C0
    ; START OF FUNCTION CHUNK FOR extint0

    CODE_6C0:
    movx    @DPTR, A
    ljmp    CODE_5A7
    ; END OF FUNCTION CHUNK FOR extint0
    ; START OF FUNCTION CHUNK FOR extint0

    CODE_5A7:
    inc     R3
    mov     RAM_C, #0xA6 ; 'Ž'
    mov     RAM_D, #0x20 ; ' '
    mov     RAM_E, #0
    mov     RAM_27, #4
    jbc     P10, CODE_5BA+1

    nop
    acall   CODE_58

    CODE_5BA:
    jz      CODE_5BF
    CODE_5BF:
    mov     A, #1
    ljmp    CODE_49F
    ; END OF FUNCTION CHUNK FOR extint0
    ; Timer interrupt 0 (TIM0)

    ; public timint0
    timint0:
    nop
    nop
    ljmp    CODE_645
    ; End of function timint0
    ; START OF FUNCTION CHUNK FOR timint0

    CODE_645:
    add     A, R1
    nop
    acall   CODE_510
    clr     P30
    mov     A, #0xC8 ; 'L'
    acall   CODE_8B
    ljmp    CODE_118
    ; END OF FUNCTION CHUNK FOR timint0

    Pozdrawiam

    0 9
  • #2 26 Cze 2010 22:57
    atom1477
    Poziom 43  

    Nie rozumiem i nie zrozumiem.
    Masz napisany kod w assebblerze. Kompilujesz go, dekompilujesz go, i ten zdekompilowany kod chcesz przerabiać? Na assemblera?

    0
  • #3 26 Cze 2010 23:10
    picassek
    Poziom 9  

    kod programu mam napisany i skompilowany w bascomie 51. Podczas kompilacji programu w bascomie uzyskałem plik hex i ten otrzymany plik hex chciałbym zamienić na kod asemblera, żeby nie pisać programu od podstaw w asemblerze. Użyłem programu IDA, żeby z pliku hex otrzymać kod w asemblerze, ale nie wiem czy tak uzyskany kod jest poprawny, czy trzeba w nim mino wszystko wprowadzić poprawki.

    0
  • #4 27 Cze 2010 00:04
    kemot55
    Poziom 30  

    Wybrałeś drogę przez "pokrzywy" :-). Może i dobrze. Jak się poparzysz to będziesz inaczej patrzył na temat programowania. W sumie można i deasemblować. Ale zobacz pierwsze linijki (zaraz po etykiecie start). Moim zdaniem wpakowana jest tam instrukcja bez sensu (jeżeli flaga ustawiona lub wyzerowana to skocz do...).
    Kod po deasemblacji jest "nienaturalny". Trudno się połapać o co chodzi. I jeszcze etykiety w stylu "CODE_6B1" - brrr. Dodatkowo jeżeli w kodzie będą dane to zostaną one przedstawione w postaci listy rozkazów co też jest koszmarem. 8051 jest prostym zwierzakiem i b. łatwo się jest nauczyć go programować. Poza tym zawsze można to zrobić w C.
    Wracając do tematu. Po deasemblacji trzeba znaleźć jeszcze asemblera, który wytworzy odpowiedni kod i tu może być mały kłopocik.
    A tak a'propos słonia bascom nie generuje przypadkiem jakiegoś kodu assemblerowego (np. listingów?).

    Generalnie unikałbym stosowania programów deasemblujących - kilka razy straciłem tylko na tym czas.

    0
  • #5 27 Cze 2010 12:23
    picassek
    Poziom 9  

    zdaje sobie sprawe ze jest to wyprawa w dżungle. Ale nie moge połapać się w asemblerze, a niestety potrzebuje kod napisany w tym języku. A co do bascoma to raczej nie generuje kodu asemblerowego, w plikach wyjsciowych jakie są do utworzenia jest tylko binary, debug, hex, report, error i NOI file.
    Jeżeli 8051 jest prostym zwierzakiem, to jak uporać się z tym kodem

    Code:

    Temp = B2 * 256
    Temp = Temp + B1

    If Temp < 859 Then
       Call Ledy_(8 , 0)
       Booz_ = 1
    Elseif Temp > 860 And Temp < 2109 Then
       Call Ledy_(7 , 0)
       Booz_ = 1
    Elseif Temp > 2108 And Temp < 3359 Then

    oraz

    Select Case Gd
       Case 0 :
          Select Case Nled
             Case 0 : Ledy = 255
             Case 1 : Ledy = 254
             Case 2 : Ledy = 252
    itd

    Pozdrawiam

    0
  • #6 27 Cze 2010 19:45
    kemot55
    Poziom 30  

    Twój kod jest poszarpany więc tłumaczenie na asm będzie przykładowe.

    Code:

    Ledy   EQU   90h ;(port P1)

       ISEG      ;Deklaracja komórek pamięci 1-bajtowych
       ORG   29H
    B1:   DS   1   
    B2 :   DS   1   
    temp:   DS   2   
    GD:   DS   1
    Nled:   DS   1
    Booz:   DS   1
       
       CSEG   
       ORG   0
       MOV   SP,#0E0H

    ;warunki if nie są kompletne (dziury!) np. nie ma definicji akcji dla wartości ;temp=859.

       mov   a,B2
       cjne   a,#03h,skok1
       mov   a,B1
       cjne   a,#5Bh,skok1
       sjmp   wieksze859
    skok1:
       jnc   wieksze859
       mov   a,#80h
       acall   LedyProc
       sjmp   koniec
    wieksze859:

    ;reszta "ifów" -> podobnie jak wyżej
    koniec:

       mov   a,GD
       cjne   a,#0,highlevel1
       mov    a,Nled
       cjne   a,#0,lowlevel1
       mov   Ledy,#255
       sjmp   highlevel1
    lowlevel1:
       cjne   a,#1,lowlevel2
       mov   Ledy,#254
       sjmp   highlevel1
    lowlevel2:
       cjne   a,#2,lowlevel3
       mov   Ledy,#252
       sjmp   highlevel1
    lowlevel3:

    highlevel1:
       mov   a,GD
       cjne   a,#1,highlevel2
    highlevel2:
       sjmp    $


    LedyProc:
       ORL   Ledy,A
       RET

       END

    0
  • #7 27 Cze 2010 20:38
    picassek
    Poziom 9  

    kod w całości wygląda następująco:

    Code:

    $crystal = 12000000  // ustawienie częstotliwości zegara taktującego procesor (liczba określająca częstotliwość w Hz kwarcu lub oscylatora taktującego procesora)
    $regfile = "89C2051.DAT"
    Config Timer0 = Timer , Gate = Internal , Mode = 1 
    Tmod.3 = 1
    Tmod.7 = 0
    Gate_alias P3.7
    Booz_alias P3.0    
     Ledy Alias P1 
    Dim Temp As Long 
    Dim Error As Byte
    Dim B1 As Byte   
    Dim B2 As Byte   
    Declare Sub Ledy_(nled As Byte , Gd As Byte)
    Dim Nled As Byte
    Dim Gd As Byte   
    On Timer0 Timer0_int
    On Int0 Int0_int
    Tcon.0 = 0         
    Priority Set Int0 
    Enable Interrupts   
    Enable Timer0     
    Disable Int0       

    'Początek programu

    Booz_ = 0         
    Gate_ = 1         
    Call Ledy_(8 , 0) 

    'Początek pętli głównej

    Do
       Error = 0   
        Th0 = 0   
        Tl0 = 0 
       Gate_ = 0 
        Delay   
        Delay 
        Delay 
        Delay 
        Delay 
       Gate_ = 1 
      Tcon.4 = 1
      Waitms 1     
        Delay   
        Delay   
        Delay   
        Delay   
        Delay   
      Tcon.1 = 0
     Enable Int0

    Do

     Error.1 = Tcon.5     

    Loop Until Error > 0

       If Error.0 = 1 Then 
       Call Ledy_(0 , 0)     
       Booz_ = 0
       Print "T"           
    Elseif Error.1 = 1 Then 
       B1 = Tl0               
       B2 = Th0             

    Temp = B2 * 256         
    Temp = Temp + B1         

    If Temp < 860 Then       
       Call Ledy_(8 , 0)     
       Booz_ = 1             
    Elseif Temp > 859 And Temp < 2109 Then 
       Call Ledy_(7 , 0) 
       Booz_ = 1         
    Elseif Temp > 2108 And Temp < 3359 Then
       Call Ledy_(6 , 0)
       Booz_ = 1




    Elseif Temp > 3358 And Temp < 4609 Then 
       Call Ledy_(5 , 0)
       Booz_ = 1
    Elseif Temp > 4608 And Temp < 5859 Then 
       Call Ledy_(4 , 0)
       Booz_ = 0  // buzer się nie włącza
    Elseif Temp > 5858 And Temp < 7109 Then
       Call Ledy_(3 , 0)
       Booz_ = 0
    Elseif Temp > 7108 And Temp < 8359 Then
       Call Ledy_(2 , 0)
       Booz_ = 0
    Elseif Temp > 8358 And Temp < 10000 Then
       Call Ledy_(1 , 0)
       Booz_ = 0
    Elseif Temp > 9999 Then 
       Call Ledy_(0 , 0) 
       Booz_ = 0       

    End If  // konie
    End If
    Waitms 200
    Loop

    'Koniec pętli głównej

    Sub Ledy_(nled As Byte , Gd As Byte)
    Select Case Gd                 
       Case 0 :                     
          Select Case Nled         
             Case 0 : Ledy = 255   
             Case 1 : Ledy = 254
             Case 2 : Ledy = 252
             Case 3 : Ledy = 248
             Case 4 : Ledy = 240
             Case 5 : Ledy = 224
             Case 6 : Ledy = 192
             Case 7 : Ledy = 128
             Case 8 : Ledy = 0
          End Select       
       Case 1 :
          Select Case Nled
             Case 0 : Ledy = 255
             Case 1 : Ledy = 127
             Case 2 : Ledy = 63
             Case 3 : Ledy = 31
             Case 4 : Ledy = 15
             Case 5 : Ledy = 7
             Case 6 : Ledy = 3
             Case 7 : Ledy = 1
             Case 8 : Ledy = 0
          End Select   
    End Select        
    B2 = Ledy       
    End Sub         

    Timer0_int:   
    '  Incr Over_count 
    '  If Over_count > 9 Then 
    '  Tcon.4 = 0       
      Disable Int0     
       Error.0 = 1     
    '  End If       
    Return         

    Int0_int:           
       Tcon.4 = 0     
      Disable Int0   
       Error.1 = 1 
    Return

    End

    przy if-ie w zakresie wiekszym od 859 a mniejszym od 2109 chodziło mi o to, żeby w tym zakresie zapalało sie 7 Ledów oraz włączał się buzer, zmienić lepiej te wartości na temp > 860 i temp < 2010 ?
    a co do deasemblera to udowodnileś mi własnie jakie to są maliny
    pozdrawiam

    0
  • #8 27 Cze 2010 20:42
    atom1477
    Poziom 43  

    Nie o to chodziło.
    Chodziło o to:

    Cytat:

    If Temp < 859 Then
    ...
    Elseif Temp > 860 And Temp < 2109 Then
    ...


    Czyli o to że wartości 859 i 869 nie były obsługiwane.
    Ale to już nieaktualnie bo w tym nowym kodzie poprawiłeś się.

    0
  • #9 27 Cze 2010 23:39
    picassek
    Poziom 9  

    czyli dla przypadków Case powinno to wygladać tak ?

    Code:

    ; case 0
       mov   a,GD
       cjne   a,#0,highlevel1
       mov    a,Nled
       cjne   a,#0,lowlevel1
       mov   Ledy,#255
       sjmp   highlevel1
    lowlevel1:
       cjne   a,#1,lowlevel2
       mov   Ledy,#254
       sjmp   highlevel1
    lowlevel2:
       cjne   a,#2,lowlevel3
       mov   Ledy,#252
       sjmp   highlevel1
    lowlevel3:
       cjne   a,#3,lowlevel4
       mov   Ledy,#248
       sjmp   highlevel1
    lowleve14
       cjne   a,#4,lowlevel5
       mov   Ledy,#240
       sjmp   highlevel1
    lowlevel5
       cjne   a,#5,lowlevel6
       mov   Ledy,#224
       sjmp   highlevel1
    lowlevel6
       cjne   a,#6,lowlevel7
       mov   Ledy,#192
       sjmp   highlevel1
    lowlevel7
       cjne   a,#7,lowlevel8
       mov   Ledy,#128
       sjmp   highlevel1
    lowlevel8
       cjne   a,#8,
       mov   Ledy,#0
       sjmp   highlevel1

    ; case 1
       mov   a,GD
       cjne   a,#1,highlevel1
       mov    a,Nled
       cjne   a,#0,lowlevel1
       mov   Ledy,#255
       sjmp   highlevel1
    lowlevel1:
       cjne   a,#1,lowlevel2
       mov   Ledy,#127
       sjmp   highlevel1
    lowlevel2:
       cjne   a,#2,lowlevel3
       mov   Ledy,#63
       sjmp   highlevel1
    lowlevel3:
       cjne   a,#3,lowlevel4
       mov   Ledy,#31
       sjmp   highlevel1
    lowleve14
       cjne   a,#4,lowlevel5
       mov   Ledy,#15
       sjmp   highlevel1
    lowlevel5
       cjne   a,#5,lowlevel6
       mov   Ledy,#7
       sjmp   highlevel1
    lowlevel6
       cjne   a,#6,lowlevel7
       mov   Ledy,#3
       sjmp   highlevel1
    lowlevel7
       cjne   a,#7,lowlevel8
       mov   Ledy,#1
       sjmp   highlevel1
    lowlevel8
       cjne   a,#8,
       mov   Ledy,#0
       sjmp   highlevel1
       
    highlevel1:
       mov   a,GD
       cjne   a,#1,highlevel2
    highlevel2:
       sjmp    $

    ale tego z if-ami nie łapie, jak zrobić gdy wartość jest pomiędzy wartościami Temp 860 a 2009 ?
    a za początek kodu jak się najlepiej zabrać ?

    0
  • #10 28 Cze 2010 12:48
    kemot55
    Poziom 30  

    Jak już się zdecydowałeś pokazać do końca program to bym to zapisał tak:

    Code:

       iseg
       ORG 30h
    GD:   DS   1
    NLed:   DS   1

       cseg
       ORG   0
       mov   GD,#1     ;do testów na symulatorze
       mov   NLed,#7  ;j.w.

       mov   A,GD
       cjne   A,#0,skok1

       mov   A,NLed
       jz   zapis
       mov   R7,A
       mov   A,#0FFh
    nextloop1:
       clr   c
       rlc   A
       djnz   r7,nextloop1
       mov   P1,A
       sjmp   koniec
    zapis:
       mov   P1,#0FFh
       sjmp   koniec
    skok1:
       mov   A,NLed
       jz   zapis2
       mov   R7,A
       mov   A,#0FFh
    nextloop2:
       clr   c
       rrc   A
       djnz   r7,nextloop2
       mov   P1,A
       sjmp   koniec
    zapis2:
       mov   P1,#0FFh
       sjmp   koniec      
    koniec:
       sjmp   $
       END

    To wynik po małej optymalizacji :-)
    Sugeruję żebyś sobie zassał symulator z linku Symulatory
    Do kompilacji załączam prosty, ale inteligentny programik.
    Spróbuj napisać kod do warunków. Jest z tym może trochę zabawy, ale nie jest to jakiś kosmos.
    Program należy zacząć należy zawsze od określenia stosu i konfiguracji procesora (timery, porty, RS'y, przerwania itd.)

    0