Gnu AS似乎没有预处理#defines,但GCC确实如此

时间:2016-02-29 21:20:00

标签: gcc assembly c-preprocessor gas

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

我的情况示例如下:

我定义变量的头文件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

但是,在尝试编译时,链接器会报告以下错误:

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

显然正在尝试链接这些“符号” - 因此我得出结论,预处理器没有将符号替换为rmode_loc.h所指示的值。

我在另一篇SO帖子(无法找到链接)上看到,如果源文件的扩展名为.s,则不会进行任何预处理,并且建议定义__ASSEMBLER__还给出了 - 但是,这似乎不是问题,因为所有来源都有.S个扩展名,并且我在标题中添加了#define __ASSEMBLY__

但是,当使用GCC作为编译的前端,即gcc myprog.S -o myprog时,BSEQ标签被正确替换,并且所有内容都会编译。

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

1 个答案:

答案 0 :(得分:6)

GNU as本身从不处理#define指令。

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

如果要使用C预处理程序指令,可以命名文件as并使用.S命令,或者将它们命名为任意内容并手动执行两次传递:

gcc