Forum: Compiler & IDEs ARM Assembler-Frage


von Volker T. (funker211)


Lesenswert?

Hallo,

ich möchte mit in meinem Startup-Script für einen ARM-Prozesseor 
Registerdefinitionen anlegen und später als Konstante nutzen:

> IO0DIR = 0xE0028008   // GPIO 0 Direction Control Register
>
> ...
>
>
> ldr r0, =IODIR        // Load address of IODIR register into r0
> ldr  r1, =0x00002000   // Load bit pattern into r1
> str r1, [r0]          // Store bit pattern at address referenced in r0
>

So, wie ich mir das vostelle, scheint's nicht zu gehen (Fehlermeldung: 
src/crt.s:211: undefined reference to `IODIR'). Wie dann dann?

Ich nutze arm-elf-gcc als Assembler (der ruft natürlich dann arm-elf-as 
auf).

von PS (Gast)


Lesenswert?

Das geht mit

    .set SYMBOL, EXPRESSION

Du kannst die Registerdefinitionen aber auch im
Linker-Script anlegen, z.B.:

PROVIDE( MEMMAP = 0xE01FC040 );  /* Memory mapping control */


von A.K. (Gast)


Lesenswert?

Das geht auch, wenn man den C-Präprozessor vor dem Assembler verwendet 
(üblicherweise signalisiert mit file.S statt file.s als Quelltext), so 
dass sich in C und Assembler die gleichen Definitionsdateien nutzen 
lassen.

von Volker T. (funker211)


Lesenswert?

Muchas Gracias!

Irgendwo im Manual meine ich gelesen zu haben, das sei äquivalent zu

SYMBOL = EXPRESSION

aber mit .set SYMBOL, EXPRESSION funktioniert es.

Ich habe generell das Problem, an Informationen zu gelangen, die für 
mich relevant sind. Derzeit suche ich mir alles aus einem Mix von as, 
gcc, ld und dem ARM ADS1.2 User Manual zusammen. Leider ist die 
Assemblersyntax zwischen den ARM Tools und GNU Tools wohl nicht ganz 
identisch.

U.a. kann ich in meinem Assemblerfile als Kommentare /* comment */ wie 
auch // line comment nutzen, aber nicht @ line comment, wie im Manual 
beschrieben. ADS wiederum würde ; nutzen...

Naja, aller Anfang ist eben schwer, das ist der Preis der freien 
Software. Keine Lizenzkosten, dafür hoher Zeitaufwand...

Kennt jemand also ein Dokument, das speziell für arm-elf-as gut geeignet 
wäre?

von Volker T. (funker211)


Lesenswert?

Noch eine Follow-Up-Frage zum Präprozessor. In meinem C-Header-File habe 
ich Register üblicherweise so definiert:

.set VICIRQSTATUS  (*(volatile unsigned long *) 0xFFFFF000UL)

Das erlaubt mir im C-Code die Verwendung von

VICIRQSTATUS = 0x7637;

um ins Register zu schreiben.

Im Assembler Code bräuchte ich ja etwas wie

.set VICIRQSTATUS, 0xFFFFF000

Ich nehme an, mein *(volatile unsigned long *)-Konstrukt sollte aber 
kein Problem darstellen?

Ich habe meinen Startup-Code nun auch umbenannt, aber die im Header-File 
definierten Symbole werden noch nicht eingebunden. Muss ich im 
Assemblerfile auch eine Art "include" vornehmen, oder soll der Assembler 
automatisch nach allen verfügbaren Symbolen im Include-Pfad suchen?

von A.K. (Gast)


Lesenswert?

Wie wär's mit
  #ifdef ...C,wassweichichwiesichdieunterscheiden-dokulesen...
    #define IOLONG(x) (*(volatile unsigned long *)(x))
  #else // assembler
    #define IOLONG(x) (x)
  #endif

Und dann:
#define VICIRQSTATUS IOLONG(0xFFFFF000)

> In meinem C-Header-File habe ich Register üblicherweise so definiert:
> .set VICIRQSTATUS  (*(volatile unsigned long *) 0xFFFFF000UL)

Ähm. Das funktioniert in C??


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


Lesenswert?

Funker 211 wrote:

> U.a. kann ich in meinem Assemblerfile als Kommentare /* comment */
> wie auch // line comment nutzen,

Das hängt damit zusammen, dass der Unix-typische Weg (den die
GNU-Tools beschreiten) ist, dass man Assemblerquellen zuvor noch durch
den C-Präprozessor zieht (Dateinamenssuffix .S).  Dieser wiederum
entfernt alle C-Kommentare.

> aber nicht @ line comment, wie im Manual
> beschrieben. ADS wiederum würde ; nutzen...

Der GNU-Assembler hat dann noch ein eigenes Kommentarzeichen,
normalerweise ist es ;, aber das Backend kann das für sich festlegen.
Außerdem gibt es "comment chars" und "line comment chars", letztere
werden bei AVR auf # gesetzt (d. h. eine Zeile, die ganz vorn ein #
hat, ist eine Kommentarzeile -- das ist nützlich, da der Präprozessor
solche Zeilen ja selbst generiert).

Habe gerade mal im tc-arm.c geguckt, da ist comment_chars auf "@"
gesetzt, und ";" wird für line_separator_chars benutzt, d.h. damit
kann man mehrere logische Zeilen innerhalb einer physischen trennen.

Ansonsten benutzt der GNU-Assembler als Unix-Assembler halt die
Unix-typischen pseudo ops, diese aber dafür komplett unabhängig vom
Zielprozessor.  Da in den Assemblern der einzelnen Hersteller jeder
sein eigenes Süppchen mit den pseudo ops kocht, unterscheiden sich
diese also in der Regel von der Herstellersyntax.

> Kennt jemand also ein Dokument, das speziell für arm-elf-as gut
> geeignet wäre?

So schlecht ist doch das gas-Manual gar nicht, was fehlt dir denn?  Im
Gegensatz zu den AVR-Spezifika sind die ARM-Spezifika sogar weitgehend
dokumentiert.  (An zwei Stellen sehe ich noch ein "TODO".)

> Noch eine Follow-Up-Frage zum Präprozessor. In meinem C-Header-File
> habe ich Register üblicherweise so definiert:

> .set VICIRQSTATUS  (*(volatile unsigned long *) 0xFFFFF000UL)

Du meinst sicher eher

#define VICIRQSTATUS  (*(volatile unsigned long *) 0xFFFFF000UL)

> Im Assembler Code bräuchte ich ja etwas wie

> .set VICIRQSTATUS, 0xFFFFF000

Naja, das #define kann man dort auch nehmen, aber es sollte nicht mehr
zu einem Typecast evaluieren...  Die Headers in der avr-libc machen
dafür paar Klimmzüge, die kannst du dir mal angucken.  Da kommen dann
für die Dinge, die im C-Modus in ähnlichen Konstrukten mit Typecast
und Zeigern enden, im Assemblermodus einfache Zahlen heraus.

von Volker T. (funker211)


Lesenswert?

Jörg, danke für Deine Antworten.

Ja, ich meinte #define (*(volatile ..., da bin ich jetzt beim Schreiben 
durcheinandergekommen.

Bezüglich der Kommentare habe ich das jetzt glaube ich verstanden. Bei 
mir wird ja auch das Assemblerfile durch arm-elf-gcc gezogen und nicht 
direkt mit arm-elf-as assembliert - damit wird wohl (nach meinem 
jetzigen Verständnis) dann sogar ein *.s-File durch den Präprozessor 
gejagt, weil ich hier ja explizit arm-elf-gcc nutze!? Jedenfalls werden 
meine C-Style-Kommentare entfernt, egal ob meine Datei crt.S oder crt.s 
heisst.

Das as-Manual ist schon gut, ich habe nur ein Problem mit dem Mix aus 
Dokumenten, die ich durchlesen muss. Mir fehlt halt noch der Überblick, 
was welches Tool genau mit meinem Assemblerfile treibt und welche Syntax 
ich dann verwenden darf.

Was ich jetzt noch nicht blicke, ist, wie genau ich mein Headerfile zum 
Assembler einbinde.

Mein Startup-Code heisst nun crt.S und liegt in ./src , meine 
Headerdatei heisst lpc2129.h und liegt in ./inc. In crt.S will ich jetzt 
also auf Definitionen aus dem Headerfile zugreifen. Ich gehe mal davon 
aus, dass ein .include hier der falsche Weg wäre, denn dann wird wohl 
ein Assemblerfile erwartet (so scheint es sich zu hier verhalten, denn 
es kommen dann entsprechende Fehlermeldungen).

Genügt es dann, das verwendete Symbol mit ".extern" zu deklarieren und 
einfach ./inc in den Includepfad für as aufzunehmen? (Probiere es mal 
aus).

73
DG4SGA

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


Lesenswert?

Du nimmst dafür ein #include und setzt auf der Kommandozeile die
-I-Optionen so, dass ./inc mit in den Suchpfad aufgenommen wird.
Dann hast du kein Assemblersymbol, sondern einen Präprozessormakro,
den schreibst du einfach so hin, und der Präprozessor ersetzt ihn
durch den entsprechenden Text.

von Volker T. (funker211)


Lesenswert?

Okay, vielen Dank!

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.