- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Ergebnis 1 bis 10 von 65

Thema: Bascom Inline-Assembler

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    08.09.2007
    Ort
    Berlin
    Alter
    31
    Beiträge
    1.578

    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.842
    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
    31
    Beiträge
    1.578
    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.

Ä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: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

LiFePO4 Speicher Test