Forum: Compiler & IDEs min()-/max()-Macro in AVR-AS


von Verzweifelter (Gast)


Lesenswert?

Hallo,

gibt es irgendwo Macros für den AVR-AS (GCC) um den größten, bzw. 
kleinsten Wert aus 2 Werten zu bestimmen (sowas wie max(3,4)=3)?
Alle Versuche meinerseits mit .macro .... .endm, a>b? a:b, defines und 
sonstwas schlagen fehl und ich finde keine Macrosammlung oder sowas im 
Netz ;-(
Problem ist, daß zur Übersetzungszeit eine Berechnung ausgeführt wird, 
die zwar 0 ergeben kann, aber nicht darf. Dafür brauch ich halt das 
max()

Grüße, Verzweifelter

P.S.: Gibt es irgendwo eine Macro-Sammlung oder sowas?

von Verzweifelter (Gast)


Lesenswert?

Shit. max(3,4) ist natürlich 4 ;-)

von Mathias (Gast)


Lesenswert?

So hab ich mir die Makros für Keil definiert:

#define MIN( a, b ) (a < b) ? a : b
#define MAX( a, b ) (a > b) ? a : b

Vielleicht hat es wegen deiner Klammernsetzung nicht funktioniert!?

Mfg, Mathias

von Karl H. (kbuchegg)


Lesenswert?

Apropos Klammernsetzung.

rechne mal

  2 + MIN( 3, 4 );
  MAX( 4, 3 ) + 2;

Ich denke nicht, dass 4, bzw. 5 die erwarteten Ergebnisse sind :-)


#define MIN( a, b ) ( ((a) < (b)) ? (a) : (b) )
#define MAX( a, b ) ( ((a) > (b)) ? (a) : (b) )

Sonst kann es zu unliebsamen Überraschungen kommen, wenn
man die Makros in Ausdrücken benutzt. Zumindest ein Teil
dieser Überraschungen lässt sich mit zusätzlichen Klammern
umgehen. Makroargumente bei der Verwendung in Klammern zu
setzen ist immer eine gute Idee.

Aber so wie ich den OP verstanden habe, braucht er das
für den Assembler und nicht für C.


von Verzweifelter (Gast)


Lesenswert?

Hallo,

> Aber so wie ich den OP verstanden habe, braucht er das
> für den Assembler und nicht für C.
Genauso ist es. Allergings hab ich den GCC den Assembler aufrufen 
lassen. Dachte bei einem .S-File wird der gleiche Preprozessor 
verwendet. Scheint aber nicht so ;-(
1
#define __SFR_OFFSET 0
2
#include <avr/io.h>
3
4
#define MAX(a, b) ( ((a) > (b)) ? (a) : (b) )
5
6
.func Test
7
    ldi     25, MAX(3, 4)
8
    ret
9
.endfunc

liefert z.B.:
Test.S: Assembler messages:
Test.S:7: Error: missing ')'
Test.S:7: Error: garbage at end of line

Wieso er allerdings ein fehlendes ')' bemängelt ist mir ein wenig 
schleierhaft.

Grüße, Verzweifelter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Verzweifelter wrote:

> Dachte bei einem .S-File wird der gleiche Preprozessor
> verwendet. Scheint aber nicht so ;-(

Doch, schon.

> Wieso er allerdings ein fehlendes ')' bemängelt ist mir ein wenig
> schleierhaft.

Weil der Assembler halt kein C-Compiler ist.  Den C-typischen
?:-Operator versteht er schlicht nicht, und der bleibt auch nach
deinem preprocessing noch da drin:
1
% avr-cpp foo.S
2
# 1 "foo.S"
3
# 1 "<built-in>"
4
# 1 "<command line>"
5
# 1 "foo.S"
6
7
# 1 "/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/io.h" 1 3
8
# 86 "/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/io.h" 3
9
# 1 "/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/sfr_defs.h" 1 3
10
# 87 "/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/io.h" 2 3
11
In file included from foo.S:2:
12
/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/io.h:332:6: warning: #warning "device type not defined"
13
# 336 "/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/io.h" 3
14
# 1 "/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/portpins.h" 1 3
15
# 337 "/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/io.h" 2 3
16
# 346 "/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/io.h" 3
17
# 1 "/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/version.h" 1 3
18
# 347 "/usr/local/lib/gcc/avr/4.1.1/../../../../avr/include/avr/io.h" 2 3
19
# 3 "foo.S" 2
20
21
22
23
.func Test
24
    ldi 25, ( ((3) > (4)) ? (3) : (4) )
25
    ret
26
.endfunc

von Verzweifelter (Gast)


Lesenswert?

> Weil der Assembler halt kein C-Compiler ist.  Den C-typischen
> ?:-Operator versteht er schlicht nicht, und der bleibt auch nach
> deinem preprocessing noch da drin:
Deswegen ja auch meine obigen Versuche mit .macro und #define.
Das '?' hatte ich mal versucht, aber aus Deinem genannten Grund 
ausgeschlossen. Ich wollte nur nochmal einen Versuch starten, weil
von den anderen Postern drauf verwiesen wurde.

Eine Mischung aus Macros und Defines schlägt leider fehl, da der 
Preprozessor innerhalb der Macrodefinition schon versucht die Defines 
aufzulösen ;-(
Peter Danegger hat mal sowas mit verschachtelten Macros hier gepostet 
(anderes Problem, aber trotzdem trotzdem trickreich den Preprozessor 
gelinkt g). Denke auf sowas wird es hinauslaufen.
Dachte halt es gibt da schon eine fertige Lösung ;-)

Grüße, Verzweifelter

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ich denke nicht, dass der C-Präprozessor das kann, was du hier von
ihm erwartest.

Wenn du den Befehl selbst mit als Makro-Argument übergeben kannst,
geht sowas:
1
#define __SFR_OFFSET 0
2
#include <avr/io.h>
3
4
.macro max a, b, instr
5
        .if \a > \b
6
        \instr  \a
7
        .else
8
        \instr  \b
9
        .endif
10
.endm
11
12
.func Test
13
    .global Test
14
Test:
15
    max 3 5 "ldi r25, "
16
    ret
17
.endfunc

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.