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).
Das geht mit .set SYMBOL, EXPRESSION Du kannst die Registerdefinitionen aber auch im Linker-Script anlegen, z.B.: PROVIDE( MEMMAP = 0xE01FC040 ); /* Memory mapping control */
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.
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?
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?
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??
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.
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.