-
+ Antworten
Seite 1 von 7 123 ... LetzteLetzte
Ergebnis 1 bis 10 von 65

Thema: Bascom Inline-Assembler

  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    21
    Beiträge
    1.450

    Bascom Inline-Assembler

    Hallo,

    möchte nun versuchen, eine ISR von Bascom nach ASM zu übersetzen. Ich denke, der Großteil ist mir auch gelungen, jedoch habe ich auch nach mehrstündigem Suchen im Web keine Tipps gefunden, wie man ein Array KONKRETT in ASM anspricht. Vielleicht kann mir das jemand erklären? Hier mal mein Code:
    Bascom:
    Code:
    Isr_int0:
    If Channel > 0 And Channel < 6 Then
      Empf(channel) = Timer0
    End If
    Timer0 = 6
    Incr Channel
    Return
    Datentypes:
    Code:
    Dim Empf(5) As Word                             
    Dim Channel As Byte
    Dim Empf_tmp As Word
    Hier mein Übersetzungsversuch:
    Code:
    Isr_int0:
    
    push r16                                                    'sichere r16
    
    lds r16 , {channel}                                         'lade channel in r16
    cpi r16 , 6                                                 'vergleiche r16 mit 6
    brlo _lower                                                 'springe, wenn kleiner
    rjmp _out_of_range                                          'sonst springe nach _out_of_range
    _lower:                                                     '_lower Label
    cpi r16 , 1                                                 'vergleiche r16 mit 1
    brge _higher                                                'springe, wenn größer gleich
    rjmp _out_of_range                                          'sonst springe nach _out_of_range
    _higher:                                                    '_higher Label
    '###
    in r16 , tcnt0
    sts {empf_tmp} , r16
    Empf(channel) = Empf_tmp
    '###
    _out_of_range:                                              '_out_of_range Label
    ldi r16 , 6                                                 'lade 6 in r16
    !out tcnt0 , r16                                            'schreibe r16 in timer0
    lds r16 , {channel}                                         'lade Channel in r16
    inc r16                                                     'erhöhe Channel um 1
    sts {channel} , r16                                         'lade r16 in Channel
    
    pop r16                                                     'stelle r16 wieder her
    
    Return
    Meint ihr, das würde so funktionieren? Laut Simulation siehts ganz gut aus. Habt ihr noch Tipps, wie ich das ganze noch etwas verschlanken kann? Bin mir nicht sicher, ob die If-Else-Abfrage nicht noch etwas eleganter / kürzer ginge?

    Außerdem wollte ich noch fragen, wie das ist, wenn man einem Word ein Byte in ASM zuweist? Soweit ich das verstanden habe, wird das Byte in das untere Byte des Words geschrieben, weil man ja das höherwertige Byte des Words mit {Word+1} anspricht, oder?

    Vielen Dank schonmal
    Gruß
    Chris

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Du benötigst die Helperfunktion Loadadr dafür. Wenn das Array von 0 beginnen darf, kann das SBIW entfallen.
    Code:
    Loadadr myArr(1) , Z
    !LDS   R18,   {ArrPtr}
    !LDS   R19,   {ArrPtr+1}
    !SBIW  ZL,    1
    !ADD   ZL,    R18
    !ADC   ZH,    R19
    !LD    R16,   Z
    !STS   {Rslt},R16
    Der Code ist selbsterklärend und sollte alle Deine Fragen beantworten.
    Loadadr benutzt außer dem angegebenen Pointerregister keine weiteren Register, es muss also dafür nichts zusätzlich gesichert werden.
    Geändert von MagicWSmoke (19.12.2011 um 09:41 Uhr)

  3. #3
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.820
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  4. #4
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Unter diesem Link seh' ich aber nix zum absoluten Adressieren von Arrays, Loadadr kommt zwar vor, wird aber zur sequentiellen Adressierung benutzt, einmal bei Strings und einmal um ein Word zu holen.

    Der Trick bei der absoluten Adressierung ist dagegen, sich die Basisadresse zu holen und den Index aufzuaddieren. Da im vorliegenden Beispiel der Code in einer ISR ausgeführt wird, muss der Index immer wieder neu geholt werden, sequentielle Adressierung ist nicht brauchbar.

  5. #5
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    21
    Beiträge
    1.450
    Hallo,

    danke, das hilft mir schon mal sehr weiter
    ABER:
    Wie lade ich denn den Wert wieder ins Array? Im Endeffekt möchte ich folgendes nach ASM umsetzen:
    Code:
    Dim Empf(5) As Word
    Dim Channel As Byte
    ...
    ISR:
    Empf(channel) = Timer0
    Außerdem ist zu beachten, dass Empf() ein Word ist, aber ich denke, das macht nichts!?
    Sorry, für meine etwas blöden Fragen, aber ich habe noch nicht viel in ASM gemacht, außer ein paar If-Abfragen und Blink-Programme - ausschließlich mit Byte-Datentypen.

    Gruß
    Chris

  6. #6
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Wie lade ich denn den Wert wieder ins Array?
    Mit dem Gegenpart des "LD"-Befehls, dem "ST"-Befehl, das wiederum ist im Tutorial zu finden.
    Sinnvollerweise mit postincrement, da wird der X,Y oder Z-Pointer nach Ausführung um 1 erhöht.
    dass Empf() ein Word ist, aber ich denke, das macht nichts!?
    "Macht nichts" ist der falsche Ausdruck, natürlich muss darauf reagiert werden, die X,Y & Z-Pointerei ist Byte-orientiert, damit entspricht WordArr(3) dem 5. & 6. Byte. Du musst also den Index, bevor Du ihn zur Basisadresse addierst, mal 2 nehmen. Am schnellsten geht's, wenn Du ihn einmal nach links schiebst, das geht mit LSL für das LB und ROL für das HB.
    Wenn Dein Array nur 5 Elemente groß ist, kannst Du Dir sparen das HB zu schieben, da immer 0.
    Das entspräche dann dem hier:
    Code:
    !LDS   R18,   {ArrPtr}
    !DEC   R18   <--- weglassen bei Index 0-4
    !CLR   R19
    !LSL   R18
    !ADD   ZL,    R18
    !ADC   ZH,    R19
    !ST    Z+,    Reg(WordVal_LB)
    !ST    Z,     Reg(WordVal_HB)
    Würde Dir raten, Du holst Dir das AVR-Studio 4, dort kannst Du die von Bascom erzeugte .obj-Datei laden und Dir den disassemblierten Code ansehen. Indem Du Dir einfache Beispiele in Basic schreibst, kannst Du daraus lernen wie Bascom das umsetzt.

  7. #7
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    21
    Beiträge
    1.450
    Hallo,

    habe mir gerade das AVR-Studio 4 runtergeladen und mir den Disassemblierten Code angesehen.
    Code:
    1202:       Empf(channel) = Timer0
    
    +00001D0E:   E4A6        LDI       R26,0x46       Load immediate
    +00001D0F:   E0B0        LDI       R27,0x00       Load immediate
    +00001D10:   918C        LD        R24,X          Load indirect
    +00001D11:   E3AF        LDI       R26,0x3F       Load immediate
    +00001D12:   E0B3        LDI       R27,0x03       Load immediate
    +00001D13:   90AD        LD        R10,X+         Load indirect and postincrement
    +00001D14:   24BB        CLR       R11            Clear Register
    +00001D15:   E1A5        LDI       R26,0x15       Load immediate
    +00001D16:   E0B3        LDI       R27,0x03       Load immediate
    +00001D17:   0CAA        LSL       R10            Logical Shift Left
    +00001D18:   1CBB        ROL       R11            Rotate Left Through Carry
    +00001D19:   0DAA        ADD       R26,R10        Add without carry
    +00001D1A:   1DBB        ADC       R27,R11        Add with carry
    +00001D1B:   938D        ST        X+,R24         Store indirect and postincrement
    +00001D1C:   2788        CLR       R24            Clear Register
    +00001D1D:   938C        ST        X,R24          Store indirect
    Manches verstehe ich aber nicht. Warum wird z.b. R26 und R27 dreimal mit einem Wert beschrieben, wenn die Register nach den ersten beiden Malen gar nicht verwendet werden und wieder überschrieben werden? Außerdem wird R11 erst gelöscht und dann um 1 nach links geschoben. Was hat das für einen Sinn?
    Ich hoffe, ich stelle mich jetzt nicht zu blöd an und jemand ist bereit, mir das zu erklären?

    Gruß & Vielen Dank
    Ghris

  8. #8
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.820
    Denk dran', "X" und R26 / R27 ist das Gleiche !

    Um das Register R24 mit einem Wert aus einer SRAM -Variablen zu laden, muss man --> :
    Code:
      LDI    R26 , LOW (Variable)   
      LDI    R27 , HIGH (Variable)   
      LD     R24 , X                 X ==  Registerpaar XL /XH und das ist identisch mit  R26/R27
    AVR ASM hat drei solcher Pointer-Register
    X == XL/XH == R26/R27
    Y == YL/YH == R28/R29
    Z == ZL/ZH == R30/R31

    und für die gibt es die BEfehle
    LD reg , X
    LD reg , Y
    LD reg , Z
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  9. #9
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    01.10.2009
    Beiträge
    437
    Chris.
    Zitat Zitat von Che Guevara Beitrag anzeigen
    Außerdem wird R11 erst gelöscht und dann um 1 nach links geschoben. Was hat das für einen Sinn?
    XL & XH wurde Dir ja bereits von PicNick erklärt. Wobei mir allerdings der Nutzen im gezeigten Code nicht recht klar wird, denn wenn keine variable Adressierung notwendig ist, so verbraucht die Kombination
    Code:
    LDI   XL,   lbyte(Sram_Adress)
    LDI   XH,   hbyte(Sram_Adress)
    LD    Rxx,  X
    deutlich mehr Flash als ein simples
    Code:
    LDS   Rxx,   {Sram_Adress}
    Außerdem wird R11 erst gelöscht und dann um 1 nach links geschoben. Was hat das für einen Sinn?
    Das dient zum Übertrag des Carry-Flags, hier in's High-Byte des 16Bit Wertes, mache ich auch so im von mir geposteten Beispielcode, nur dort mit ADD/ADC.
    Du könntest keine Additionen oder Schiebeoperationen größer 8Bit ohne Carry durchführen.

    Hast Du eigentlich die Bascom-Kommentare aus dem AVR-Studio Listing gezielt entfernt, oder nur das falsche File geladen ?

  10. #10
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.820
    Bascom ist nicht der allergrösste Optimierer. Wenn die Zielvariable ("Empf") ein Word ist, verwendet Bascom eigentlich generell die
    LD XL, lbyte ( ..)
    LD XH, hbyte( ..)
    sequenz, auch wenn das im Einzelfall gar nicht notwendig wäre

    Btw: Wenn man Assembler schreibt, sollte man sich auch von der BAscom-od. "höhere-Sprache" Denkweise lösen. z.B
    Du füllst ja die "Empf" Tabelle strikt aufsteigend. Also ist das Verwenden eines Index überflüssige Arbeit für den µC.
    aber das ist jetzt vielleicht zuviel über-drüber für deine Fragestellung
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

+ Antworten
Seite 1 von 7 123 ... LetzteLetzte

Ähnliche Themen

  1. Inline Assembler
    Von Che Guevara im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 16
    Letzter Beitrag: 01.02.2010, 20:25
  2. AVR GCC inline Assembler
    Von chientech im Forum Assembler-Programmierung
    Antworten: 1
    Letzter Beitrag: 26.09.2009, 17:39
  3. Inline Assembler für Anfänger
    Von 1udo1 im Forum C - Programmierung (GCC u.a.)
    Antworten: 3
    Letzter Beitrag: 25.10.2007, 20:53
  4. Inline Assembler - Register
    Von s.o. im Forum C - Programmierung (GCC u.a.)
    Antworten: 5
    Letzter Beitrag: 02.08.2007, 21:26
  5. Parameterübergabe bei Inline-Assembler
    Von ogni42 im Forum C - Programmierung (GCC u.a.)
    Antworten: 21
    Letzter Beitrag: 30.03.2006, 14:32

Berechtigungen

  • Neue Themen erstellen: Ja
  • Themen beantworten: Ja
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •