In my ongoing experimentation with GCC inline assembly, I’ve run into a new problem regarding labels and inlined code.
Consider the following simple jump:
__asm__
(
"jmp out;"
"out:;"
:
:
);
This does nothing except jump to the out label. As is, this code compiles fine. But if you place it inside a function, and then compile with optimization flags, the compiler complains: “Error: symbol ‘out’ is already defined”.
What seems to be happening is that the compiler is repeating this assembly code every time it inlines the function. This causes the label out to get duplicated, leading to multiple out labels.
So, how do I work around this? Is it really not possible to use labels in inline assembly? This tutorial on GCC inline assembly mentions that:
Thus, you can make put your assembly
into CPP macros, and inline C
functions, so anyone can use it in as
any C function/macro. Inline functions
resemble macros very much, but are
sometimes cleaner to use. Beware that
in all those cases, code will be
duplicated, so only local labels (of
1: style) should be defined in that
asm code.
I tried to find more information about these “local labels”, but can’t seem to find anything relating to inline assembly. It looks like the tutorial is saying that a local label is a number followed by a colon, (like 1:), so I tried using a label like that. Interestingly, the code compiled, but at run time it simply triggered a Segmentation Fault. Hmm…
So any suggestions, hints, answers…?
A declaration of a local label is indeed a number followed by a colon. But a reference to a local label needs a suffix of
forb, depending on whether you want to look forwards or backwards – i.e.1frefers to the next1:label in the forwards direction.So declaring the label as
1:is correct; but to reference it, you need to sayjmp 1f(because you are jumping forwards in this case).