Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GCC Inline Assembly: Jump to label outside block

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.

like image 981
Vicent Marti Avatar asked Apr 13 '09 14:04

Vicent Marti


2 Answers

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;
}
like image 136
Bastien Léonard Avatar answered Sep 28 '22 08:09

Bastien Léonard


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;
}
like image 21
chue x Avatar answered Sep 28 '22 08:09

chue x