Gcc gnu arm汇编程序命令行宏失败,返回“0”;.ifdef“的标识符无效;

Gcc gnu arm汇编程序命令行宏失败,返回“0”;.ifdef“的标识符无效;,gcc,assembly,gnu-assembler,Gcc,Assembly,Gnu Assembler,我的工具链是arm gcc的最新版本 我在汇编文件中有一段代码,必须有条件地包含/汇编 .ifdef MACRO_FROM_CMDLINE Assembly instr1 Assembly instr2 .endif 封装代码是最近添加的 我试过两种方法: gcc -x assembler-with-cpp --defsym MACRO_FROM_CMDLINE=1 <along with other necessary options> gcc -x assembler-

我的工具链是arm gcc的最新版本

我在汇编文件中有一段代码,必须有条件地包含/汇编

.ifdef MACRO_FROM_CMDLINE
 Assembly instr1
 Assembly instr2
.endif
封装代码是最近添加的

我试过两种方法:

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>   
gcc-x汇编程序,带有cpp--defsym MACRO\u FROM\u CMDLINE=1
gcc-x汇编程序,带有来自\u CMDLINE=1的cpp-D宏\u
-D
导致“.ifdef的标识符无效”和“.endif无.if”错误


--defsym
导致“MACRO\u FROM\u CMDLINE=1:没有这样的文件或目录”,“无法识别的选项--defsym”错误。

奇怪,但事实证明我需要在程序集文件中使用C语法

#ifdef MACRO
  Assembly Instruction
  Assembly Instruction
#endif

宏必须使用-D选项传递。

gcc二进制文件通过依次调用许多其他程序来驱动编译过程,以实际执行各个阶段的工作(编译、组装、链接)

当你说:

gcc -x assembler-with-cpp -D MACRO_FROM_CMDLINE=1 ...
您要求它通过C预处理器运行源代码,然后通过汇编程序运行结果

C预处理器步骤将转到:

.ifdef MACRO_FROM_CMDLINE
进入:

在将其传递给汇编程序之前,汇编程序无法理解它。这就是为什么会出现“无效标识符”错误。它还解释了为什么使用C预处理器
#ifdef
可以解决这个问题


--defsym
不起作用,因为它是汇编程序的一个选项,而不是
gcc
驱动程序。(gcc驱动程序确实理解并将一些选项传递给它调用的一些程序,但不是全部。)

但是,您可以使用

-Wa,option[,option...]
语法,它告诉
gcc
驱动程序将这些选项传递给汇编程序(作为空格分隔的选项列表)

例如:

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

gcc
调用它时,作为
传递给
的选项列表,这就是如何使原始
.ifdef
示例工作的方法


通过添加
-v
选项,您可以看到由
gcc
调用的各个程序,以及它实际传递给它们的选项


在这种情况下,您应该看到一个名为
cc1
(实际的GCC C编译器二进制)的东西,它使用
-E
标志(仅限预处理)调用,以预处理临时文件的输入,然后在临时文件上调用
作为对其进行组装。

GAS支持afaik和,为什么不直接调用GAS,而不是在程序集文件上通过gcc?使用gcc(而不是像GNU那样直接)有在编译后调用链接器的好处,而直接使用as,则需要在编译后使用ld执行额外的链接步骤。所以。。。仅仅节省10秒的时间?@sgupta:在这里使用CPP是最好的选择,而且
as
直接不进行预处理。(但是,
#
是x86的注释字符,因此该文件可能仍然会被汇编!)直接使用
作为
是错误的建议。将您的文件命名为
foo.S
,并使用
gcc
+任何gcc选项构建它,例如
-m32
-c
。我确认上面Mat描述的-Wa选项运行良好。
gcc -x assembler-with-cpp -Wa,--defsym,MACRO_FROM_CMDLINE=1 ...
--defsym MACRO_FROM_CMDLINE=1