2012-10-07 7 views
7

Meine Toolchain ist eine aktuelle Version von Arm-GCC.gnu Arm Assembler-Befehlszeile Makro schlägt mit "Ungültige Kennung für .ifdef"

Ich habe ein Stück Code in einer Montagedatei, die bedingt enthalten/montiert werden muss.

.ifdef MACRO_FROM_CMDLINE 
Assembly instr1 
Assembly instr2 
.endif 

Gekapselter Code ist ein neuer Zusatz.

Ich habe beide versucht:

gcc -x assembler-with-cpp --defsym MACRO_FROM_CMDLINE=1 <along with other necessary options> 

gcc -x assembler-with-cpp -D MACRO_FROM_CMDLINE=1 <along with other necessary options> 

Die -D Ergebnisse in "Ungültige Kennung für .ifdef" und ".endif ohne .IF" Fehler.

Die --defsym Ergebnisse in "MACRO_FROM_CMDLINE = 1: keine solche Datei oder Verzeichnis", "nicht erkannte Option --defsym" Fehler.

Antwort

11

Die gcc Binärdatei steuert den Kompilierungsprozess, indem sie eine Reihe anderer Programme nacheinander aufruft, um die verschiedenen Arbeitsschritte (Kompilieren, Assemblieren, Verknüpfen) tatsächlich auszuführen.

Wenn Sie sagen:

gcc -x assembler-with-cpp -D MACRO_FROM_CMDLINE=1 ... 

Sie es fordern von der Quelle durch den C-Präprozessor laufen, und dann das Ergebnis durch den Monteur ausgeführt werden.

Der Präprozessor Schritt C schaltet:

.ifdef MACRO_FROM_CMDLINE 

in:

.ifdef 1 

bevor es dem Assembler, vorbei, die dann nicht Sinn davon machen kann. Aus diesem Grund erhalten Sie den Fehler "ungültiger Bezeichner". Es erklärt auch, warum die Verwendung von C-Preprozessor #ifdef das Problem behebt.


--defsym nicht funktioniert, weil es den Monteur eine Option, nicht das gcc Treiberprogramm. (Der gcc Fahrer versteht und durch einige Optionen einige der Programme aufruft, aber nicht alle.)

Sie können jedoch passieren beliebige Optionen bis zum Assembler mit dem

Syntax, die den gcc Treiber anweist, diese Optionen an den Assembler zu übergeben (als eine Liste von durch Leerzeichen getrennten Optionen).

Zum Beispiel:

gcc -x assembler-with-cpp -Wa,--defsym,MACRO_FROM_CMDLINE=1 ... 

fügt

--defsym MACRO_FROM_CMDLINE=1 

in die Liste der Optionen zu übergeben, wenn asgcc sie aufruft, und das ist, wie Sie Ihre ursprüngliche .ifdef Beispiel Arbeit zu machen.


Sie können die einzelnen Programme von gcc aufgerufen sehen, und die Optionen, es tatsächlich zu ihnen geht, durch Hinzufügen der -v Option.

In diesem Fall sollten Sie etwas namens cc1 (die tatsächliche GCC C Compiler binär) aufgerufen mit dem -E Flag (Vorprozess nur) zur Vorverarbeitung der Eingabe in eine temporäre Datei, und dann as aufgerufen auf die temporäre Datei sehen zu montieren es.

+0

Ich bestätige, dass die -Wa, die oben von Mat beschriebenen Optionen recht gut funktionieren. – Raj

1

Seltsam, aber es stellt sich heraus, ich musste die C-Syntax in der Assembly-Datei verwenden.

#ifdef MACRO 
    Assembly Instruction 
    Assembly Instruction 
#endif 

Und das Makro musste mit der Option -D übergeben werden.

+0

GAS unterstützt beide afaik, warum rufen Sie GAS nicht direkt auf, anstatt gcc auf Ihren Assembly-Dateien zu durchlaufen? – sgupta

+0

Die Verwendung von gcc (und nicht von GNU als direkt) hat den Vorteil, dass der Linker nach der Kompilierung aufgerufen wird, während die Verwendung als direkt den zusätzlichen Schritt der anschließenden Verknüpfung mit ld erfordert. Sooo ... nur 10 Sekunden Zeit sparen? – adam

+0

@sgupta: Die Verwendung von CPP ist hier die beste Wahl und "direkt" nicht * vorverarbeitet. (Aber '#' ist das Kommentarzeichen für x86, also könnte die Datei noch zusammengesetzt werden!) '' 'Direkt zu verwenden, ist ein schlechter Rat. Benennen Sie Ihre Datei 'foo.S' und bauen Sie sie mit' gcc' + beliebigen gcc-Optionen, z. '-m32',' -c'. –