Han XIAO
Han XIAO

Reputation: 1248

Why is "##" in C macro needed here and what does semicolon in preprocessed MIPS assembly means?

I am recently reading the MIPS assembly for a little OS running on embedded systems based on MIPSfpga.

I have two files, boot.S and boot.h. I used the command mips-sde-elf-gcc -c -o boot.o boot.S to compile it so it would go through the C preprocessor cpp.

In the file boot.h, it defined a macro :

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

What does ## means? I found it on info cpp navigate to Macros then navigate to Concatenation, this is called "token pasting or token concatenation". But why do we need to concatenate token in this situation? You see, the boot.S will go through cpp, and then as. But the as also have a built-in token parser, so I don't think this token pasting is necessary here because as will parse it as a single symbol, rather than two separate symbols, from the output of cpp. cpp don't need to bother pasting it.

Then, I used the command gcc -E boot.S > boot.i to see what I got after preprocessing. In boot.S, the macro LEAF(__reset_vector) expanded to the following:

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

The preprocessed directives are on the same line. But what does ; mean? It is not documented in info as.

Upvotes: 2

Views: 256

Answers (3)

Peter Cordes
Peter Cordes

Reputation: 365527

As far as I can tell, the ## CPP operator is not required and has no effect, unless text, globl, or ent are #defined as macros.

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

LEAF(myname)

CPP output: .text; .globl myname; .ent myname;myname:

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

LEAF2(myname)

CPP output: .text; .globl myname; .ent myname;myname:

The output is identical with or without the ## token-pasting.


The ; is a statement separator in this asm syntax (like a newline), so this macro switches to the .text section, and declares a global symbol with the macro arg as the name. There's also a .ent name directive in there, and I don't know what it does.

Upvotes: 1

AntoineL
AntoineL

Reputation: 946

What does ## mean?

Create a token out of the preceding and the following one, pasting them together. The purpose here is probably to prevent the preprocessor to insert an extra space between the . and the following identifier, since . is not parsed with the identifier by CPP.

But what does ; mean?

In GAS syntax for most architectures, it is a statement separator. Assembly statements are normally separated by newlines, but cpp's macros cannot easily produce multi-line outputs, so another separator is required.

In some other assembly syntaxes (like NASM or MASM), ; is the comment character.

(Updated based on your additions.)

Upvotes: 2

Han XIAO
Han XIAO

Reputation: 1248

I carefully read info as. It turns out that "comments and statements" defined by GNU as are target specific. Different assembly language may have different comment and statement syntax, as well as line separator. So I need to dig deeper in MIPS syntax.

Upvotes: 1

Related Questions