Forum: Mikrocontroller und Digitale Elektronik C Makros in Assembler


von Walter T. (nicolas)


Lesenswert?

Hallo zusammen,

ich bin noch bei meinen ersten Gehversuchen mit Assembler und frage 
mich, ob es möglich ist, Makro-Definitionen in C-Headern in 
Assembler-Dateien zu nutzen.

Wenn es nicht so geht, werde ich wohl einen Umweg suchen müssen.

Was ich schon gefunden habe: Generell können C-Header-Dateien mit 
.include eingebunden werden, wenn diese nur #defines enthalten. Gut.

Ich habe jetzt eine Header-Datei, die nur Pin-Definitionen enthält, z.B.
1
    // config.h
2
    #define TST0_PIN PA0
3
    #define TST1_PIN PA1

Unter C nutze ich die so:
Es gibt eine weitere Header-Datei, in der die Pin-Bezeichnungen 
zugewiesen werden:
1
    // pins.h
2
    #define PA0  GPIOA, GPIO_Pin_0
3
    #define PA1  GPIOA, GPIO_Pin_1
4
    ...
5
  
6
    /** Hilfs-Makro: Erstes Argument */
7
    #define _arg1(a,b) a
8
    
9
    /** Hilfs-Makro: Zweites Argument */
10
    #define _arg2(a,b) b
11
    
12
    
13
    /** Aus Makros wie PB0: GPIOB, GPIO_Pin_0 wieder GPIOB zurueckgewinnen
14
     * (Makro-Version der Funktione gpio_port() ) */
15
    #define GPIO_PORT(ab)   _arg1(ab)
16
    
17
    /** Aus Makros wie PB0: GPIOB, GPIO_Pin_0 wieder GPIO_Pin_0 zurueckgewinnen
18
     * (Makro-Version der Funktione gpio_pin() ) */
19
    #define GPIO_PIN(ab)    _arg2(ab)

Und in meiner C-Datei nutze ich das entsprechend:
1
  GPIO_t GPIOx = GPIO_PORT(TST0_PIN);
2
  GPIOx->BSRR = GPIO_PIN(TST_PIN);
und die Welt ist einfach.

Wie schön wäre es doch, wenn ich die Config-Datei weiternutzen könnte.

Also:
1
.syntax unified
2
.cpu cortex-m3
3
.thumb
4
5
@ hw_config.h laesst sich importieren, weil sie nur aus MAKRO-Definitionen besteht.
6
.include "hw_config.h"
7
8
@ sollte auch noch gehen
9
#define PA8  GPIOA, GPIO_Pin_8
10
11
12
GPIOA = 0x40010800
13
GPIO_Pin_0 = 1<<0
14
15
.macro GPIO_PORT port pin
16
  \port
17
.endm
18
19
.macro GPIO_PIN port pin
20
  \pin
21
.endm
22
23
.text
24
.type asmtestfcn, %function
25
.global asmtestfcn
26
asmtestfcn:
27
    ldr r0, =GPIO_PORT( GPIOA, GPIO_Pin_0 )
28
    ldr r1, =GPIO_PIN( GPIOA, GPIO_Pin_0 )
29
    str r1, [r0, #GPIOx_BSRR]
30
    bx lr
Der Assembler wirft mir vor: "Error: garbage following instruction -- 
`ldr r0,=GPIO_PORT(GPIOA,GPIO_Pin_0)'"
und ich kann dem noch nicht einmal widersprechen.

Kann mir jemand einen Anstoß geben, wie ich mein Vorhaben umsetzen kann?

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


Lesenswert?

Der GCC (den benutzt du wohl) schickt alle .S-Dateien (also solche, die 
auf der Kommandozeile ein großes "S" als Suffix haben) standardmäßig 
über den C-Präprozessor und erst danach zum Assembler.

Da brauchst du auch kein .include, sondern kannst ganz normal mit 
#include arbeiten.

Die Header selbst können ggf. Dinge, die ein Assembler nicht verstehen 
kann (bspw. C-structs) via
1
#ifndef __ASSEMBLER__
2
...
3
#endif

vor dem Assembler schützen.

Damit kannst du auf die ganz normalen C-Makros zugreifen in der von C 
gewohnten Weise.

Assembler-Makros wiederum sind eine völlig andere Baustelle.

von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Jörg W. schrieb:
> Damit kannst du auf die ganz normalen C-Makros zugreifen in der von C
> gewohnten Weise.

Das ist ja famos! Vielen Dank, damit hast Du mir sehr weitergeholfen.


Nachtrag: Gibt es einen Mechanismus, mit dem das Auslassen per #ifndef 
_ASSEMBLER_ schiefgehen kann?
Ich bekomme bei der Header-Datei im Anfang immer die Fehlermeldung "bad 
instruction" oder "junk at ..." für jede einzelne Zeile innerhalb des 
#ifndef(_ASSEMBLER_)-Blocks.

von A. S. (Gast)


Lesenswert?

Walter T. schrieb:
> innerhalb des
> #ifndef(ASSEMBLER)-Blocks.

Leerzeichen nach #ifndef ?

von Walter T. (nicolas)


Lesenswert?

Habe es gefunden. Die "io.h", die unauffällig oben includiert wird, 
enthält Funktionen, die nicht Assembler-tauglich sind.

Und die Header müssen mit #include und nicht .include eingeladen 
werden.

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


Lesenswert?

Nur noch als Tipp: arm-none-eabi-gcc -E (plus die nötigen -D und -I 
Optionen) gibt dir das präprozessierte Ergebnis auf stdout aus. Da kann 
man sich dann angucken, was (in diesem Falle) dem Assembler vorgesetzt 
wird.

von Walter T. (nicolas)


Lesenswert?

Jörg W. schrieb:
> Nur noch als Tipp: arm-none-eabi-gcc -E (plus die nötigen -D und -I
> Optionen) gibt dir das präprozessierte Ergebnis auf stdout aus.

Danke für die Erinnerung. Das nutzt man irgendwie zu selten.

Für die Assembler-Makros scheint es das nicht zu geben. (?) Da bleibt 
einem wohl nur, sich das Dissassembly anzuschauen.

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


Lesenswert?

Walter T. schrieb:
> Für die Assembler-Makros scheint es das nicht zu geben.

Schau mal ins Handbuch, es müsste im Assembler auch eine Option für ein 
klassisches Assemblerlisting geben.

Assembleroptionen kannst du auf der Compiler-Kommandozeile mit -Wa 
präfixen.

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.