GCC Inline Assembly: Jump to label outside block
Solution 1
The code in this answer happens to work, but is undefined behaviour and will in general break things with optimization enabled. It's only safe to jmp out of an inline asm statement with asm goto
, or under limited circumstances when the asm statement is followed by __builtin_unreachable();
(That's not usable here: it's never safe to jump into the middle of an inline asm statement and then fall out into compiler-generated code again inside a function.)
What if you define the label with the assembler?
asm("external_label:");
Update: this code seems to work:
#include <stdio.h>
int
main(void)
{
asm("jmp label");
puts("You should not see this.");
asm("label:");
return 0;
}
Solution 2
As of GCC 4.5, you can also use asm goto
. The following example jumps to a C label:
#include <stdio.h>
int main(void) {
asm goto (
"jmp %l[done]" // %l == lowercase L
:
:
:
: done // specify c label(s) here
);
printf("Should not see this\n");
done:
printf("Exiting\n");
return 0;
}
Vicent Marti
Updated on June 05, 2022Comments
-
Vicent Marti almost 2 years
When using inline assembly under MSVC, one is allowed to jump outside of the assembly block by referencing a label in the C/C++ code, as explained in this MSDN article.
Can such thing be done when using inline assembly under GCC?
Here's an example of what I'm trying to accomplish:
__asm__ __volatile__ ( " /* assembly code */ " " jz external_label; " ); /* some C code */ external_label: /* C code coninues... */
The compiler, however, complains about "external_label" not being defined.
-
Bastien Léonard about 15 yearsI updated with a sample that seems correct. Does it work for you?
-
Vicent Marti about 15 yearsHmm... This is strange. Your code does compile, however when doing the same thing in mine, the linker still complains about an undefined reference. :/
-
Vicent Marti about 15 yearsActually, I've just fixed. Turns out you cannot have a 'continue' keyword between the two assembly jumps, or things go messy. :) Thanks!
-
jww almost 13 years"Speaking of labels, jumps from one asm to another are not supported. The compiler's optimizers do not know about these jumps, and therefore they cannot take account of them when deciding how to optimize. See 'Extended asm with goto'." See gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html.
-
curiousguy over 12 years"this code seems to work:" As in: "has undefined behaviour"?
-
Bastien Léonard over 12 years@curiousguy: why not read the comments? Especially if you're posting two years after I wrote the answer...
-
curiousguy over 12 years@BastienLéonard "why not read the comments?" You mean the very small text that explains the code doesn't work? "Especially if you're posting two years after I wrote the answer..." I have just discovered this page. I assume others will find it too.