www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Warum kennt der Compiler das nicht (.set, .macro)


Autor: Oz zy (ozzy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

ich habe hier im Forum Code für schnelles Wurzelziehen in asm gefunden, 
und wollte den nun auch benutzen und einbinden. Also die .S-Datei 
runtergeladen, mit in mein Verzeichnis und bei AVR-Studio dem Projekt 
hinzugefügt. Dann kam aber schon die Fehler beim Kompilieren, z.B.

../sqrt.S:5: Error: expected comma after "useMOVW"
../sqrt.S:8: Error: expected comma after "useSpeedOptimized"
../sqrt.S:10: Error: expected comma after "saveRegs"
../sqrt.S:40: Error: unexpected end of file in macro `wurzel_shiftleft' 
definition

Hier der Code aus der Datei:
.set useMOVW = 1
.set useSpeedOptimized = 1
.set saveRegs = 0

.macro WURZEL_SHIFTLEFT
  //@0 @1 @2 @3 << 1
  lsl @3
  rol @2
  rol @1
  rol @0
.endmacro

Warum mag der Compiler denn so etwas nicht? In der Makefile steht die 
Datei richtig drin. Muss man denn noch irgendwo etwas konfigurieren / 
hinzufügen?

Vielen Dank für Eure Hilfe, MfG, Ozzy

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Syntax eines anderen Assemblers.  Du willst den GNU-Assembler benutzen,
der Code dürfte für den Atmel-AVR-Assembler geschrieben worden sein.

Probier mal:
.set useMOVW, 1
.set useSpeedOptimized, 1
.set saveRegs, 0

.macro WURZEL_SHIFTLEFT, a0, a1, a2
  //a0 a1 a2 a3 << 1
  lsl \a3
  rol \a2
  rol \a1
  rol \a0
.endm

Statt .set kann man im GNU-Assembler auch #define benutzen, da die
.S-Dateien vom Compiler zuvor noch durch den Präprozessor geschickt
werden.  Damit besitzt man eine zusätzliche Makro-Ebene oberhalb
des Assemblers.

Autor: Oz zy (ozzy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

habe es jetzt so umgeändert:
.MACRO WURZEL_SHIFTLEFT
  //@0 @1 @2 @3 << 1
  lsl @3
  rol @2
  rol @1
  rol @0
.ENDM
Jetzt gibt es da keine Fehlermeldungen mehr. Dafür aber bei z.B. diesem 
Aufruf:
WURZEL32_OUTERLOOP 15, (0x8000 >> 0)
der das Makro:
.MACRO WURZEL32_OUTERLOOP
    .if @0 == 0
      clr r19
      clr r18
      movw r17:r16, YH:YL
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      ori r16, 1
    .elif @0 == 1
      WURZEL_lshift0 (@1>>1)
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
    .elif @0 == 2
      WURZEL_lshift0 (@1>>1)
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
    .elif @0 == 3
      WURZEL_lshift0 (@1>>1)
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
    .elif @0 == 4
      WURZEL_lshift8 (@1>>1)
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
    .elif @0 == 5
      WURZEL_lshift8 (@1>>1)
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
    .elif @0 == 6
      WURZEL_lshift8 (@1>>1)
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
    .elif @0 == 7
      WURZEL_lshift8 (@1>>1)
    .elif @0 == 8
      WURZEL_lshift8 (@1>>1)
      WURZEL_SHIFTLEFT r19, r18, r17, r16
    .elif @0 == 9
      WURZEL_lshift8 (@1>>1)
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
    .elif @0 == 10
      WURZEL_lshift8 (@1>>1)
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
    .elif @0 == 11
      /*WURZEL_lshift8 (@1>>1)
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16
      WURZEL_SHIFTLEFT r19, r18, r17, r16*/
      WURZEL_lshift16 (@1>>1)
      WURZEL_RORRIGHT r19, r18, r17, r16
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
    .elif @0 == 12
      WURZEL_lshift16 (@1>>1)
      WURZEL_RORRIGHT r19, r18, r17, r16
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
    .elif @0 == 13
      WURZEL_lshift16 (@1>>1)
      WURZEL_RORRIGHT r19, r18, r17, r16
      WURZEL_SHIFTRIGHT r19, r18, r17, r16
    .elif @0 == 14
      WURZEL_lshift16 (@1>>1)
      WURZEL_RORRIGHT r19, r18, r17, r16
    .elif @0 == 15
      WURZEL_lshift16 (@1>>1)
    .else
      .error "ooops!!!"
    .endif
    cp r2, r16
    cpc r3, r17
    cpc r4, r18
    cpc r5, r19
    brlo wurzel32_2f_wd
      subi YL,  LOW(~@1+1)
      sbci YH, HIGH(~@1+1)
      sub r2, r16
      sbc r3, r17
      sbc r4, r18
      sbc r5, r19
  wurzel32_2f_wd:
  
.ENDM
und zwar die Fehlermeldung:
../sqrt.S:272: Error: too many positional arguments

Der Thread zu der Wurzelfunktion ist übrigens hier:
Beitrag "[ASM] (schnelle) Integer Wurzel 32bit"

Vielen Dank für Eure Hilfe, MfG, Ozzy

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum zum Geier[tm] änderst du es nicht so, wie ich es dir nahe gelegt
habe?

Wenn du mich ignorierst und ohnehin erst alles (offenbar ohne Benutzung
des Manuals) trial&error selbst machen willst, dann brauch' ich dir
ja auch nicht mehr zu schreiben...

Autor: Oz zy (ozzy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe es mittlerweile ja schon geändert (hatte Deinen Post vorher 
nicht gesehen).
Aber das ändert nicht viel, nur haben sich die Fehlermeldungen 
verändert:
../sqrt.S:165: Error: garbage at end of line

Das Makro mit passendem Aufruf funktioniert jetzt:
.MACRO WURZEL_SHIFTLEFT a3,a2,a1,a0
  //\a0 \a1 \a2 \a3 << 1
  lsl \a3
  rol \a2
  rol \a1
  rol \a0
.ENDM

WURZEL_SHIFTLEFT r16, r17, r18, r19

Nur noch bei der Fkt oben gibt es Probleme. Ich habe beim Makro die 
parameter mitgegeben:
.MACRO WURZEL32_OUTERLOOP a0, a1
und die @0 durch \a0, und die @1 durch \a1 geändert.
Jetzt bekomme ich zuerst ein "ooops!!!", da er wohl den ersten Parameter 
nicht erkennt.

Hast Du da noch eine Idee??

MfG und vielen Dank, Ozzy

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph O. wrote:

> ../sqrt.S:165: Error: garbage at end of line

Und welche Zeile ist das?

> Jetzt bekomme ich zuerst ein "ooops!!!", da er wohl den ersten Parameter
> nicht erkennt.

Ich denke nicht, dass man mit dem Parameterwert eines Makros eine
bedingte Assemblierung vornehmen lassen kann.  Wenn ich das hier:
.macro a a0 r
.if a0 == 1
        ldi     r\r, 1
.elif a0 == 2
        ldi     r\r, 2
.else
        ldi     r\r, 42
.endif
.endm

a 1 16
a 2 17
a 3 18

assemblieren lasse und wieder disassembliere, erhalte ich:

foo.o:     file format elf32-avr

Disassembly of section .text:

00000000 <.text>:
   0:   0a e2           ldi     r16, 0x2A       ; 42
   2:   1a e2           ldi     r17, 0x2A       ; 42
   4:   2a e2           ldi     r18, 0x2A       ; 42

Also auch nur jeweils die letzte Verzweigung.

Autor: Oz zy (ozzy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

also ich konnte den Fehler jetzt auf folgende Zeile(n) begrenzen:
subi YL,  LOW(~\a1+1)
, was ich von folgender Zeile geändert hatte:
subi YL,  LOW(~@1+1)

Noch eine Idee, wie man das in den Griff bekommt?

MfG, und vielen Dank für Deine Hilfe, Ozzy

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du denn irgendwo einen Makro namens LOW definiert?

Die Operatoren im avr-as heißen lo8() und hi8().

Autor: Oz zy (ozzy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

nein, habe ich nicht. Aber ich habe früher einiges in Assembler 
programmiert, und da z.B. auch Befehle wie
zeichenkette:    .db    "Set:[HH][MM][SS]";,NUL

ldi    ZL, LOW(zeichenkette<<1)
ldi    ZH, HIGH(zeichenkette<<1)
gehabt, und die Programme funktionierten immer. Programmiert hatte ich 
damals auch in AVR Studio auf dem ATmega32, dann allerdings eben keine 
C, sondern reine Assembler-Programme, daher auch meine jetzigen 
Probleme...

Aber vielen Dank für Deine Hilfe, die Fehler sind jetzt weg. Mit dem 
if/elif muss ich noch mal schauen, ich wundere mich nur, dass es bei dem 
Thread-Ersteller geklappt hat...

MfG, und vielen Dank noch einmal, Ozzy

Autor: Oz zy (ozzy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch eine kleine Frage: "BYTE" kennt er wohl auch nicht:
subi r17, BYTE1(~\a0+1)
sbci r18, BYTE2(~\a0+1)
sbci r19, BYTE3(~\a0+1)
Durch was ersetzt man das denn bei avr-as.

Und noch ganz wichtig: Kannst Du mir eine Quelle nennen, wo man so etwas 
auch nachlesen kann?

MfG, und wirklich vielen, vielen Dank, Ozzy

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph O. wrote:

> Aber vielen Dank für Deine Hilfe, die Fehler sind jetzt weg. Mit dem
> if/elif muss ich noch mal schauen, ich wundere mich nur, dass es bei dem
> Thread-Ersteller geklappt hat...

Offenbar verhält sich der Atmel-AVR-Assembler da einfach mal anders
als der GNU-Assembler.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph O. wrote:

> Durch was ersetzt man das denn bei avr-as.

Ich kann nur raten, was diese Operatoren beim Atmel-Assembler machen.
Demnach wären sie wohl äquivalent zu hi8(), hlo8() und hhi8().

Allerdings frage ich mich gerade, wie man den gas dazu überredet, den
Ausdruck nicht als vom Typ int, sondern als long int zu berechnen,
sodass die Benutzung von hlo8() und hhi8() überhaupt Sinn hat.

> Und noch ganz wichtig: Kannst Du mir eine Quelle nennen, wo man so etwas
> auch nachlesen kann?

Der GNU-Assembler kommt mit sogenannten info-Dateien daher, da sind die
Pseudo-Ops (einschließlich Makros etc.) erklärt.  Bei mir tippe ich
dafür einfach "info as" ein.  Ich glaube, WinAVR bringt die zugehörige
Doku auch irgendwo mit.

Die AVR-spezifischen Pseudo-Ops sind außerdem hier erklärt:

http://www.nongnu.org/avr-libc/user-manual/assembl...

Leider fehlt dort noch die Erklärung für hlo8() und hhi8(), die erst
später dazu gekommen sind.

Autor: Oz zy (ozzy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Jörg,

vielen Dank für Deine ganze Hilfe, jetzt kompiliert er wenigstens 
fehlerfrei, mal sehen, was er daraus so macht...

Übrigens funktioniert das mit der bedingten Assemblierung doch:
.macro a a0 r
.if \a0 == 1
        ldi     r\r, 1
.elseif \a0 == 2
        ldi     r\r, 2
.else
        ldi     r\r, 42
.endif
.endm

a 1 16
a 2 17
a 3 18
 27c:  01 e0         ldi  r16, 0x01  ; 1
 27e:  12 e0         ldi  r17, 0x02  ; 2
 280:  2a e2         ldi  r18, 0x2A  ; 42


Vielen Dank noch einmal, MfG, Ozzy

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph O. wrote:

> Übrigens funktioniert das mit der bedingten Assemblierung doch:

OK, pilot error.  Gut zu wissen, danke!

Autor: Oz zy (ozzy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kein Problem. Das einzige, was leider noch nicht funktioniert: Der 
Sprung, da er immer sagt, dass er die Marke schon kennt. Klar, wenn er 
sie immer wieder einfügen möchte... Hast Du da eine Idee???
brlo wurzel32_2f_wd
  subi YL, lo8(~\a1+1)
  sbci YH, hi8(~\a1+1)
  sub r2, r16
  sbc r3, r17
  sbc r4, r18
  sbc r5, r19
wurzel32_2f_wd:

MfG, Ozzy

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christoph O. wrote:

> Kein Problem. Das einzige, was leider noch nicht funktioniert: Der
> Sprung, da er immer sagt, dass er die Marke schon kennt. Klar, wenn er
> sie immer wieder einfügen möchte... Hast Du da eine Idee???

Klar, local labels benutzen:
  brlo 1f
  subi YL, lo8(~\a1+1)
  sbci YH, hi8(~\a1+1)
  sub r2, r16
  sbc r3, r17
  sbc r4, r18
  sbc r5, r19
1:

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.