我有大量的常量,这些常量被越来越多的源文件使用。我需要能够使用它的值,所以在一个地方定义它很方便。
我的情况示例如下:
我定义变量的头文件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
?
答案 0 :(得分:6)
GNU as
本身从不处理#define
指令。
gcc
命令的一个特殊功能是,当给定一个以.S
结尾的文件名时,它会在其上运行C预处理器cpp
(处理#define
和{ {1}}等等,然后在结果输出上运行#include
。但是当给出以as
结尾的文件名时,它只会运行.s
。
如果要使用C预处理程序指令,可以命名文件as
并使用.S
命令,或者将它们命名为任意内容并手动执行两次传递:
gcc