Gnu AS 似乎不预处理#defines,但 GCC 会

Gnu AS doesn't seem to preprocess #defines, but GCC does

我可能有大量常量被越来越多的源文件使用。我需要能够玩弄它的价值,所以把它定义在一个地方很方便。

我的情况举例如下:

我定义变量的 header 文件,rmode_loc.h:

#define __ASSEMBLER__

#define BSEQ_HI 0xF000
#define BSEQ_LO 0x0000

(应该)使用它们的一些代码的摘录,myprog.S:

.code16

/* Include constants */
#include "rmode_loc.h"

_start:

    ...

    push    $BSEQ_HI

    ...

    mov $BSEQ_LO, %bx

然而,在尝试编译时,linker 报告了以下错误:

myprog.o: In function `_start':
(.text+0x1b): undefined reference to `BSEQ_HI'
myprog.o: In function `_start':
(.text+0x1f): undefined reference to `BSEQ_LO'

显然正在尝试 link 来对抗这些 'symbols' - 因此我得出结论,预处理器没有将符号替换为 rmode_loc.h 指示的值。

我在另一个 SO post(找不到 link)上读到,其中提到如果源文件的扩展名是 .s,则不会进行任何预处理,并且还给出了定义 __ASSEMBLER__ 的建议 - 但是,这似乎不是这里的问题,因为所有来源都有 .S 扩展名,我在 [=45] 中添加了 #define __ASSEMBLY__ =].

但是,当使用 GCC 作为编译前端时,即 gcc myprog.S -o myprogBSEQ 标签被正确替换,一切都可以编译。

我的问题是,当使用 as 而不是 gcc 来产生这些结果时,预处理有什么不同,使用 gcc 编译时是否有任何重大的技术差异汇编代码而不是 as?

GNU as 自己从不 处理#define 指令。

gcc 命令的一个特殊功能是,当给定一个以 .S 结尾的文件名时,它会在其上运行 C 预处理器 cpp(它处理 #define#include 等等),然后在结果输出上运行 as。但是当给定以 .s 结尾的文件名时,它只会运行 as.

如果您想使用 C 预处理器指令,您可以将文件命名为 .S 并使用 gcc 命令,或者将它们命名为任何您想要的名称并手动执行两次:

cpp foo.s |as -o foo.o -