>我有潜在的大量常量,这些常量被越来越多的源文件使用。我需要能够利用它的值,以便在一个地方定义它很方便。
我的情况示例如下:
我定义变量的头文件 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
编译汇编代码时是否有任何显着的技术差异?
GNU as
本身从不处理#define
指令。
gcc
命令的一个特殊功能是,当给定一个以 .S
结尾的文件名时,它会在其上运行 C 预处理器cpp
(处理#define
和#include
等),然后在生成的输出上运行as
。 但是当给定一个以 .s
结尾的文件名时,它只是运行as
。
如果要使用 C 预处理器指令,可以.S
命名文件并使用 gcc
命令,也可以随意命名它们并手动执行这两个过程:
cpp foo.s |as -o foo.o -