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.

ARM7TDMI Skoki bezwarunkowe (BL) - jak to robi kompiler

elektro255 29 Lip 2006 12:14 699 2
  • #1 29 Lip 2006 12:14
    elektro255
    Poziom 14  

    Witam,
    ostatnio bawię się troche w edycję softów w motoroloach, jednak nie moge rozszyfrować w jaki sposób kompiler liczy skoki bezwarunkowe.
    W nocie katalogowej jest:
    Cond+101L+Offset jednak jakoś to sie nie sprawdza w moim kodzie :)

    Chodzi mi o skoki z ardresem powrotu (linkiem) BL
    Dla bliskich skoków jest to odległość skoku, jednak dla długich to sie nie sprawdza.
    Dla skoku dalekiego instrukcja ma 4 bajty:
    np.:
    F1 EC F9 0F dla skoku z adresu 1023733A do 1042355C
    F6 50 FD 4A dla skoku z adresu 1023739C do 10087E34
    F1 54 FF 66 dla skoku z adresu 102373CC do 1038C29C
    F0 03 FD 99 dla skoku z adresu 102373E6 do 1023AF1C
    F7 FF FF 1B dla skoku z adresu 102373EE do 10237228

    Próbowałem liczyć tym sposobem: (adr1-adr2)/2 ale sprawdza sie tylko w niektorych przypadkach.

    Myśle że ktoś kto sie zajmuje ARM na codzien powienien wiedzieć jak to liczy kompiler :)

    Oczywiście za odpowiedź sypne punktami :)



    P.S. Posiadam internet przez GPRS wiec nie moge ściągać żadnych kompilerów ASM dlatego zadaje te pytanie :)

    0 2
  • #2 31 Lip 2006 18:32
    vibrasphere
    Poziom 14  

    Podaję za Arm Architecture Manual:

    Tak wygląda kodowanie instrukcji (a konkretnie 24 bitów odpowiedzialnych za offset)

    To calculate the correct value of signed_immed_24, the assembler (or other toolkit component) needs to:
    1. Form the base address for this branch instruction. This is the address of the instruction, plus 8. In
    other words, this base address is equal to the PC value used by the instruction.
    2. Subtract the base address from the target address to form a byte offset. This offset is always a multiple
    of four, because all ARM instructions are word-aligned.
    3. If the byte offset is outside the range -33554432 to +33554428, use an alternative code-generation
    strategy or produce an error as appropriate.
    4. Otherwise, set the signed_immed_24 field of the instruction to bits{25:2] of the byte offset.


    Tak wygląda proces dekodowania:

    The branch target address is calculated by:
    1. Sign-extending the 24-bit signed (two’s complement) immediate to 32 bits.
    2. Shifting the result left two bits.
    3. Adding this to the contents of the PC, which contains the address of the branch
    instruction plus 8.
    The instruction can therefore specify a branch of approximately ±32MB.

    Dodawanie 8 do adresu instrukcji trzeba prawdopodobnie uwzględnić ze względu na pipeline.

    Próbowałem powtrórzyć w/w procedurę na Twoich przykładach, ale jak odejmiesz od siebie adresy to wychodzi liczba która jest niepodzielna przez 4.

    Zauważ że po odjęciu, do instrukcji bierze się jedynie bity [25:2]

    0
  • #3 13 Lut 2007 09:59
    elektro255
    Poziom 14  

    długie skoki w procesoracz ARM są zapisane w 22 bitach po 11 bitów w 2 słowach
    w formacie 11110xxxxxxxxxxx11111xxxxxxxxxxx
    gdzie xxx to różnica adresów podzielonych przez 2.



    algorytm w delphi
    adr1 - adres z którego wywołujemy skok
    adr2 - adres do którego wywyołujemy skok

    temp:=(adr1-adr2)-2;
    if (temp<$FFC00000) and (temp>$3FFFFF) then label6.Caption:='Overflow!' else label6.Caption:='';
    label4.Caption:=inttohex(temp,8);
    t1:=temp AND $7FF;
    t2:=(temp AND $3FF800) shl 5;
    t3:=$F000F800;
    t4:=t3 or t1;
    t4:=t4 or t2;
    edit3.Text:=inttohex(t4,8); - w t4 otrzymujemy wynik

    0