为什么这里需要C宏中的“##”以及预处理MIPS汇编中的分号是什么意思?

时间:2018-03-13 13:54:24

标签: assembly mips preprocessor

我最近正在阅读基于MIPSfpga的嵌入式系统上运行的小型操作系统的MIPS程序集。

我有两个文件,boot.Sboot.h。我使用命令mips-sde-elf-gcc -c -o boot.o boot.S进行编译,以便它通过C预处理器cpp

在文件boot.h中,它定义了一个宏:

#define LEAF(name)\
    .##text;\
    .##globl    name;\
    .##ent  name;\
name:

##的含义是什么?我在info cpp上找到它导航到Macros然后导航到Concatenation,这称为“令牌粘贴或令牌连接”。但是为什么我们需要在这种情况下连接令牌呢?您看,boot.S将通过cpp,然后as。但是as也有一个内置的令牌解析器,所以我认为这里不需要这种令牌粘贴,因为as会将它解析为单个符号,而不是两个单独的符号。输出cppcpp不需要费心去粘贴它。

然后,我使用命令gcc -E boot.S > boot.i来查看预处理后得到的内容。在boot.S中,宏LEAF(__reset_vector)扩展为以下内容:

.text; .globl __reset_vector; .ent __reset_vector;__reset_vector:

预处理的指令在同一行。但;是什么意思? info as中没有记录。

3 个答案:

答案 0 :(得分:2)

  

##是什么意思?

从上一个和下一个中创建一个令牌,将它们粘贴在一起。这里的目的可能是为了防止预处理器在.和以下标识符之间插入额外的空格,因为CPP不会使用标识符解析.

  

;是什么意思?

在大多数体系结构的GAS语法中,它是一个语句分隔符。汇编语句通常由换行符分隔,但cpp的宏不能轻易生成多行输出,因此需要另一个分隔符。

在其他一些汇编语法中(如NASM或MASM),;是注释字符。

(根据您的补充更新。)

答案 1 :(得分:1)

我仔细阅读了info as。事实证明,GNU as定义的“评论和陈述”是针对具体目标的。不同的汇编语言可能具有不同的注释和语句语法,以及行分隔符。所以我需要深入研究MIPS语法。

答案 2 :(得分:1)

据我所知,除非##text或{{1},否则globl CPP运算符且无效} {是ent d为宏。

#define

CPP输出:#define LEAF(name)\ .##text;\ .##globl name;\ .##ent name;\ name: LEAF(myname)

.text; .globl myname; .ent myname;myname:

CPP输出:#define LEAF2(name)\ .text;\ .globl name;\ .ent name;\ name: LEAF2(myname)

输出与.text; .globl myname; .ent myname;myname:令牌粘贴相同或不相同。

##是此asm语法中的语句分隔符(如换行符),因此此宏切换到;部分,并声明一个以宏arg作为名称的全局符号。那里还有一个.text指令,我不知道它的作用。